Loading CHANGES +12 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,18 @@ Changes between 0.9.5a and 0.9.6 [xx XXX 2000] Changes between 0.9.5a and 0.9.6 [xx XXX 2000] *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT STRING types. These convert content octets to and from the underlying type. The actual tag and length octets are already assumed to have been read in and checked. These are needed because all other string types have virtually identical handling apart from the tag. By having versions of the ASN1 functions that just operate on content octets IMPLICIT tagging can be handled properly. It also allows the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED and ASN1_INTEGER are identical apart from the tag. [Steve Henson] *) Change the handling of OID objects as follows: *) Change the handling of OID objects as follows: - New object identifiers are inserted in objects.txt, following - New object identifiers are inserted in objects.txt, following Loading crypto/asn1/a_bitstr.c +45 −17 Original line number Original line Diff line number Diff line Loading @@ -71,12 +71,26 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { { int ret,j,r,bits,len; int len, ret; len = i2c_ASN1_BIT_STRING(a, NULL); ret=ASN1_object_size(0,len,V_ASN1_BIT_STRING); if(pp) { ASN1_put_object(pp,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); i2c_ASN1_BIT_STRING(a, pp); } return ret; } int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { int ret,j,bits,len; unsigned char *p,*d; unsigned char *p,*d; if (a == NULL) return(0); if (a == NULL) return(0); len=a->length; len=a->length; ret=1+len; if (pp == NULL) return(ret); if (len > 0) if (len > 0) { { Loading Loading @@ -104,36 +118,27 @@ int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) } } else else bits=0; bits=0; ret=1+len; r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); if (pp == NULL) return(r); p= *pp; p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); *(p++)=(unsigned char)bits; *(p++)=(unsigned char)bits; d=a->data; d=a->data; memcpy(p,d,len); memcpy(p,d,len); p+=len; p+=len; if (len > 0) p[-1]&=(0xff<<bits); if (len > 0) p[-1]&=(0xff<<bits); *pp=p; *pp=p; return(r); return(ret); } } /* Convert DER encoded ASN1 BIT_STRING to ASN1_BIT_STRING structure */ ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, long length) long length) { { ASN1_BIT_STRING *ret=NULL; unsigned char *p; unsigned char *p,*s; long len; long len; int inf,tag,xclass; int i; int i; int inf,tag,xclass; if ((a == NULL) || ((*a) == NULL)) ASN1_BIT_STRING *ret; { if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL); } else ret=(*a); p= *pp; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); inf=ASN1_get_object(&p,&len,&tag,&xclass,length); Loading @@ -149,7 +154,30 @@ ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, goto err; goto err; } } if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } ret = c2i_ASN1_BIT_STRING(a, &p, len); if(ret) *pp = p; return ret; err: ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); return(NULL); } ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, long len) { ASN1_BIT_STRING *ret=NULL; unsigned char *p,*s; int i; if ((a == NULL) || ((*a) == NULL)) { if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL); } else ret=(*a); p= *pp; i= *(p++); i= *(p++); /* We do this to preserve the settings. If we modify /* We do this to preserve the settings. If we modify * the settings, via the _set_bit function, we will recalculate * the settings, via the _set_bit function, we will recalculate Loading crypto/asn1/a_enum.c +21 −135 Original line number Original line Diff line number Diff line Loading @@ -71,88 +71,27 @@ ASN1_ENUMERATED *ASN1_ENUMERATED_new(void) void ASN1_ENUMERATED_free(ASN1_ENUMERATED *x) void ASN1_ENUMERATED_free(ASN1_ENUMERATED *x) { M_ASN1_ENUMERATED_free(x); } { M_ASN1_ENUMERATED_free(x); } int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **pp) { int pad=0,ret,r,i,t; unsigned char *p,*n,pb=0; if ((a == NULL) || (a->data == NULL)) return(0); t=a->type; if (a->length == 0) ret=1; else { ret=a->length; i=a->data[0]; if ((t == V_ASN1_ENUMERATED) && (i > 127)) { pad=1; pb=0; } else if(t == V_ASN1_NEG_ENUMERATED) { if(i>128) { pad=1; pb=0xFF; } else if(i == 128) { for(i = 1; i < a->length; i++) if(a->data[i]) { pad=1; pb=0xFF; break; } } } ret+=pad; } r=ASN1_object_size(0,ret,V_ASN1_ENUMERATED); if (pp == NULL) return(r); p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL); int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **pp) if (pad) *(p++)=pb; if (a->length == 0) *(p++)=0; else if (t == V_ASN1_ENUMERATED) { { memcpy(p,a->data,(unsigned int)a->length); int len, ret; p+=a->length; len = i2c_ASN1_INTEGER(a, NULL); } ret=ASN1_object_size(0,len,V_ASN1_ENUMERATED); else { if(pp) { /* Begin at the end of the encoding */ ASN1_put_object(pp,0,ret,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL); n=a->data + a->length - 1; i2c_ASN1_INTEGER(a, pp); p += a->length - 1; i = a->length; /* Copy zeros to destination as long as source is zero */ while(!*n) { *(p--) = 0; n--; i--; } /* Complement and increment next octet */ *(p--) = ((*(n--)) ^ 0xff) + 1; i--; /* Complement any octets left */ for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; p += a->length; } } return ret; *pp=p; return(r); } } ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, long length) long length) { { ASN1_ENUMERATED *ret=NULL; unsigned char *p; unsigned char *p,*to,*s; long len; long len; int inf,tag,xclass; int i; int i; int inf,tag,xclass; if ((a == NULL) || ((*a) == NULL)) ASN1_ENUMERATED *ret; { if ((ret=M_ASN1_ENUMERATED_new()) == NULL) return(NULL); ret->type=V_ASN1_ENUMERATED; } else ret=(*a); p= *pp; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); inf=ASN1_get_object(&p,&len,&tag,&xclass,length); Loading @@ -167,69 +106,16 @@ ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_ENUMERATED; i=ASN1_R_EXPECTING_AN_ENUMERATED; goto err; goto err; } } ret = c2i_ASN1_INTEGER(a, &p, len); /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it if(ret) { * signifies a missing NULL parameter. */ ret->type = (V_ASN1_NEG & ret->type) | V_ASN1_ENUMERATED; s=(unsigned char *)OPENSSL_malloc((int)len+1); if (s == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } to=s; if(!len) { /* Strictly speaking this is an illegal ENUMERATED but we * tolerate it. */ ret->type=V_ASN1_ENUMERATED; } else if (*p & 0x80) /* a negative number */ { ret->type=V_ASN1_NEG_ENUMERATED; if ((*p == 0xff) && (len != 1)) { p++; len--; } i = len; p += i - 1; to += i - 1; while((!*p) && i) { *(to--) = 0; i--; p--; } if(!i) { *s = 1; s[len] = 0; p += len; len++; } else { *(to--) = (*(p--) ^ 0xff) + 1; i--; for(;i > 0; i--) *(to--) = *(p--) ^ 0xff; p += len; } } else { ret->type=V_ASN1_ENUMERATED; if ((*p == 0) && (len != 1)) { p++; len--; } memcpy(s,p,(int)len); p+=len; } if (ret->data != NULL) OPENSSL_free(ret->data); ret->data=s; ret->length=(int)len; if (a != NULL) (*a)=ret; *pp = p; *pp = p; return(ret); } return ret; err: err: ASN1err(ASN1_F_D2I_ASN1_ENUMERATED,i); ASN1err(ASN1_F_D2I_ASN1_ENUMERATED,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) M_ASN1_ENUMERATED_free(ret); return(NULL); return(NULL); } } int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) Loading crypto/asn1/a_int.c +59 −25 Original line number Original line Diff line number Diff line Loading @@ -72,8 +72,22 @@ ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) { return M_ASN1_INTEGER_cmp(x,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 * 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 * 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. * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. Loading @@ -97,23 +111,23 @@ int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) * followed by optional zeros isn't padded. * 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; unsigned char *p,*n,pb=0; if ((a == NULL) || (a->data == NULL)) return(0); if ((a == NULL) || (a->data == NULL)) return(0); t=a->type; neg=a->type & V_ASN1_NEG; if (a->length == 0) if (a->length == 0) ret=1; ret=1; else else { { ret=a->length; ret=a->length; i=a->data[0]; i=a->data[0]; if ((t == V_ASN1_INTEGER) && (i > 127)) { if (!neg && (i > 127)) { pad=1; pad=1; pb=0; pb=0; } else if(t == V_ASN1_NEG_INTEGER) { } else if(neg) { if(i>128) { if(i>128) { pad=1; pad=1; pb=0xFF; pb=0xFF; Loading @@ -131,14 +145,12 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) } } ret+=pad; ret+=pad; } } r=ASN1_object_size(0,ret,V_ASN1_INTEGER); if (pp == NULL) return(ret); if (pp == NULL) return(r); p= *pp; p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL); if (pad) *(p++)=pb; if (pad) *(p++)=pb; if (a->length == 0) *(p++)=0; 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 { else { /* Begin at the end of the encoding */ /* Begin at the end of the encoding */ n=a->data + a->length - 1; n=a->data + a->length - 1; Loading @@ -157,30 +169,22 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; } } *pp+=r; *pp+=ret; return(r); return(ret); } } /* Convert DER encoded ASN1 INTEGER to ASN1_INTEGER structure */ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, long length) long length) { { ASN1_INTEGER *ret=NULL; unsigned char *p; unsigned char *p,*to,*s, *pend; long len; long len; int inf,tag,xclass; int i; int i; int inf,tag,xclass; if ((a == NULL) || ((*a) == NULL)) ASN1_INTEGER *ret; { if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); ret->type=V_ASN1_INTEGER; } else ret=(*a); p= *pp; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); inf=ASN1_get_object(&p,&len,&tag,&xclass,length); pend = p + len; if (inf & 0x80) if (inf & 0x80) { { i=ASN1_R_BAD_OBJECT_HEADER; i=ASN1_R_BAD_OBJECT_HEADER; Loading @@ -192,6 +196,35 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_INTEGER; i=ASN1_R_EXPECTING_AN_INTEGER; goto err; 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 /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it * signifies a missing NULL parameter. */ * signifies a missing NULL parameter. */ Loading Loading @@ -261,6 +294,7 @@ err: return(NULL); return(NULL); } } /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of * ASN1 integers: some broken software can encode a positive INTEGER * ASN1 integers: some broken software can encode a positive INTEGER * with its MSB set as negative (it doesn't add a padding zero). * with its MSB set as negative (it doesn't add a padding zero). Loading crypto/asn1/asn1.h +10 −2 Original line number Original line Diff line number Diff line Loading @@ -86,11 +86,13 @@ extern "C" { #define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ #define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ #define V_ASN1_NEG 0x100 /* negative flag */ #define V_ASN1_UNDEF -1 #define V_ASN1_UNDEF -1 #define V_ASN1_EOC 0 #define V_ASN1_EOC 0 #define V_ASN1_BOOLEAN 1 /**/ #define V_ASN1_BOOLEAN 1 /**/ #define V_ASN1_INTEGER 2 #define V_ASN1_INTEGER 2 #define V_ASN1_NEG_INTEGER (2+0x100) #define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) #define V_ASN1_BIT_STRING 3 #define V_ASN1_BIT_STRING 3 #define V_ASN1_OCTET_STRING 4 #define V_ASN1_OCTET_STRING 4 #define V_ASN1_NULL 5 #define V_ASN1_NULL 5 Loading @@ -99,7 +101,7 @@ extern "C" { #define V_ASN1_EXTERNAL 8 #define V_ASN1_EXTERNAL 8 #define V_ASN1_REAL 9 #define V_ASN1_REAL 9 #define V_ASN1_ENUMERATED 10 #define V_ASN1_ENUMERATED 10 #define V_ASN1_NEG_ENUMERATED (10+0x100) #define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) #define V_ASN1_UTF8STRING 12 #define V_ASN1_UTF8STRING 12 #define V_ASN1_SEQUENCE 16 #define V_ASN1_SEQUENCE 16 #define V_ASN1_SET 17 #define V_ASN1_SET 17 Loading Loading @@ -526,8 +528,11 @@ unsigned char * ASN1_STRING_data(ASN1_STRING *x); ASN1_BIT_STRING * ASN1_BIT_STRING_new(void); ASN1_BIT_STRING * ASN1_BIT_STRING_new(void); void ASN1_BIT_STRING_free(ASN1_BIT_STRING *a); void ASN1_BIT_STRING_free(ASN1_BIT_STRING *a); int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, long length); long length); ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, long length); int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); int length ); int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); Loading @@ -547,8 +552,11 @@ int d2i_ASN1_BOOLEAN(int *a,unsigned char **pp,long length); ASN1_INTEGER * ASN1_INTEGER_new(void); ASN1_INTEGER * ASN1_INTEGER_new(void); void ASN1_INTEGER_free(ASN1_INTEGER *a); void ASN1_INTEGER_free(ASN1_INTEGER *a); int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, long length); long length); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, long length); ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,unsigned char **pp, ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,unsigned char **pp, long length); long length); ASN1_INTEGER * ASN1_INTEGER_dup(ASN1_INTEGER *x); ASN1_INTEGER * ASN1_INTEGER_dup(ASN1_INTEGER *x); Loading Loading
CHANGES +12 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,18 @@ Changes between 0.9.5a and 0.9.6 [xx XXX 2000] Changes between 0.9.5a and 0.9.6 [xx XXX 2000] *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT STRING types. These convert content octets to and from the underlying type. The actual tag and length octets are already assumed to have been read in and checked. These are needed because all other string types have virtually identical handling apart from the tag. By having versions of the ASN1 functions that just operate on content octets IMPLICIT tagging can be handled properly. It also allows the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED and ASN1_INTEGER are identical apart from the tag. [Steve Henson] *) Change the handling of OID objects as follows: *) Change the handling of OID objects as follows: - New object identifiers are inserted in objects.txt, following - New object identifiers are inserted in objects.txt, following Loading
crypto/asn1/a_bitstr.c +45 −17 Original line number Original line Diff line number Diff line Loading @@ -71,12 +71,26 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { { int ret,j,r,bits,len; int len, ret; len = i2c_ASN1_BIT_STRING(a, NULL); ret=ASN1_object_size(0,len,V_ASN1_BIT_STRING); if(pp) { ASN1_put_object(pp,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); i2c_ASN1_BIT_STRING(a, pp); } return ret; } int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { int ret,j,bits,len; unsigned char *p,*d; unsigned char *p,*d; if (a == NULL) return(0); if (a == NULL) return(0); len=a->length; len=a->length; ret=1+len; if (pp == NULL) return(ret); if (len > 0) if (len > 0) { { Loading Loading @@ -104,36 +118,27 @@ int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) } } else else bits=0; bits=0; ret=1+len; r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); if (pp == NULL) return(r); p= *pp; p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); *(p++)=(unsigned char)bits; *(p++)=(unsigned char)bits; d=a->data; d=a->data; memcpy(p,d,len); memcpy(p,d,len); p+=len; p+=len; if (len > 0) p[-1]&=(0xff<<bits); if (len > 0) p[-1]&=(0xff<<bits); *pp=p; *pp=p; return(r); return(ret); } } /* Convert DER encoded ASN1 BIT_STRING to ASN1_BIT_STRING structure */ ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, long length) long length) { { ASN1_BIT_STRING *ret=NULL; unsigned char *p; unsigned char *p,*s; long len; long len; int inf,tag,xclass; int i; int i; int inf,tag,xclass; if ((a == NULL) || ((*a) == NULL)) ASN1_BIT_STRING *ret; { if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL); } else ret=(*a); p= *pp; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); inf=ASN1_get_object(&p,&len,&tag,&xclass,length); Loading @@ -149,7 +154,30 @@ ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, goto err; goto err; } } if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } ret = c2i_ASN1_BIT_STRING(a, &p, len); if(ret) *pp = p; return ret; err: ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); return(NULL); } ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, long len) { ASN1_BIT_STRING *ret=NULL; unsigned char *p,*s; int i; if ((a == NULL) || ((*a) == NULL)) { if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL); } else ret=(*a); p= *pp; i= *(p++); i= *(p++); /* We do this to preserve the settings. If we modify /* We do this to preserve the settings. If we modify * the settings, via the _set_bit function, we will recalculate * the settings, via the _set_bit function, we will recalculate Loading
crypto/asn1/a_enum.c +21 −135 Original line number Original line Diff line number Diff line Loading @@ -71,88 +71,27 @@ ASN1_ENUMERATED *ASN1_ENUMERATED_new(void) void ASN1_ENUMERATED_free(ASN1_ENUMERATED *x) void ASN1_ENUMERATED_free(ASN1_ENUMERATED *x) { M_ASN1_ENUMERATED_free(x); } { M_ASN1_ENUMERATED_free(x); } int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **pp) { int pad=0,ret,r,i,t; unsigned char *p,*n,pb=0; if ((a == NULL) || (a->data == NULL)) return(0); t=a->type; if (a->length == 0) ret=1; else { ret=a->length; i=a->data[0]; if ((t == V_ASN1_ENUMERATED) && (i > 127)) { pad=1; pb=0; } else if(t == V_ASN1_NEG_ENUMERATED) { if(i>128) { pad=1; pb=0xFF; } else if(i == 128) { for(i = 1; i < a->length; i++) if(a->data[i]) { pad=1; pb=0xFF; break; } } } ret+=pad; } r=ASN1_object_size(0,ret,V_ASN1_ENUMERATED); if (pp == NULL) return(r); p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL); int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **pp) if (pad) *(p++)=pb; if (a->length == 0) *(p++)=0; else if (t == V_ASN1_ENUMERATED) { { memcpy(p,a->data,(unsigned int)a->length); int len, ret; p+=a->length; len = i2c_ASN1_INTEGER(a, NULL); } ret=ASN1_object_size(0,len,V_ASN1_ENUMERATED); else { if(pp) { /* Begin at the end of the encoding */ ASN1_put_object(pp,0,ret,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL); n=a->data + a->length - 1; i2c_ASN1_INTEGER(a, pp); p += a->length - 1; i = a->length; /* Copy zeros to destination as long as source is zero */ while(!*n) { *(p--) = 0; n--; i--; } /* Complement and increment next octet */ *(p--) = ((*(n--)) ^ 0xff) + 1; i--; /* Complement any octets left */ for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; p += a->length; } } return ret; *pp=p; return(r); } } ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, long length) long length) { { ASN1_ENUMERATED *ret=NULL; unsigned char *p; unsigned char *p,*to,*s; long len; long len; int inf,tag,xclass; int i; int i; int inf,tag,xclass; if ((a == NULL) || ((*a) == NULL)) ASN1_ENUMERATED *ret; { if ((ret=M_ASN1_ENUMERATED_new()) == NULL) return(NULL); ret->type=V_ASN1_ENUMERATED; } else ret=(*a); p= *pp; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); inf=ASN1_get_object(&p,&len,&tag,&xclass,length); Loading @@ -167,69 +106,16 @@ ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_ENUMERATED; i=ASN1_R_EXPECTING_AN_ENUMERATED; goto err; goto err; } } ret = c2i_ASN1_INTEGER(a, &p, len); /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it if(ret) { * signifies a missing NULL parameter. */ ret->type = (V_ASN1_NEG & ret->type) | V_ASN1_ENUMERATED; s=(unsigned char *)OPENSSL_malloc((int)len+1); if (s == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } to=s; if(!len) { /* Strictly speaking this is an illegal ENUMERATED but we * tolerate it. */ ret->type=V_ASN1_ENUMERATED; } else if (*p & 0x80) /* a negative number */ { ret->type=V_ASN1_NEG_ENUMERATED; if ((*p == 0xff) && (len != 1)) { p++; len--; } i = len; p += i - 1; to += i - 1; while((!*p) && i) { *(to--) = 0; i--; p--; } if(!i) { *s = 1; s[len] = 0; p += len; len++; } else { *(to--) = (*(p--) ^ 0xff) + 1; i--; for(;i > 0; i--) *(to--) = *(p--) ^ 0xff; p += len; } } else { ret->type=V_ASN1_ENUMERATED; if ((*p == 0) && (len != 1)) { p++; len--; } memcpy(s,p,(int)len); p+=len; } if (ret->data != NULL) OPENSSL_free(ret->data); ret->data=s; ret->length=(int)len; if (a != NULL) (*a)=ret; *pp = p; *pp = p; return(ret); } return ret; err: err: ASN1err(ASN1_F_D2I_ASN1_ENUMERATED,i); ASN1err(ASN1_F_D2I_ASN1_ENUMERATED,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) M_ASN1_ENUMERATED_free(ret); return(NULL); return(NULL); } } int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) Loading
crypto/asn1/a_int.c +59 −25 Original line number Original line Diff line number Diff line Loading @@ -72,8 +72,22 @@ ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) { return M_ASN1_INTEGER_cmp(x,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 * 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 * 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. * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. Loading @@ -97,23 +111,23 @@ int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) * followed by optional zeros isn't padded. * 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; unsigned char *p,*n,pb=0; if ((a == NULL) || (a->data == NULL)) return(0); if ((a == NULL) || (a->data == NULL)) return(0); t=a->type; neg=a->type & V_ASN1_NEG; if (a->length == 0) if (a->length == 0) ret=1; ret=1; else else { { ret=a->length; ret=a->length; i=a->data[0]; i=a->data[0]; if ((t == V_ASN1_INTEGER) && (i > 127)) { if (!neg && (i > 127)) { pad=1; pad=1; pb=0; pb=0; } else if(t == V_ASN1_NEG_INTEGER) { } else if(neg) { if(i>128) { if(i>128) { pad=1; pad=1; pb=0xFF; pb=0xFF; Loading @@ -131,14 +145,12 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) } } ret+=pad; ret+=pad; } } r=ASN1_object_size(0,ret,V_ASN1_INTEGER); if (pp == NULL) return(ret); if (pp == NULL) return(r); p= *pp; p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_INTEGER,V_ASN1_UNIVERSAL); if (pad) *(p++)=pb; if (pad) *(p++)=pb; if (a->length == 0) *(p++)=0; 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 { else { /* Begin at the end of the encoding */ /* Begin at the end of the encoding */ n=a->data + a->length - 1; n=a->data + a->length - 1; Loading @@ -157,30 +169,22 @@ int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; } } *pp+=r; *pp+=ret; return(r); return(ret); } } /* Convert DER encoded ASN1 INTEGER to ASN1_INTEGER structure */ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, long length) long length) { { ASN1_INTEGER *ret=NULL; unsigned char *p; unsigned char *p,*to,*s, *pend; long len; long len; int inf,tag,xclass; int i; int i; int inf,tag,xclass; if ((a == NULL) || ((*a) == NULL)) ASN1_INTEGER *ret; { if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL); ret->type=V_ASN1_INTEGER; } else ret=(*a); p= *pp; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); inf=ASN1_get_object(&p,&len,&tag,&xclass,length); pend = p + len; if (inf & 0x80) if (inf & 0x80) { { i=ASN1_R_BAD_OBJECT_HEADER; i=ASN1_R_BAD_OBJECT_HEADER; Loading @@ -192,6 +196,35 @@ ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_INTEGER; i=ASN1_R_EXPECTING_AN_INTEGER; goto err; 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 /* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it * signifies a missing NULL parameter. */ * signifies a missing NULL parameter. */ Loading Loading @@ -261,6 +294,7 @@ err: return(NULL); return(NULL); } } /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of * ASN1 integers: some broken software can encode a positive INTEGER * ASN1 integers: some broken software can encode a positive INTEGER * with its MSB set as negative (it doesn't add a padding zero). * with its MSB set as negative (it doesn't add a padding zero). Loading
crypto/asn1/asn1.h +10 −2 Original line number Original line Diff line number Diff line Loading @@ -86,11 +86,13 @@ extern "C" { #define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ #define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ #define V_ASN1_NEG 0x100 /* negative flag */ #define V_ASN1_UNDEF -1 #define V_ASN1_UNDEF -1 #define V_ASN1_EOC 0 #define V_ASN1_EOC 0 #define V_ASN1_BOOLEAN 1 /**/ #define V_ASN1_BOOLEAN 1 /**/ #define V_ASN1_INTEGER 2 #define V_ASN1_INTEGER 2 #define V_ASN1_NEG_INTEGER (2+0x100) #define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) #define V_ASN1_BIT_STRING 3 #define V_ASN1_BIT_STRING 3 #define V_ASN1_OCTET_STRING 4 #define V_ASN1_OCTET_STRING 4 #define V_ASN1_NULL 5 #define V_ASN1_NULL 5 Loading @@ -99,7 +101,7 @@ extern "C" { #define V_ASN1_EXTERNAL 8 #define V_ASN1_EXTERNAL 8 #define V_ASN1_REAL 9 #define V_ASN1_REAL 9 #define V_ASN1_ENUMERATED 10 #define V_ASN1_ENUMERATED 10 #define V_ASN1_NEG_ENUMERATED (10+0x100) #define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) #define V_ASN1_UTF8STRING 12 #define V_ASN1_UTF8STRING 12 #define V_ASN1_SEQUENCE 16 #define V_ASN1_SEQUENCE 16 #define V_ASN1_SET 17 #define V_ASN1_SET 17 Loading Loading @@ -526,8 +528,11 @@ unsigned char * ASN1_STRING_data(ASN1_STRING *x); ASN1_BIT_STRING * ASN1_BIT_STRING_new(void); ASN1_BIT_STRING * ASN1_BIT_STRING_new(void); void ASN1_BIT_STRING_free(ASN1_BIT_STRING *a); void ASN1_BIT_STRING_free(ASN1_BIT_STRING *a); int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, long length); long length); ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, long length); int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); int length ); int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); Loading @@ -547,8 +552,11 @@ int d2i_ASN1_BOOLEAN(int *a,unsigned char **pp,long length); ASN1_INTEGER * ASN1_INTEGER_new(void); ASN1_INTEGER * ASN1_INTEGER_new(void); void ASN1_INTEGER_free(ASN1_INTEGER *a); void ASN1_INTEGER_free(ASN1_INTEGER *a); int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, long length); long length); ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, long length); ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,unsigned char **pp, ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,unsigned char **pp, long length); long length); ASN1_INTEGER * ASN1_INTEGER_dup(ASN1_INTEGER *x); ASN1_INTEGER * ASN1_INTEGER_dup(ASN1_INTEGER *x); Loading