X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fa_object.c;h=a11d25e1fb7a8b8ca172fb2a080e5a80e53dd969;hp=ab69b955b51f315c924423ac5b1f22dcbd18819d;hb=452ae49db5444f61fd643507fe71e4ac41ecfb1c;hpb=d8223efd04f8526b602209ee5f39c06fa300beea diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index ab69b955b5..a11d25e1fb 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -57,6 +57,7 @@ */ #include +#include #include "cryptlib.h" #include #include @@ -65,11 +66,12 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) { unsigned char *p; + int objsize; if ((a == NULL) || (a->data == NULL)) return(0); - if (pp == NULL) - return(ASN1_object_size(0,a->length,V_ASN1_OBJECT)); + objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT); + if (pp == NULL) return objsize; p= *pp; ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL); @@ -77,15 +79,17 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) p+=a->length; *pp=p; - return(a->length); + return(objsize); } int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) { - int i,first,len=0,c; - char tmp[24]; + int i,first,len=0,c, use_bn; + char ftmp[24], *tmp = ftmp; + int tmpsize = sizeof ftmp; const char *p; unsigned long l; + BIGNUM *bl = NULL; if (num == 0) return(0); @@ -97,7 +101,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) num--; if ((c >= '0') && (c <= '2')) { - first=(c-'0')*40; + first= c-'0'; } else { @@ -121,6 +125,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) goto err; } l=0; + use_bn = 0; for (;;) { if (num <= 0) break; @@ -133,7 +138,22 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); goto err; } - l=l*10L+(long)(c-'0'); + if (!use_bn && l > (ULONG_MAX / 10L)) + { + use_bn = 1; + if (!bl) + bl = BN_new(); + if (!bl || !BN_set_word(bl, l)) + goto err; + } + if (use_bn) + { + if (!BN_mul_word(bl, 10L) + || !BN_add_word(bl, c-'0')) + goto err; + } + else + l=l*10L+(long)(c-'0'); } if (len == 0) { @@ -142,14 +162,42 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE); goto err; } - l+=(long)first; + if (use_bn) + { + if (!BN_add_word(bl, first * 40)) + goto err; + } + else + l+=(long)first*40; } i=0; - for (;;) + if (use_bn) { - tmp[i++]=(unsigned char)l&0x7f; - l>>=7L; - if (l == 0L) break; + int blsize; + blsize = BN_num_bits(bl); + blsize = (blsize + 6)/7; + if (blsize > tmpsize) + { + if (tmp != ftmp) + OPENSSL_free(tmp); + tmpsize = blsize + 32; + tmp = OPENSSL_malloc(tmpsize); + if (!tmp) + goto err; + } + while(blsize--) + tmp[i++] = BN_div_word(bl, 0x80L); + } + else + { + + for (;;) + { + tmp[i++]=(unsigned char)l&0x7f; + l>>=7L; + if (l == 0L) break; + } + } if (out != NULL) { @@ -165,8 +213,16 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) else len+=i; } + if (tmp != ftmp) + OPENSSL_free(tmp); + if (bl) + BN_free(bl); return(len); err: + if (tmp != ftmp) + OPENSSL_free(tmp); + if (bl) + BN_free(bl); return(0); } @@ -177,37 +233,34 @@ int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) { - char buf[80]; + char buf[80], *p = buf; int i; if ((a == NULL) || (a->data == NULL)) return(BIO_write(bp,"NULL",4)); - i=i2t_ASN1_OBJECT(buf,80,a); - if (i > 80) i=80; - BIO_write(bp,buf,i); + i=i2t_ASN1_OBJECT(buf,sizeof buf,a); + if (i > (int)(sizeof(buf) - 1)) + { + p = OPENSSL_malloc(i + 1); + if (!p) + return -1; + i2t_ASN1_OBJECT(p,i + 1,a); + } + BIO_write(bp,p,i); + if (p != buf) + OPENSSL_free(p); return(i); } -ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long length) - { - ASN1_OBJECT *ret=NULL; - unsigned char *p; +{ + const unsigned char *p; long len; int tag,xclass; int inf,i; - - /* only the ASN1_OBJECTs from the 'table' will have values - * for ->sn or ->ln */ - if ((a == NULL) || ((*a) == NULL) || - !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) - { - if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); - } - else ret=(*a); - + ASN1_OBJECT *ret = NULL; p= *pp; - inf=ASN1_get_object(&p,&len,&tag,&xclass,length); if (inf & 0x80) { @@ -220,10 +273,36 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_OBJECT; goto err; } + ret = c2i_ASN1_OBJECT(a, &p, len); + if(ret) *pp = p; + return ret; +err: + ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_OBJECT_free(ret); + return(NULL); +} +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long len) + { + ASN1_OBJECT *ret=NULL; + const unsigned char *p; + int i; + + /* only the ASN1_OBJECTs from the 'table' will have values + * for ->sn or ->ln */ + if ((a == NULL) || ((*a) == NULL) || + !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) + { + if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); + } + else ret=(*a); + + p= *pp; if ((ret->data == NULL) || (ret->length < len)) { - if (ret->data != NULL) Free((char *)ret->data); - ret->data=(unsigned char *)Malloc(len ? (int)len : 1); + if (ret->data != NULL) OPENSSL_free(ret->data); + ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; if (ret->data == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } @@ -239,7 +318,7 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, *pp=p; return(ret); err: - ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); + ASN1err(ASN1_F_C2I_ASN1_OBJECT,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_OBJECT_free(ret); return(NULL); @@ -249,7 +328,7 @@ ASN1_OBJECT *ASN1_OBJECT_new(void) { ASN1_OBJECT *ret; - ret=(ASN1_OBJECT *)Malloc(sizeof(ASN1_OBJECT)); + ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); if (ret == NULL) { ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE); @@ -269,24 +348,24 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a) if (a == NULL) return; if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { -#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause mempory leaks */ - if (a->sn != NULL) Free((void *)a->sn); - if (a->ln != NULL) Free((void *)a->ln); +#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */ + if (a->sn != NULL) OPENSSL_free((void *)a->sn); + if (a->ln != NULL) OPENSSL_free((void *)a->ln); #endif a->sn=a->ln=NULL; } if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { - if (a->data != NULL) Free(a->data); + if (a->data != NULL) OPENSSL_free(a->data); a->data=NULL; a->length=0; } if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) - Free(a); + OPENSSL_free(a); } ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, - char *sn, char *ln) + const char *sn, const char *ln) { ASN1_OBJECT o;