diff options
Diffstat (limited to 'crypto/asn1')
59 files changed, 1088 insertions, 390 deletions
diff --git a/crypto/asn1/Makefile.ssl b/crypto/asn1/Makefile.ssl index 30751bd156..1e9951fc56 100644 --- a/crypto/asn1/Makefile.ssl +++ b/crypto/asn1/Makefile.ssl @@ -23,7 +23,7 @@ APPS= LIB=$(TOP)/libcrypto.a LIBSRC= a_object.c a_bitstr.c a_utctm.c a_int.c a_octet.c a_print.c \ - a_type.c a_set.c a_dup.c a_d2i_fp.c a_i2d_fp.c \ + a_type.c a_set.c a_dup.c a_d2i_fp.c a_i2d_fp.c a_bmp.c \ a_sign.c a_digest.c a_verify.c \ x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c \ x_name.c x_cinf.c x_x509.c x_crl.c x_info.c x_spki.c \ @@ -38,7 +38,7 @@ LIBSRC= a_object.c a_bitstr.c a_utctm.c a_int.c a_octet.c a_print.c \ asn1_par.c asn1_lib.c $(ERRC).c a_meth.c a_bytes.c \ evp_asn1.c LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_int.o a_octet.o a_print.o \ - a_type.o a_set.o a_dup.o a_d2i_fp.o a_i2d_fp.o \ + a_type.o a_set.o a_dup.o a_d2i_fp.o a_i2d_fp.o a_bmp.o \ a_sign.o a_digest.o a_verify.o \ x_algor.o x_val.o x_pubkey.o x_sig.o x_req.o x_attrib.o \ x_name.o x_cinf.o x_x509.o x_crl.o x_info.o x_spki.o \ diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c index 2c10120651..275de43eb6 100644 --- a/crypto/asn1/a_bitstr.c +++ b/crypto/asn1/a_bitstr.c @@ -68,27 +68,50 @@ int i2d_ASN1_BIT_STRING(a,pp) ASN1_BIT_STRING *a; unsigned char **pp; { - int ret,j,r,bits; + int ret,j,r,bits,len; unsigned char *p,*d; if (a == NULL) return(0); - /* our bit strings are always a multiple of 8 :-) */ - bits=0; - ret=1+a->length; + len=a->length; + + if (len > 0) + { + if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) + { + bits=(int)a->flags&0x07; + } + else + { + for ( ; len > 0; len--) + { + if (a->data[len-1]) break; + } + j=a->data[len-1]; + if (j & 0x01) bits=0; + else if (j & 0x02) bits=1; + else if (j & 0x04) bits=2; + else if (j & 0x08) bits=3; + else if (j & 0x10) bits=4; + else if (j & 0x20) bits=5; + else if (j & 0x40) bits=6; + else if (j & 0x80) bits=7; + else bits=0; /* should not happen */ + } + } + else + bits=0; + ret=1+len; r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); if (pp == NULL) return(r); p= *pp; ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); - if (bits == 0) - j=0; - else j=8-bits; - *(p++)=(unsigned char)j; + *(p++)=(unsigned char)bits; d=a->data; - memcpy(p,d,a->length); - p+=a->length; - if (a->length > 0) p[-1]&=(0xff<<j); + memcpy(p,d,len); + p+=len; + if (len > 0) p[-1]&=(0xff<<bits); *pp=p; return(r); } @@ -127,6 +150,12 @@ long length; if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } i= *(p++); + /* We do this to preserve the settings. If we modify + * the settings, via the _set_bit function, we will recalculate + * on output */ + ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ + ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */ + if (len-- > 1) /* using one because of the bits left byte */ { s=(unsigned char *)Malloc((int)len); @@ -170,6 +199,8 @@ int value; v=1<<(7-(n&0x07)); iv= ~v; + a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */ + if (a == NULL) return(0); if ((a->length < (w+1)) || (a->data == NULL)) { diff --git a/crypto/asn1/a_bitstr.orig.c b/crypto/asn1/a_bitstr.orig.c new file mode 100644 index 0000000000..871e0575d9 --- /dev/null +++ b/crypto/asn1/a_bitstr.orig.c @@ -0,0 +1,236 @@ +/* crypto/asn1/a_bitstr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "asn1.h" + +/* ASN1err(ASN1_F_ASN1_STRING_NEW,ASN1_R_STRING_TOO_SHORT); + * ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,ASN1_R_EXPECTING_A_BIT_STRING); + */ + +int i2d_ASN1_BIT_STRING(a,pp) +ASN1_BIT_STRING *a; +unsigned char **pp; + { + int ret,i,j,r,bits,len; + unsigned char *p,*d; + + if (a == NULL) return(0); + + len=a->length; + + if ((len > 0) + { + if (a->flags & ASN1_FG_BITS_LEFT)) + { + bits=a->flags&0x07; + } + else + { + for ( ; len > 0; len--) + { + if (a->data[len-1]) break; + } + j=a->data[len-1]; + if (j & 0x80) bits=1; + else if (j & 0x40) bits=2; + else if (j & 0x20) bits=3; + else if (j & 0x10) bits=4; + else if (j & 0x08) bits=5; + else if (j & 0x04) bits=6; + else if (j & 0x02) bits=7; + else if (j & 0x01) bits=8; + else bits=0; + } + } + else + bits=0; + ret=1+len; + r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); + if (pp == NULL) return(r); + p= *pp; + + ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); + if (bits == 0) + j=0; + else j=8-bits; + *(p++)=(unsigned char)j; + d=a->data; + memcpy(p,d,len); + p+=len; + if (len > 0) p[-1]&=(0xff<<j); + *pp=p; + return(r); + } + +ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(a, pp, length) +ASN1_BIT_STRING **a; +unsigned char **pp; +long length; + { + ASN1_BIT_STRING *ret=NULL; + unsigned char *p,*s; + long len; + int inf,tag,xclass; + int i; + + if ((a == NULL) || ((*a) == NULL)) + { + if ((ret=ASN1_BIT_STRING_new()) == NULL) return(NULL); + } + else + ret=(*a); + + p= *pp; + inf=ASN1_get_object(&p,&len,&tag,&xclass,length); + if (inf & 0x80) + { + i=ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_BIT_STRING) + { + i=ASN1_R_EXPECTING_A_BIT_STRING; + goto err; + } + if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } + + i= *(p++); + ret->flag&= ~(ASN1_FG_BITS_LEFT|0x07); /* clear */ + if (i > 0) + ret->flag|=(ASN1_FG_BITS_LEFT|(i&0x07)); /* set */ + + if (len-- > 1) /* using one because of the bits left byte */ + { + s=(unsigned char *)Malloc((int)len); + if (s == NULL) + { + i=ERR_R_MALLOC_FAILURE; + goto err; + } + memcpy(s,p,(int)len); + s[len-1]&=(0xff<<i); + p+=len; + } + else + s=NULL; + + ret->length=(int)len; + if (ret->data != NULL) Free((char *)ret->data); + ret->data=s; + ret->type=V_ASN1_BIT_STRING; + if (a != NULL) (*a)=ret; + *pp=p; + return(ret); +err: + ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_BIT_STRING_free(ret); + return(NULL); + } + +/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de> + */ +int ASN1_BIT_STRING_set_bit(a,n,value) +ASN1_BIT_STRING *a; +int n; +int value; + { + int w,v,iv; + unsigned char *c; + + w=n/8; + v=1<<(7-(n&0x07)); + iv= ~v; + + a->flag&= ~(ASN1_FG_BITS_LEFT|0x07); /* clear, set on write */ + + if (a == NULL) return(0); + if ((a->length < (w+1)) || (a->data == NULL)) + { + if (!value) return(1); /* Don't need to set */ + if (a->data == NULL) + c=(unsigned char *)Malloc(w+1); + else + c=(unsigned char *)Realloc(a->data,w+1); + if (c == NULL) return(0); + a->data=c; + a->length=w+1; + c[w]=0; + } + a->data[w]=((a->data[w])&iv)|v; + while ((a->length > 0) && (a->data[a->length-1] == 0)) + a->length--; + return(1); + } + +int ASN1_BIT_STRING_get_bit(a,n) +ASN1_BIT_STRING *a; +int n; + { + int w,v; + + w=n/8; + v=1<<(7-(n&0x07)); + if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL)) + return(0); + return((a->data[w]&v) != 0); + } + diff --git a/crypto/asn1/a_bmp.c b/crypto/asn1/a_bmp.c index 774502b1fc..76a6f1cd66 100644 --- a/crypto/asn1/a_bmp.c +++ b/crypto/asn1/a_bmp.c @@ -79,10 +79,10 @@ long length; ASN1_BMPSTRING *ret=NULL; ret=(ASN1_BMPSTRING *)d2i_ASN1_bytes((ASN1_STRING **)a, - pp,length,V_ASN1_BMPSTRING,V_ASN1_UNIVERSAL); + pp,length,V_ASN1_BMPSTRING,V_ASN1_UNIVERSAL); if (ret == NULL) { - ASN1err(ASN1_F_D2I_ASN1_BMPSTRING,ASN1_R_ERROR_STACK); + ASN1err(ASN1_F_D2I_ASN1_BMPSTRING,ERR_R_NESTED_ASN1_ERROR); return(NULL); } return(ret); diff --git a/crypto/asn1/a_bytes.c b/crypto/asn1/a_bytes.c index 14168d61ad..6bfa983349 100644 --- a/crypto/asn1/a_bytes.c +++ b/crypto/asn1/a_bytes.c @@ -60,9 +60,7 @@ #include "cryptlib.h" #include "asn1_mac.h" -/* ASN1err(ASN1_F_ASN1_TYPE_NEW,ASN1_R_ERROR_STACK); - * ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,ASN1_R_ERROR_STACK); - * ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,ASN1_R_WRONG_TYPE); +/* ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,ASN1_R_WRONG_TYPE); * ASN1err(ASN1_F_ASN1_COLLATE_PRIMATIVE,ASN1_R_WRONG_TAG); */ diff --git a/crypto/asn1/a_hdr.c b/crypto/asn1/a_hdr.c index 4fb7a5fa75..e9de2838d0 100644 --- a/crypto/asn1/a_hdr.c +++ b/crypto/asn1/a_hdr.c @@ -62,10 +62,10 @@ #include "asn1.h" /* - * ASN1err(ASN1_F_D2I_ASN1_HEADER,ASN1_R_LENGTH_MISMATCH); - * ASN1err(ASN1_F_I2D_ASN1_HEADER,ASN1_R_BAD_GET_OBJECT); - * ASN1err(ASN1_F_I2D_ASN1_HEADER,ASN1_R_BAD_GET_OBJECT); - * ASN1err(ASN1_F_ASN1_HEADER_NEW,ASN1_R_BAD_GET_OBJECT); + * ASN1err(ASN1_F_D2I_ASN1_HEADER,ERR_R_ASN1_LENGTH_MISMATCH); + * ASN1err(ASN1_F_I2D_ASN1_HEADER,ERR_R_BAD_GET_ASN1_OBJECT_CALL); + * ASN1err(ASN1_F_I2D_ASN1_HEADER,ERR_R_BAD_GET_ASN1_OBJECT_CALL); + * ASN1err(ASN1_F_ASN1_HEADER_NEW,ERR_R_BAD_GET_ASN1_OBJECT_CALL); */ int i2d_ASN1_HEADER(a,pp) @@ -110,6 +110,7 @@ long length; ASN1_HEADER *ASN1_HEADER_new() { ASN1_HEADER *ret=NULL; + ASN1_CTX c; M_ASN1_New_Malloc(ret,ASN1_HEADER); M_ASN1_New(ret->header,ASN1_OCTET_STRING_new); diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index df79cf99bb..e847efee85 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -279,7 +279,7 @@ ASN1_INTEGER *ai; ret=ai; if (ret == NULL) { - ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ASN1_R_ERROR_STACK); + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR); goto err; } ret->type=V_ASN1_INTEGER; diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index 5a7eeef8d8..a476960d9a 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -382,8 +382,8 @@ char *sn,*ln; o.data=data; o.nid=nid; o.length=len; - o.flags=ASN1_OBJECT_FLAG_DYNAMIC| - ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA; + o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS| + ASN1_OBJECT_FLAG_DYNAMIC_DATA; return(OBJ_dup(&o)); } diff --git a/crypto/asn1/a_octet.c b/crypto/asn1/a_octet.c index be3f172a8c..5954c7bee0 100644 --- a/crypto/asn1/a_octet.c +++ b/crypto/asn1/a_octet.c @@ -82,7 +82,7 @@ long length; pp,length,V_ASN1_OCTET_STRING,V_ASN1_UNIVERSAL); if (ret == NULL) { - ASN1err(ASN1_F_D2I_ASN1_OCTET_STRING,ASN1_R_ERROR_STACK); + ASN1err(ASN1_F_D2I_ASN1_OCTET_STRING,ERR_R_NESTED_ASN1_ERROR); return(NULL); } return(ret); diff --git a/crypto/asn1/a_set.c b/crypto/asn1/a_set.c index 17c49946cf..7fd4807e52 100644 --- a/crypto/asn1/a_set.c +++ b/crypto/asn1/a_set.c @@ -89,11 +89,12 @@ int ex_class; return(r); } -STACK *d2i_ASN1_SET(a,pp,length,func,ex_tag,ex_class) +STACK *d2i_ASN1_SET(a,pp,length,func,free_func,ex_tag,ex_class) STACK **a; unsigned char **pp; long length; char *(*func)(); +void (*free_func)(); int ex_tag; int ex_class; { @@ -136,14 +137,25 @@ int ex_class; char *s; if (M_ASN1_D2I_end_sequence()) break; - if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) goto err; + if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) + { + ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT); + asn1_add_error(*pp,(int)(c.q- *pp)); + goto err; + } if (!sk_push(ret,s)) goto err; } if (a != NULL) (*a)=ret; *pp=c.p; return(ret); err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) sk_free(ret); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + { + if (free_func != NULL) + sk_pop_free(ret,free_func); + else + sk_free(ret); + } return(NULL); } diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c index 02188e68c4..c2ff9783ac 100644 --- a/crypto/asn1/a_sign.c +++ b/crypto/asn1/a_sign.c @@ -136,7 +136,11 @@ EVP_MD *type; signature->data=buf_out; buf_out=NULL; signature->length=outl; - + /* In the interests of compatability, I'll make sure that + * the bit string has a 'not-used bits' value of 0 + */ + signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; err: memset(&ctx,0,sizeof(ctx)); if (buf_in != NULL) diff --git a/crypto/asn1/a_type.c b/crypto/asn1/a_type.c index 7c0004084c..7ddf5f9917 100644 --- a/crypto/asn1/a_type.c +++ b/crypto/asn1/a_type.c @@ -60,9 +60,7 @@ #include "cryptlib.h" #include "asn1_mac.h" -/* ASN1err(ASN1_F_ASN1_TYPE_NEW,ASN1_R_ERROR_STACK); - * ASN1err(ASN1_F |