X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fasn1%2Fa_int.c;h=c6fd204ae3b7221d5ab5323f68bc0c6b7fff4818;hb=e69adea53921cac7a7a012cade24cce228a310a5;hp=bcbdc7d4e128cbd995bb1a93c3ca9480b92e221c;hpb=d8223efd04f8526b602209ee5f39c06fa300beea;p=openssl.git diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index bcbdc7d4e1..c6fd204ae3 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -59,21 +59,35 @@ #include #include "cryptlib.h" #include +#include -ASN1_INTEGER *ASN1_INTEGER_new(void) -{ return M_ASN1_INTEGER_new();} +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) +{ return M_ASN1_INTEGER_dup(x);} -void ASN1_INTEGER_free(ASN1_INTEGER *x) -{ M_ASN1_INTEGER_free(x);} +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) + { + int neg, ret; + /* Compare signs */ + neg = x->type & V_ASN1_NEG; + if (neg != (y->type & V_ASN1_NEG)) + { + if (neg) + return -1; + else + return 1; + } -ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) -{ return M_ASN1_INTEGER_dup(x);} + ret = ASN1_STRING_cmp(x, y); -int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) -{ return M_ASN1_INTEGER_cmp(x,y);} + if (neg) + return -ret; + else + return ret; + } + /* - * This converts an ASN1 INTEGER into its DER encoding. + * This converts an ASN1 INTEGER into its content encoding. * The internal representation is an ASN1_STRING whose data is a big endian * representation of the value, ignoring the sign. The sign is determined by * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. @@ -97,23 +111,23 @@ int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) * followed by optional zeros isn't padded. */ -int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) { - int pad=0,ret,r,i,t; + int pad=0,ret,i,neg; unsigned char *p,*n,pb=0; if ((a == NULL) || (a->data == NULL)) return(0); - t=a->type; + neg=a->type & V_ASN1_NEG; if (a->length == 0) ret=1; else { ret=a->length; i=a->data[0]; - if ((t == V_ASN1_INTEGER) && (i > 127)) { + if (!neg && (i > 127)) { pad=1; pb=0; - } else if(t == V_ASN1_NEG_INTEGER) { + } else if(neg) { if(i>128) { pad=1; pb=0xFF; @@ -131,14 +145,12 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) } ret+=pad; } - r=ASN1_object_size(0,ret,V_ASN1_INTEGER); - if (pp == NULL) return(r); + if (pp == NULL) return(ret); p= *pp; - ASN1_put_object(&p,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL); if (pad) *(p++)=pb; if (a->length == 0) *(p++)=0; - else if (t == V_ASN1_INTEGER) memcpy(p,a->data,(unsigned int)a->length); + else if (!neg) memcpy(p,a->data,(unsigned int)a->length); else { /* Begin at the end of the encoding */ n=a->data + a->length - 1; @@ -157,17 +169,18 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; } - *pp+=r; - return(r); + *pp+=ret; + return(ret); } -ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, - long length) +/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long len) { ASN1_INTEGER *ret=NULL; - unsigned char *p,*to,*s, *pend; - long len; - int inf,tag,xclass; + const unsigned char *p, *pend; + unsigned char *to,*s; int i; if ((a == NULL) || ((*a) == NULL)) @@ -179,23 +192,11 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, ret=(*a); p= *pp; - inf=ASN1_get_object(&p,&len,&tag,&xclass,length); pend = p + len; - if (inf & 0x80) - { - i=ASN1_R_BAD_OBJECT_HEADER; - goto err; - } - if (tag != V_ASN1_INTEGER) - { - i=ASN1_R_EXPECTING_AN_INTEGER; - goto err; - } - - /* We must Malloc stuff, even for 0 bytes otherwise it + /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it * signifies a missing NULL parameter. */ - s=(unsigned char *)Malloc((int)len+1); + s=(unsigned char *)OPENSSL_malloc((int)len+1); if (s == NULL) { i=ERR_R_MALLOC_FAILURE; @@ -248,29 +249,31 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, memcpy(s,p,(int)len); } - if (ret->data != NULL) Free((char *)ret->data); + if (ret->data != NULL) OPENSSL_free(ret->data); ret->data=s; ret->length=(int)len; if (a != NULL) (*a)=ret; *pp=pend; return(ret); err: - ASN1err(ASN1_F_D2I_ASN1_INTEGER,i); + ASN1err(ASN1_F_C2I_ASN1_INTEGER,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) M_ASN1_INTEGER_free(ret); return(NULL); } + /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of * ASN1 integers: some broken software can encode a positive INTEGER * with its MSB set as negative (it doesn't add a padding zero). */ -ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, unsigned char **pp, +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length) { ASN1_INTEGER *ret=NULL; - unsigned char *p,*to,*s; + const unsigned char *p; + unsigned char *to,*s; long len; int inf,tag,xclass; int i; @@ -297,9 +300,9 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, unsigned char **pp, goto err; } - /* We must Malloc stuff, even for 0 bytes otherwise it + /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it * signifies a missing NULL parameter. */ - s=(unsigned char *)Malloc((int)len+1); + s=(unsigned char *)OPENSSL_malloc((int)len+1); if (s == NULL) { i=ERR_R_MALLOC_FAILURE; @@ -317,7 +320,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, unsigned char **pp, p+=len; } - if (ret->data != NULL) Free((char *)ret->data); + if (ret->data != NULL) OPENSSL_free(ret->data); ret->data=s; ret->length=(int)len; if (a != NULL) (*a)=ret; @@ -332,16 +335,17 @@ err: int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) { - int i,j,k; + int j,k; + unsigned int i; unsigned char buf[sizeof(long)+1]; long d; a->type=V_ASN1_INTEGER; - if (a->length < (sizeof(long)+1)) + if (a->length < (int)(sizeof(long)+1)) { if (a->data != NULL) - Free((char *)a->data); - if ((a->data=(unsigned char *)Malloc(sizeof(long)+1)) != NULL) + OPENSSL_free(a->data); + if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL) memset((char *)a->data,0,sizeof(long)+1); } if (a->data == NULL) @@ -369,7 +373,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) return(1); } -long ASN1_INTEGER_get(ASN1_INTEGER *a) +long ASN1_INTEGER_get(const ASN1_INTEGER *a) { int neg=0,i; long r=0; @@ -379,15 +383,15 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a) if (i == V_ASN1_NEG_INTEGER) neg=1; else if (i != V_ASN1_INTEGER) - return(0); + return -1; - if (a->length > sizeof(long)) + if (a->length > (int)sizeof(long)) { /* hmm... a bit ugly */ return(0xffffffffL); } if (a->data == NULL) - return(0); + return 0; for (i=0; ilength; i++) { @@ -398,7 +402,7 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a) return(r); } -ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai) +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) { ASN1_INTEGER *ret; int len,j; @@ -412,24 +416,44 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai) ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR); goto err; } - if(bn->neg) ret->type = V_ASN1_NEG_INTEGER; + if (BN_is_negative(bn)) + ret->type = V_ASN1_NEG_INTEGER; else ret->type=V_ASN1_INTEGER; j=BN_num_bits(bn); len=((j == 0)?0:((j/8)+1)); - ret->data=(unsigned char *)Malloc(len+4); + if (ret->length < len+4) + { + unsigned char *new_data=OPENSSL_realloc(ret->data, len+4); + if (!new_data) + { + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE); + goto err; + } + ret->data=new_data; + } ret->length=BN_bn2bin(bn,ret->data); + /* Correct zero case */ + if(!ret->length) + { + ret->data[0] = 0; + ret->length = 1; + } return(ret); err: if (ret != ai) M_ASN1_INTEGER_free(ret); return(NULL); } -BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn) +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) { BIGNUM *ret; if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB); - if(ai->type == V_ASN1_NEG_INTEGER) bn->neg = 1; + else if(ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); return(ret); } + +IMPLEMENT_STACK_OF(ASN1_INTEGER) +IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)