1*0Sstevel@tonic-gate /* crypto/asn1/a_object.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include "cryptlib.h" 61*0Sstevel@tonic-gate #include <openssl/buffer.h> 62*0Sstevel@tonic-gate #include <openssl/asn1.h> 63*0Sstevel@tonic-gate #include <openssl/objects.h> 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) 66*0Sstevel@tonic-gate { 67*0Sstevel@tonic-gate unsigned char *p; 68*0Sstevel@tonic-gate int objsize; 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate if ((a == NULL) || (a->data == NULL)) return(0); 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT); 73*0Sstevel@tonic-gate if (pp == NULL) return objsize; 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate p= *pp; 76*0Sstevel@tonic-gate ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL); 77*0Sstevel@tonic-gate memcpy(p,a->data,a->length); 78*0Sstevel@tonic-gate p+=a->length; 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate *pp=p; 81*0Sstevel@tonic-gate return(objsize); 82*0Sstevel@tonic-gate } 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) 85*0Sstevel@tonic-gate { 86*0Sstevel@tonic-gate int i,first,len=0,c; 87*0Sstevel@tonic-gate char tmp[24]; 88*0Sstevel@tonic-gate const char *p; 89*0Sstevel@tonic-gate unsigned long l; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate if (num == 0) 92*0Sstevel@tonic-gate return(0); 93*0Sstevel@tonic-gate else if (num == -1) 94*0Sstevel@tonic-gate num=strlen(buf); 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate p=buf; 97*0Sstevel@tonic-gate c= *(p++); 98*0Sstevel@tonic-gate num--; 99*0Sstevel@tonic-gate if ((c >= '0') && (c <= '2')) 100*0Sstevel@tonic-gate { 101*0Sstevel@tonic-gate first=(c-'0')*40; 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate else 104*0Sstevel@tonic-gate { 105*0Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE); 106*0Sstevel@tonic-gate goto err; 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate if (num <= 0) 110*0Sstevel@tonic-gate { 111*0Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER); 112*0Sstevel@tonic-gate goto err; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate c= *(p++); 115*0Sstevel@tonic-gate num--; 116*0Sstevel@tonic-gate for (;;) 117*0Sstevel@tonic-gate { 118*0Sstevel@tonic-gate if (num <= 0) break; 119*0Sstevel@tonic-gate if ((c != '.') && (c != ' ')) 120*0Sstevel@tonic-gate { 121*0Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR); 122*0Sstevel@tonic-gate goto err; 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate l=0; 125*0Sstevel@tonic-gate for (;;) 126*0Sstevel@tonic-gate { 127*0Sstevel@tonic-gate if (num <= 0) break; 128*0Sstevel@tonic-gate num--; 129*0Sstevel@tonic-gate c= *(p++); 130*0Sstevel@tonic-gate if ((c == ' ') || (c == '.')) 131*0Sstevel@tonic-gate break; 132*0Sstevel@tonic-gate if ((c < '0') || (c > '9')) 133*0Sstevel@tonic-gate { 134*0Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); 135*0Sstevel@tonic-gate goto err; 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate l=l*10L+(long)(c-'0'); 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate if (len == 0) 140*0Sstevel@tonic-gate { 141*0Sstevel@tonic-gate if ((first < 2) && (l >= 40)) 142*0Sstevel@tonic-gate { 143*0Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE); 144*0Sstevel@tonic-gate goto err; 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate l+=(long)first; 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate i=0; 149*0Sstevel@tonic-gate for (;;) 150*0Sstevel@tonic-gate { 151*0Sstevel@tonic-gate tmp[i++]=(unsigned char)l&0x7f; 152*0Sstevel@tonic-gate l>>=7L; 153*0Sstevel@tonic-gate if (l == 0L) break; 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate if (out != NULL) 156*0Sstevel@tonic-gate { 157*0Sstevel@tonic-gate if (len+i > olen) 158*0Sstevel@tonic-gate { 159*0Sstevel@tonic-gate ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL); 160*0Sstevel@tonic-gate goto err; 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate while (--i > 0) 163*0Sstevel@tonic-gate out[len++]=tmp[i]|0x80; 164*0Sstevel@tonic-gate out[len++]=tmp[0]; 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate else 167*0Sstevel@tonic-gate len+=i; 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate return(len); 170*0Sstevel@tonic-gate err: 171*0Sstevel@tonic-gate return(0); 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) 175*0Sstevel@tonic-gate { 176*0Sstevel@tonic-gate return OBJ_obj2txt(buf, buf_len, a, 0); 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) 180*0Sstevel@tonic-gate { 181*0Sstevel@tonic-gate char buf[80]; 182*0Sstevel@tonic-gate int i; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate if ((a == NULL) || (a->data == NULL)) 185*0Sstevel@tonic-gate return(BIO_write(bp,"NULL",4)); 186*0Sstevel@tonic-gate i=i2t_ASN1_OBJECT(buf,sizeof buf,a); 187*0Sstevel@tonic-gate if (i > sizeof buf) i=sizeof buf; 188*0Sstevel@tonic-gate BIO_write(bp,buf,i); 189*0Sstevel@tonic-gate return(i); 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, 193*0Sstevel@tonic-gate long length) 194*0Sstevel@tonic-gate { 195*0Sstevel@tonic-gate unsigned char *p; 196*0Sstevel@tonic-gate long len; 197*0Sstevel@tonic-gate int tag,xclass; 198*0Sstevel@tonic-gate int inf,i; 199*0Sstevel@tonic-gate ASN1_OBJECT *ret = NULL; 200*0Sstevel@tonic-gate p= *pp; 201*0Sstevel@tonic-gate inf=ASN1_get_object(&p,&len,&tag,&xclass,length); 202*0Sstevel@tonic-gate if (inf & 0x80) 203*0Sstevel@tonic-gate { 204*0Sstevel@tonic-gate i=ASN1_R_BAD_OBJECT_HEADER; 205*0Sstevel@tonic-gate goto err; 206*0Sstevel@tonic-gate } 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate if (tag != V_ASN1_OBJECT) 209*0Sstevel@tonic-gate { 210*0Sstevel@tonic-gate i=ASN1_R_EXPECTING_AN_OBJECT; 211*0Sstevel@tonic-gate goto err; 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate ret = c2i_ASN1_OBJECT(a, &p, len); 214*0Sstevel@tonic-gate if(ret) *pp = p; 215*0Sstevel@tonic-gate return ret; 216*0Sstevel@tonic-gate err: 217*0Sstevel@tonic-gate ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); 218*0Sstevel@tonic-gate if ((ret != NULL) && ((a == NULL) || (*a != ret))) 219*0Sstevel@tonic-gate ASN1_OBJECT_free(ret); 220*0Sstevel@tonic-gate return(NULL); 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, 223*0Sstevel@tonic-gate long len) 224*0Sstevel@tonic-gate { 225*0Sstevel@tonic-gate ASN1_OBJECT *ret=NULL; 226*0Sstevel@tonic-gate unsigned char *p; 227*0Sstevel@tonic-gate int i; 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate /* only the ASN1_OBJECTs from the 'table' will have values 230*0Sstevel@tonic-gate * for ->sn or ->ln */ 231*0Sstevel@tonic-gate if ((a == NULL) || ((*a) == NULL) || 232*0Sstevel@tonic-gate !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) 233*0Sstevel@tonic-gate { 234*0Sstevel@tonic-gate if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate else ret=(*a); 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate p= *pp; 239*0Sstevel@tonic-gate if ((ret->data == NULL) || (ret->length < len)) 240*0Sstevel@tonic-gate { 241*0Sstevel@tonic-gate if (ret->data != NULL) OPENSSL_free(ret->data); 242*0Sstevel@tonic-gate ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); 243*0Sstevel@tonic-gate ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; 244*0Sstevel@tonic-gate if (ret->data == NULL) 245*0Sstevel@tonic-gate { i=ERR_R_MALLOC_FAILURE; goto err; } 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate memcpy(ret->data,p,(int)len); 248*0Sstevel@tonic-gate ret->length=(int)len; 249*0Sstevel@tonic-gate ret->sn=NULL; 250*0Sstevel@tonic-gate ret->ln=NULL; 251*0Sstevel@tonic-gate /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ 252*0Sstevel@tonic-gate p+=len; 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate if (a != NULL) (*a)=ret; 255*0Sstevel@tonic-gate *pp=p; 256*0Sstevel@tonic-gate return(ret); 257*0Sstevel@tonic-gate err: 258*0Sstevel@tonic-gate ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); 259*0Sstevel@tonic-gate if ((ret != NULL) && ((a == NULL) || (*a != ret))) 260*0Sstevel@tonic-gate ASN1_OBJECT_free(ret); 261*0Sstevel@tonic-gate return(NULL); 262*0Sstevel@tonic-gate } 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate ASN1_OBJECT *ASN1_OBJECT_new(void) 265*0Sstevel@tonic-gate { 266*0Sstevel@tonic-gate ASN1_OBJECT *ret; 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); 269*0Sstevel@tonic-gate if (ret == NULL) 270*0Sstevel@tonic-gate { 271*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE); 272*0Sstevel@tonic-gate return(NULL); 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate ret->length=0; 275*0Sstevel@tonic-gate ret->data=NULL; 276*0Sstevel@tonic-gate ret->nid=0; 277*0Sstevel@tonic-gate ret->sn=NULL; 278*0Sstevel@tonic-gate ret->ln=NULL; 279*0Sstevel@tonic-gate ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; 280*0Sstevel@tonic-gate return(ret); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate void ASN1_OBJECT_free(ASN1_OBJECT *a) 284*0Sstevel@tonic-gate { 285*0Sstevel@tonic-gate if (a == NULL) return; 286*0Sstevel@tonic-gate if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) 287*0Sstevel@tonic-gate { 288*0Sstevel@tonic-gate #ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */ 289*0Sstevel@tonic-gate if (a->sn != NULL) OPENSSL_free((void *)a->sn); 290*0Sstevel@tonic-gate if (a->ln != NULL) OPENSSL_free((void *)a->ln); 291*0Sstevel@tonic-gate #endif 292*0Sstevel@tonic-gate a->sn=a->ln=NULL; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) 295*0Sstevel@tonic-gate { 296*0Sstevel@tonic-gate if (a->data != NULL) OPENSSL_free(a->data); 297*0Sstevel@tonic-gate a->data=NULL; 298*0Sstevel@tonic-gate a->length=0; 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) 301*0Sstevel@tonic-gate OPENSSL_free(a); 302*0Sstevel@tonic-gate } 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, 305*0Sstevel@tonic-gate const char *sn, const char *ln) 306*0Sstevel@tonic-gate { 307*0Sstevel@tonic-gate ASN1_OBJECT o; 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate o.sn=sn; 310*0Sstevel@tonic-gate o.ln=ln; 311*0Sstevel@tonic-gate o.data=data; 312*0Sstevel@tonic-gate o.nid=nid; 313*0Sstevel@tonic-gate o.length=len; 314*0Sstevel@tonic-gate o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| 315*0Sstevel@tonic-gate ASN1_OBJECT_FLAG_DYNAMIC_DATA; 316*0Sstevel@tonic-gate return(OBJ_dup(&o)); 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate IMPLEMENT_STACK_OF(ASN1_OBJECT) 320*0Sstevel@tonic-gate IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT) 321