1*0Sstevel@tonic-gate /* crypto/asn1/asn1_lib.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 <limits.h> 61*0Sstevel@tonic-gate #include "cryptlib.h" 62*0Sstevel@tonic-gate #include <openssl/asn1.h> 63*0Sstevel@tonic-gate #include <openssl/asn1_mac.h> 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate static int asn1_get_length(unsigned char **pp,int *inf,long *rl,int max); 66*0Sstevel@tonic-gate static void asn1_put_length(unsigned char **pp, int length); 67*0Sstevel@tonic-gate const char *ASN1_version="ASN.1" OPENSSL_VERSION_PTEXT; 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate int ASN1_check_infinite_end(unsigned char **p, long len) 70*0Sstevel@tonic-gate { 71*0Sstevel@tonic-gate /* If there is 0 or 1 byte left, the length check should pick 72*0Sstevel@tonic-gate * things up */ 73*0Sstevel@tonic-gate if (len <= 0) 74*0Sstevel@tonic-gate return(1); 75*0Sstevel@tonic-gate else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) 76*0Sstevel@tonic-gate { 77*0Sstevel@tonic-gate (*p)+=2; 78*0Sstevel@tonic-gate return(1); 79*0Sstevel@tonic-gate } 80*0Sstevel@tonic-gate return(0); 81*0Sstevel@tonic-gate } 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate int ASN1_get_object(unsigned char **pp, long *plength, int *ptag, int *pclass, 85*0Sstevel@tonic-gate long omax) 86*0Sstevel@tonic-gate { 87*0Sstevel@tonic-gate int i,ret; 88*0Sstevel@tonic-gate long l; 89*0Sstevel@tonic-gate unsigned char *p= *pp; 90*0Sstevel@tonic-gate int tag,xclass,inf; 91*0Sstevel@tonic-gate long max=omax; 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate if (!max) goto err; 94*0Sstevel@tonic-gate ret=(*p&V_ASN1_CONSTRUCTED); 95*0Sstevel@tonic-gate xclass=(*p&V_ASN1_PRIVATE); 96*0Sstevel@tonic-gate i= *p&V_ASN1_PRIMITIVE_TAG; 97*0Sstevel@tonic-gate if (i == V_ASN1_PRIMITIVE_TAG) 98*0Sstevel@tonic-gate { /* high-tag */ 99*0Sstevel@tonic-gate p++; 100*0Sstevel@tonic-gate if (--max == 0) goto err; 101*0Sstevel@tonic-gate l=0; 102*0Sstevel@tonic-gate while (*p&0x80) 103*0Sstevel@tonic-gate { 104*0Sstevel@tonic-gate l<<=7L; 105*0Sstevel@tonic-gate l|= *(p++)&0x7f; 106*0Sstevel@tonic-gate if (--max == 0) goto err; 107*0Sstevel@tonic-gate if (l > (INT_MAX >> 7L)) goto err; 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate l<<=7L; 110*0Sstevel@tonic-gate l|= *(p++)&0x7f; 111*0Sstevel@tonic-gate tag=(int)l; 112*0Sstevel@tonic-gate if (--max == 0) goto err; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate else 115*0Sstevel@tonic-gate { 116*0Sstevel@tonic-gate tag=i; 117*0Sstevel@tonic-gate p++; 118*0Sstevel@tonic-gate if (--max == 0) goto err; 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate *ptag=tag; 121*0Sstevel@tonic-gate *pclass=xclass; 122*0Sstevel@tonic-gate if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err; 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate #if 0 125*0Sstevel@tonic-gate fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n", 126*0Sstevel@tonic-gate (int)p,*plength,omax,(int)*pp,(int)(p+ *plength), 127*0Sstevel@tonic-gate (int)(omax+ *pp)); 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate #endif 130*0Sstevel@tonic-gate if (*plength > (omax - (p - *pp))) 131*0Sstevel@tonic-gate { 132*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG); 133*0Sstevel@tonic-gate /* Set this so that even if things are not long enough 134*0Sstevel@tonic-gate * the values are set correctly */ 135*0Sstevel@tonic-gate ret|=0x80; 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate *pp=p; 138*0Sstevel@tonic-gate return(ret|inf); 139*0Sstevel@tonic-gate err: 140*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_HEADER_TOO_LONG); 141*0Sstevel@tonic-gate return(0x80); 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate static int asn1_get_length(unsigned char **pp, int *inf, long *rl, int max) 145*0Sstevel@tonic-gate { 146*0Sstevel@tonic-gate unsigned char *p= *pp; 147*0Sstevel@tonic-gate unsigned long ret=0; 148*0Sstevel@tonic-gate int i; 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate if (max-- < 1) return(0); 151*0Sstevel@tonic-gate if (*p == 0x80) 152*0Sstevel@tonic-gate { 153*0Sstevel@tonic-gate *inf=1; 154*0Sstevel@tonic-gate ret=0; 155*0Sstevel@tonic-gate p++; 156*0Sstevel@tonic-gate } 157*0Sstevel@tonic-gate else 158*0Sstevel@tonic-gate { 159*0Sstevel@tonic-gate *inf=0; 160*0Sstevel@tonic-gate i= *p&0x7f; 161*0Sstevel@tonic-gate if (*(p++) & 0x80) 162*0Sstevel@tonic-gate { 163*0Sstevel@tonic-gate if (i > sizeof(long)) 164*0Sstevel@tonic-gate return 0; 165*0Sstevel@tonic-gate if (max-- == 0) return(0); 166*0Sstevel@tonic-gate while (i-- > 0) 167*0Sstevel@tonic-gate { 168*0Sstevel@tonic-gate ret<<=8L; 169*0Sstevel@tonic-gate ret|= *(p++); 170*0Sstevel@tonic-gate if (max-- == 0) return(0); 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate else 174*0Sstevel@tonic-gate ret=i; 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate if (ret > LONG_MAX) 177*0Sstevel@tonic-gate return 0; 178*0Sstevel@tonic-gate *pp=p; 179*0Sstevel@tonic-gate *rl=(long)ret; 180*0Sstevel@tonic-gate return(1); 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate /* class 0 is constructed 184*0Sstevel@tonic-gate * constructed == 2 for indefinite length constructed */ 185*0Sstevel@tonic-gate void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, 186*0Sstevel@tonic-gate int xclass) 187*0Sstevel@tonic-gate { 188*0Sstevel@tonic-gate unsigned char *p= *pp; 189*0Sstevel@tonic-gate int i, ttag; 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate i=(constructed)?V_ASN1_CONSTRUCTED:0; 192*0Sstevel@tonic-gate i|=(xclass&V_ASN1_PRIVATE); 193*0Sstevel@tonic-gate if (tag < 31) 194*0Sstevel@tonic-gate *(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG); 195*0Sstevel@tonic-gate else 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate *(p++)=i|V_ASN1_PRIMITIVE_TAG; 198*0Sstevel@tonic-gate for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7; 199*0Sstevel@tonic-gate ttag = i; 200*0Sstevel@tonic-gate while(i-- > 0) 201*0Sstevel@tonic-gate { 202*0Sstevel@tonic-gate p[i] = tag & 0x7f; 203*0Sstevel@tonic-gate if(i != (ttag - 1)) p[i] |= 0x80; 204*0Sstevel@tonic-gate tag >>= 7; 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate p += ttag; 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate if ((constructed == 2) && (length == 0)) 209*0Sstevel@tonic-gate *(p++)=0x80; /* der_put_length would output 0 instead */ 210*0Sstevel@tonic-gate else 211*0Sstevel@tonic-gate asn1_put_length(&p,length); 212*0Sstevel@tonic-gate *pp=p; 213*0Sstevel@tonic-gate } 214*0Sstevel@tonic-gate 215*0Sstevel@tonic-gate static void asn1_put_length(unsigned char **pp, int length) 216*0Sstevel@tonic-gate { 217*0Sstevel@tonic-gate unsigned char *p= *pp; 218*0Sstevel@tonic-gate int i,l; 219*0Sstevel@tonic-gate if (length <= 127) 220*0Sstevel@tonic-gate *(p++)=(unsigned char)length; 221*0Sstevel@tonic-gate else 222*0Sstevel@tonic-gate { 223*0Sstevel@tonic-gate l=length; 224*0Sstevel@tonic-gate for (i=0; l > 0; i++) 225*0Sstevel@tonic-gate l>>=8; 226*0Sstevel@tonic-gate *(p++)=i|0x80; 227*0Sstevel@tonic-gate l=i; 228*0Sstevel@tonic-gate while (i-- > 0) 229*0Sstevel@tonic-gate { 230*0Sstevel@tonic-gate p[i]=length&0xff; 231*0Sstevel@tonic-gate length>>=8; 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate p+=l; 234*0Sstevel@tonic-gate } 235*0Sstevel@tonic-gate *pp=p; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate int ASN1_object_size(int constructed, int length, int tag) 239*0Sstevel@tonic-gate { 240*0Sstevel@tonic-gate int ret; 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate ret=length; 243*0Sstevel@tonic-gate ret++; 244*0Sstevel@tonic-gate if (tag >= 31) 245*0Sstevel@tonic-gate { 246*0Sstevel@tonic-gate while (tag > 0) 247*0Sstevel@tonic-gate { 248*0Sstevel@tonic-gate tag>>=7; 249*0Sstevel@tonic-gate ret++; 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate if ((length == 0) && (constructed == 2)) 253*0Sstevel@tonic-gate ret+=2; 254*0Sstevel@tonic-gate ret++; 255*0Sstevel@tonic-gate if (length > 127) 256*0Sstevel@tonic-gate { 257*0Sstevel@tonic-gate while (length > 0) 258*0Sstevel@tonic-gate { 259*0Sstevel@tonic-gate length>>=8; 260*0Sstevel@tonic-gate ret++; 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate } 263*0Sstevel@tonic-gate return(ret); 264*0Sstevel@tonic-gate } 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate int asn1_Finish(ASN1_CTX *c) 267*0Sstevel@tonic-gate { 268*0Sstevel@tonic-gate if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos)) 269*0Sstevel@tonic-gate { 270*0Sstevel@tonic-gate if (!ASN1_check_infinite_end(&c->p,c->slen)) 271*0Sstevel@tonic-gate { 272*0Sstevel@tonic-gate c->error=ERR_R_MISSING_ASN1_EOS; 273*0Sstevel@tonic-gate return(0); 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate } 276*0Sstevel@tonic-gate if ( ((c->slen != 0) && !(c->inf & 1)) || 277*0Sstevel@tonic-gate ((c->slen < 0) && (c->inf & 1))) 278*0Sstevel@tonic-gate { 279*0Sstevel@tonic-gate c->error=ERR_R_ASN1_LENGTH_MISMATCH; 280*0Sstevel@tonic-gate return(0); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate return(1); 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate int asn1_GetSequence(ASN1_CTX *c, long *length) 286*0Sstevel@tonic-gate { 287*0Sstevel@tonic-gate unsigned char *q; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate q=c->p; 290*0Sstevel@tonic-gate c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass), 291*0Sstevel@tonic-gate *length); 292*0Sstevel@tonic-gate if (c->inf & 0x80) 293*0Sstevel@tonic-gate { 294*0Sstevel@tonic-gate c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL; 295*0Sstevel@tonic-gate return(0); 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate if (c->tag != V_ASN1_SEQUENCE) 298*0Sstevel@tonic-gate { 299*0Sstevel@tonic-gate c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE; 300*0Sstevel@tonic-gate return(0); 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate (*length)-=(c->p-q); 303*0Sstevel@tonic-gate if (c->max && (*length < 0)) 304*0Sstevel@tonic-gate { 305*0Sstevel@tonic-gate c->error=ERR_R_ASN1_LENGTH_MISMATCH; 306*0Sstevel@tonic-gate return(0); 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate if (c->inf == (1|V_ASN1_CONSTRUCTED)) 309*0Sstevel@tonic-gate c->slen= *length+ *(c->pp)-c->p; 310*0Sstevel@tonic-gate c->eos=0; 311*0Sstevel@tonic-gate return(1); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str) 315*0Sstevel@tonic-gate { 316*0Sstevel@tonic-gate ASN1_STRING *ret; 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate if (str == NULL) return(NULL); 319*0Sstevel@tonic-gate if ((ret=ASN1_STRING_type_new(str->type)) == NULL) 320*0Sstevel@tonic-gate return(NULL); 321*0Sstevel@tonic-gate if (!ASN1_STRING_set(ret,str->data,str->length)) 322*0Sstevel@tonic-gate { 323*0Sstevel@tonic-gate ASN1_STRING_free(ret); 324*0Sstevel@tonic-gate return(NULL); 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate ret->flags = str->flags; 327*0Sstevel@tonic-gate return(ret); 328*0Sstevel@tonic-gate } 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) 331*0Sstevel@tonic-gate { 332*0Sstevel@tonic-gate unsigned char *c; 333*0Sstevel@tonic-gate const char *data=_data; 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate if (len < 0) 336*0Sstevel@tonic-gate { 337*0Sstevel@tonic-gate if (data == NULL) 338*0Sstevel@tonic-gate return(0); 339*0Sstevel@tonic-gate else 340*0Sstevel@tonic-gate len=strlen(data); 341*0Sstevel@tonic-gate } 342*0Sstevel@tonic-gate if ((str->length < len) || (str->data == NULL)) 343*0Sstevel@tonic-gate { 344*0Sstevel@tonic-gate c=str->data; 345*0Sstevel@tonic-gate if (c == NULL) 346*0Sstevel@tonic-gate str->data=OPENSSL_malloc(len+1); 347*0Sstevel@tonic-gate else 348*0Sstevel@tonic-gate str->data=OPENSSL_realloc(c,len+1); 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate if (str->data == NULL) 351*0Sstevel@tonic-gate { 352*0Sstevel@tonic-gate str->data=c; 353*0Sstevel@tonic-gate return(0); 354*0Sstevel@tonic-gate } 355*0Sstevel@tonic-gate } 356*0Sstevel@tonic-gate str->length=len; 357*0Sstevel@tonic-gate if (data != NULL) 358*0Sstevel@tonic-gate { 359*0Sstevel@tonic-gate memcpy(str->data,data,len); 360*0Sstevel@tonic-gate /* an allowance for strings :-) */ 361*0Sstevel@tonic-gate str->data[len]='\0'; 362*0Sstevel@tonic-gate } 363*0Sstevel@tonic-gate return(1); 364*0Sstevel@tonic-gate } 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate ASN1_STRING *ASN1_STRING_new(void) 367*0Sstevel@tonic-gate { 368*0Sstevel@tonic-gate return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); 369*0Sstevel@tonic-gate } 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate ASN1_STRING *ASN1_STRING_type_new(int type) 373*0Sstevel@tonic-gate { 374*0Sstevel@tonic-gate ASN1_STRING *ret; 375*0Sstevel@tonic-gate 376*0Sstevel@tonic-gate ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); 377*0Sstevel@tonic-gate if (ret == NULL) 378*0Sstevel@tonic-gate { 379*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,ERR_R_MALLOC_FAILURE); 380*0Sstevel@tonic-gate return(NULL); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate ret->length=0; 383*0Sstevel@tonic-gate ret->type=type; 384*0Sstevel@tonic-gate ret->data=NULL; 385*0Sstevel@tonic-gate ret->flags=0; 386*0Sstevel@tonic-gate return(ret); 387*0Sstevel@tonic-gate } 388*0Sstevel@tonic-gate 389*0Sstevel@tonic-gate void ASN1_STRING_free(ASN1_STRING *a) 390*0Sstevel@tonic-gate { 391*0Sstevel@tonic-gate if (a == NULL) return; 392*0Sstevel@tonic-gate if (a->data != NULL) OPENSSL_free(a->data); 393*0Sstevel@tonic-gate OPENSSL_free(a); 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b) 397*0Sstevel@tonic-gate { 398*0Sstevel@tonic-gate int i; 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate i=(a->length-b->length); 401*0Sstevel@tonic-gate if (i == 0) 402*0Sstevel@tonic-gate { 403*0Sstevel@tonic-gate i=memcmp(a->data,b->data,a->length); 404*0Sstevel@tonic-gate if (i == 0) 405*0Sstevel@tonic-gate return(a->type-b->type); 406*0Sstevel@tonic-gate else 407*0Sstevel@tonic-gate return(i); 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate else 410*0Sstevel@tonic-gate return(i); 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate 413*0Sstevel@tonic-gate void asn1_add_error(unsigned char *address, int offset) 414*0Sstevel@tonic-gate { 415*0Sstevel@tonic-gate char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1]; 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gate BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address); 418*0Sstevel@tonic-gate BIO_snprintf(buf2,sizeof buf2,"%d",offset); 419*0Sstevel@tonic-gate ERR_add_error_data(4,"address=",buf1," offset=",buf2); 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate int ASN1_STRING_length(ASN1_STRING *x) 423*0Sstevel@tonic-gate { return M_ASN1_STRING_length(x); } 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate void ASN1_STRING_length_set(ASN1_STRING *x, int len) 426*0Sstevel@tonic-gate { M_ASN1_STRING_length_set(x, len); return; } 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate int ASN1_STRING_type(ASN1_STRING *x) 429*0Sstevel@tonic-gate { return M_ASN1_STRING_type(x); } 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate unsigned char * ASN1_STRING_data(ASN1_STRING *x) 432*0Sstevel@tonic-gate { return M_ASN1_STRING_data(x); } 433