10Sstevel@tonic-gate /* crypto/asn1/a_object.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include "cryptlib.h"
610Sstevel@tonic-gate #include <openssl/buffer.h>
620Sstevel@tonic-gate #include <openssl/asn1.h>
630Sstevel@tonic-gate #include <openssl/objects.h>
640Sstevel@tonic-gate
i2d_ASN1_OBJECT(ASN1_OBJECT * a,unsigned char ** pp)650Sstevel@tonic-gate int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
660Sstevel@tonic-gate {
670Sstevel@tonic-gate unsigned char *p;
680Sstevel@tonic-gate int objsize;
690Sstevel@tonic-gate
700Sstevel@tonic-gate if ((a == NULL) || (a->data == NULL)) return(0);
710Sstevel@tonic-gate
720Sstevel@tonic-gate objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
730Sstevel@tonic-gate if (pp == NULL) return objsize;
740Sstevel@tonic-gate
750Sstevel@tonic-gate p= *pp;
760Sstevel@tonic-gate ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
770Sstevel@tonic-gate memcpy(p,a->data,a->length);
780Sstevel@tonic-gate p+=a->length;
790Sstevel@tonic-gate
800Sstevel@tonic-gate *pp=p;
810Sstevel@tonic-gate return(objsize);
820Sstevel@tonic-gate }
830Sstevel@tonic-gate
a2d_ASN1_OBJECT(unsigned char * out,int olen,const char * buf,int num)840Sstevel@tonic-gate int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
850Sstevel@tonic-gate {
860Sstevel@tonic-gate int i,first,len=0,c;
870Sstevel@tonic-gate char tmp[24];
880Sstevel@tonic-gate const char *p;
890Sstevel@tonic-gate unsigned long l;
900Sstevel@tonic-gate
910Sstevel@tonic-gate if (num == 0)
920Sstevel@tonic-gate return(0);
930Sstevel@tonic-gate else if (num == -1)
940Sstevel@tonic-gate num=strlen(buf);
950Sstevel@tonic-gate
960Sstevel@tonic-gate p=buf;
970Sstevel@tonic-gate c= *(p++);
980Sstevel@tonic-gate num--;
990Sstevel@tonic-gate if ((c >= '0') && (c <= '2'))
1000Sstevel@tonic-gate {
1010Sstevel@tonic-gate first=(c-'0')*40;
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate else
1040Sstevel@tonic-gate {
1050Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
1060Sstevel@tonic-gate goto err;
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate if (num <= 0)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
1120Sstevel@tonic-gate goto err;
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate c= *(p++);
1150Sstevel@tonic-gate num--;
1160Sstevel@tonic-gate for (;;)
1170Sstevel@tonic-gate {
1180Sstevel@tonic-gate if (num <= 0) break;
1190Sstevel@tonic-gate if ((c != '.') && (c != ' '))
1200Sstevel@tonic-gate {
1210Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
1220Sstevel@tonic-gate goto err;
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate l=0;
1250Sstevel@tonic-gate for (;;)
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate if (num <= 0) break;
1280Sstevel@tonic-gate num--;
1290Sstevel@tonic-gate c= *(p++);
1300Sstevel@tonic-gate if ((c == ' ') || (c == '.'))
1310Sstevel@tonic-gate break;
1320Sstevel@tonic-gate if ((c < '0') || (c > '9'))
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
1350Sstevel@tonic-gate goto err;
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate l=l*10L+(long)(c-'0');
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate if (len == 0)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate if ((first < 2) && (l >= 40))
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
1440Sstevel@tonic-gate goto err;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate l+=(long)first;
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate i=0;
1490Sstevel@tonic-gate for (;;)
1500Sstevel@tonic-gate {
1510Sstevel@tonic-gate tmp[i++]=(unsigned char)l&0x7f;
1520Sstevel@tonic-gate l>>=7L;
1530Sstevel@tonic-gate if (l == 0L) break;
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate if (out != NULL)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate if (len+i > olen)
1580Sstevel@tonic-gate {
1590Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
1600Sstevel@tonic-gate goto err;
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate while (--i > 0)
1630Sstevel@tonic-gate out[len++]=tmp[i]|0x80;
1640Sstevel@tonic-gate out[len++]=tmp[0];
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate else
1670Sstevel@tonic-gate len+=i;
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate return(len);
1700Sstevel@tonic-gate err:
1710Sstevel@tonic-gate return(0);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate
i2t_ASN1_OBJECT(char * buf,int buf_len,ASN1_OBJECT * a)1740Sstevel@tonic-gate int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
1750Sstevel@tonic-gate {
1760Sstevel@tonic-gate return OBJ_obj2txt(buf, buf_len, a, 0);
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate
i2a_ASN1_OBJECT(BIO * bp,ASN1_OBJECT * a)1790Sstevel@tonic-gate int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate char buf[80];
1820Sstevel@tonic-gate int i;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate if ((a == NULL) || (a->data == NULL))
1850Sstevel@tonic-gate return(BIO_write(bp,"NULL",4));
1860Sstevel@tonic-gate i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
187*2139Sjp161948 if (i > (int)sizeof(buf)) i=sizeof buf;
1880Sstevel@tonic-gate BIO_write(bp,buf,i);
1890Sstevel@tonic-gate return(i);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate
d2i_ASN1_OBJECT(ASN1_OBJECT ** a,const unsigned char ** pp,long length)192*2139Sjp161948 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
1930Sstevel@tonic-gate long length)
1940Sstevel@tonic-gate {
195*2139Sjp161948 const unsigned char *p;
1960Sstevel@tonic-gate long len;
1970Sstevel@tonic-gate int tag,xclass;
1980Sstevel@tonic-gate int inf,i;
1990Sstevel@tonic-gate ASN1_OBJECT *ret = NULL;
2000Sstevel@tonic-gate p= *pp;
2010Sstevel@tonic-gate inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
2020Sstevel@tonic-gate if (inf & 0x80)
2030Sstevel@tonic-gate {
2040Sstevel@tonic-gate i=ASN1_R_BAD_OBJECT_HEADER;
2050Sstevel@tonic-gate goto err;
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate if (tag != V_ASN1_OBJECT)
2090Sstevel@tonic-gate {
2100Sstevel@tonic-gate i=ASN1_R_EXPECTING_AN_OBJECT;
2110Sstevel@tonic-gate goto err;
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate ret = c2i_ASN1_OBJECT(a, &p, len);
2140Sstevel@tonic-gate if(ret) *pp = p;
2150Sstevel@tonic-gate return ret;
2160Sstevel@tonic-gate err:
2170Sstevel@tonic-gate ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
2180Sstevel@tonic-gate if ((ret != NULL) && ((a == NULL) || (*a != ret)))
2190Sstevel@tonic-gate ASN1_OBJECT_free(ret);
2200Sstevel@tonic-gate return(NULL);
2210Sstevel@tonic-gate }
c2i_ASN1_OBJECT(ASN1_OBJECT ** a,const unsigned char ** pp,long len)222*2139Sjp161948 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
2230Sstevel@tonic-gate long len)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate ASN1_OBJECT *ret=NULL;
226*2139Sjp161948 const unsigned char *p;
2270Sstevel@tonic-gate int i;
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate /* only the ASN1_OBJECTs from the 'table' will have values
2300Sstevel@tonic-gate * for ->sn or ->ln */
2310Sstevel@tonic-gate if ((a == NULL) || ((*a) == NULL) ||
2320Sstevel@tonic-gate !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate else ret=(*a);
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate p= *pp;
2390Sstevel@tonic-gate if ((ret->data == NULL) || (ret->length < len))
2400Sstevel@tonic-gate {
2410Sstevel@tonic-gate if (ret->data != NULL) OPENSSL_free(ret->data);
2420Sstevel@tonic-gate ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
2430Sstevel@tonic-gate ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
2440Sstevel@tonic-gate if (ret->data == NULL)
2450Sstevel@tonic-gate { i=ERR_R_MALLOC_FAILURE; goto err; }
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate memcpy(ret->data,p,(int)len);
2480Sstevel@tonic-gate ret->length=(int)len;
2490Sstevel@tonic-gate ret->sn=NULL;
2500Sstevel@tonic-gate ret->ln=NULL;
2510Sstevel@tonic-gate /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
2520Sstevel@tonic-gate p+=len;
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate if (a != NULL) (*a)=ret;
2550Sstevel@tonic-gate *pp=p;
2560Sstevel@tonic-gate return(ret);
2570Sstevel@tonic-gate err:
258*2139Sjp161948 ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
2590Sstevel@tonic-gate if ((ret != NULL) && ((a == NULL) || (*a != ret)))
2600Sstevel@tonic-gate ASN1_OBJECT_free(ret);
2610Sstevel@tonic-gate return(NULL);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate
ASN1_OBJECT_new(void)2640Sstevel@tonic-gate ASN1_OBJECT *ASN1_OBJECT_new(void)
2650Sstevel@tonic-gate {
2660Sstevel@tonic-gate ASN1_OBJECT *ret;
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
2690Sstevel@tonic-gate if (ret == NULL)
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
2720Sstevel@tonic-gate return(NULL);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate ret->length=0;
2750Sstevel@tonic-gate ret->data=NULL;
2760Sstevel@tonic-gate ret->nid=0;
2770Sstevel@tonic-gate ret->sn=NULL;
2780Sstevel@tonic-gate ret->ln=NULL;
2790Sstevel@tonic-gate ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
2800Sstevel@tonic-gate return(ret);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate
ASN1_OBJECT_free(ASN1_OBJECT * a)2830Sstevel@tonic-gate void ASN1_OBJECT_free(ASN1_OBJECT *a)
2840Sstevel@tonic-gate {
2850Sstevel@tonic-gate if (a == NULL) return;
2860Sstevel@tonic-gate if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
2870Sstevel@tonic-gate {
2880Sstevel@tonic-gate #ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
2890Sstevel@tonic-gate if (a->sn != NULL) OPENSSL_free((void *)a->sn);
2900Sstevel@tonic-gate if (a->ln != NULL) OPENSSL_free((void *)a->ln);
2910Sstevel@tonic-gate #endif
2920Sstevel@tonic-gate a->sn=a->ln=NULL;
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
2950Sstevel@tonic-gate {
2960Sstevel@tonic-gate if (a->data != NULL) OPENSSL_free(a->data);
2970Sstevel@tonic-gate a->data=NULL;
2980Sstevel@tonic-gate a->length=0;
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
3010Sstevel@tonic-gate OPENSSL_free(a);
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate
ASN1_OBJECT_create(int nid,unsigned char * data,int len,const char * sn,const char * ln)3040Sstevel@tonic-gate ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
3050Sstevel@tonic-gate const char *sn, const char *ln)
3060Sstevel@tonic-gate {
3070Sstevel@tonic-gate ASN1_OBJECT o;
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate o.sn=sn;
3100Sstevel@tonic-gate o.ln=ln;
3110Sstevel@tonic-gate o.data=data;
3120Sstevel@tonic-gate o.nid=nid;
3130Sstevel@tonic-gate o.length=len;
3140Sstevel@tonic-gate o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
3150Sstevel@tonic-gate ASN1_OBJECT_FLAG_DYNAMIC_DATA;
3160Sstevel@tonic-gate return(OBJ_dup(&o));
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate IMPLEMENT_STACK_OF(ASN1_OBJECT)
3200Sstevel@tonic-gate IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
321