From a338e21bd1f1654b9fc90352a45e054be1f947eb Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 7 Jul 2000 13:24:36 +0000 Subject: New ASN1 functions that just deal with content octets, not tag+length. --- crypto/asn1/a_int.c | 84 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 25 deletions(-) (limited to 'crypto/asn1/a_int.c') diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index 82db75f5e1..721592bf1c 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -72,8 +72,22 @@ ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) { return M_ASN1_INTEGER_cmp(x,y);} +/* Output ASN1 INTEGER including tag+length */ + +int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) +{ + int len, ret; + len = i2c_ASN1_INTEGER(a, NULL); + ret=ASN1_object_size(0,len,V_ASN1_INTEGER); + if(pp) { + ASN1_put_object(pp,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL); + i2c_ASN1_INTEGER(a, pp); + } + 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,30 +169,22 @@ 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); } +/* Convert DER encoded ASN1 INTEGER to ASN1_INTEGER structure */ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, long length) - { - ASN1_INTEGER *ret=NULL; - unsigned char *p,*to,*s, *pend; +{ + unsigned char *p; long len; - int inf,tag,xclass; int i; - - if ((a == NULL) || ((*a) == NULL)) - { - if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); - ret->type=V_ASN1_INTEGER; - } - else - ret=(*a); + int inf,tag,xclass; + ASN1_INTEGER *ret; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); - pend = p + len; if (inf & 0x80) { i=ASN1_R_BAD_OBJECT_HEADER; @@ -192,6 +196,35 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_INTEGER; goto err; } + ret = c2i_ASN1_INTEGER(a, &p, len); + if(ret) *pp = p; + return ret; +err: + ASN1err(ASN1_F_D2I_ASN1_INTEGER,i); + return(NULL); + +} + + +/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, + long len) + { + ASN1_INTEGER *ret=NULL; + unsigned char *p,*to,*s, *pend; + int i; + + if ((a == NULL) || ((*a) == NULL)) + { + if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); + ret->type=V_ASN1_INTEGER; + } + else + ret=(*a); + + p= *pp; + pend = p + len; /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it * signifies a missing NULL parameter. */ @@ -261,6 +294,7 @@ err: 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). -- cgit v1.2.3