From 38ce604e3cc97706b876b0525ddff0121115456d Mon Sep 17 00:00:00 2001 From: djm <> Date: Sat, 6 Sep 2008 12:17:54 +0000 Subject: resolve conflicts --- src/lib/libcrypto/asn1/a_bitstr.c | 13 +- src/lib/libcrypto/asn1/a_bool.c | 4 +- src/lib/libcrypto/asn1/a_bytes.c | 22 +- src/lib/libcrypto/asn1/a_d2i_fp.c | 32 +- src/lib/libcrypto/asn1/a_digest.c | 2 +- src/lib/libcrypto/asn1/a_dup.c | 18 +- src/lib/libcrypto/asn1/a_enum.c | 12 +- src/lib/libcrypto/asn1/a_gentm.c | 2 +- src/lib/libcrypto/asn1/a_hdr.c | 6 +- src/lib/libcrypto/asn1/a_i2d_fp.c | 8 +- src/lib/libcrypto/asn1/a_int.c | 26 +- src/lib/libcrypto/asn1/a_mbstr.c | 20 +- src/lib/libcrypto/asn1/a_meth.c | 16 +- src/lib/libcrypto/asn1/a_object.c | 100 +++- src/lib/libcrypto/asn1/a_octet.c | 2 +- src/lib/libcrypto/asn1/a_set.c | 21 +- src/lib/libcrypto/asn1/a_sign.c | 23 +- src/lib/libcrypto/asn1/a_strex.c | 32 +- src/lib/libcrypto/asn1/a_type.c | 28 +- src/lib/libcrypto/asn1/a_utctm.c | 2 +- src/lib/libcrypto/asn1/a_verify.c | 12 +- src/lib/libcrypto/asn1/asn1.h | 341 +++++++++--- src/lib/libcrypto/asn1/asn1_err.c | 91 +++- src/lib/libcrypto/asn1/asn1_lib.c | 73 ++- src/lib/libcrypto/asn1/asn1_mac.h | 39 +- src/lib/libcrypto/asn1/asn1_par.c | 58 +- src/lib/libcrypto/asn1/asn1t.h | 109 ++-- src/lib/libcrypto/asn1/asn_moid.c | 64 ++- src/lib/libcrypto/asn1/asn_pack.c | 26 +- src/lib/libcrypto/asn1/d2i_pr.c | 24 +- src/lib/libcrypto/asn1/d2i_pu.c | 19 +- src/lib/libcrypto/asn1/evp_asn1.c | 4 +- src/lib/libcrypto/asn1/i2d_pr.c | 9 + src/lib/libcrypto/asn1/i2d_pu.c | 7 + src/lib/libcrypto/asn1/n_pkey.c | 49 +- src/lib/libcrypto/asn1/p5_pbe.c | 15 +- src/lib/libcrypto/asn1/p5_pbev2.c | 6 +- src/lib/libcrypto/asn1/t_crl.c | 4 +- src/lib/libcrypto/asn1/t_pkey.c | 548 +++++++++++++++++-- src/lib/libcrypto/asn1/t_req.c | 22 +- src/lib/libcrypto/asn1/t_spki.c | 16 + src/lib/libcrypto/asn1/t_x509.c | 37 +- src/lib/libcrypto/asn1/tasn_dec.c | 1059 ++++++++++++++++++++++++------------- src/lib/libcrypto/asn1/tasn_enc.c | 514 ++++++++++++------ src/lib/libcrypto/asn1/tasn_fre.c | 149 ++++-- src/lib/libcrypto/asn1/tasn_new.c | 234 ++++---- src/lib/libcrypto/asn1/tasn_typ.c | 4 + src/lib/libcrypto/asn1/tasn_utl.c | 128 +++-- src/lib/libcrypto/asn1/x_algor.c | 57 ++ src/lib/libcrypto/asn1/x_bignum.c | 6 +- src/lib/libcrypto/asn1/x_crl.c | 2 +- src/lib/libcrypto/asn1/x_exten.c | 5 + src/lib/libcrypto/asn1/x_long.c | 8 +- src/lib/libcrypto/asn1/x_name.c | 52 +- src/lib/libcrypto/asn1/x_pkey.c | 6 +- src/lib/libcrypto/asn1/x_pubkey.c | 285 ++++++++-- src/lib/libcrypto/asn1/x_req.c | 2 +- src/lib/libcrypto/asn1/x_x509.c | 27 +- src/lib/libcrypto/asn1/x_x509a.c | 29 + 59 files changed, 3254 insertions(+), 1275 deletions(-) (limited to 'src/lib/libcrypto/asn1') diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c index b81bf4fc81..0fb9ce0c2a 100644 --- a/src/lib/libcrypto/asn1/a_bitstr.c +++ b/src/lib/libcrypto/asn1/a_bitstr.c @@ -113,11 +113,12 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) return(ret); } -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, - long len) +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) { ASN1_BIT_STRING *ret=NULL; - unsigned char *p,*s; + const unsigned char *p; + unsigned char *s; int i; if (len < 1) @@ -164,7 +165,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, *pp=p; return(ret); err: - ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); + ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) M_ASN1_BIT_STRING_free(ret); return(NULL); @@ -182,9 +183,11 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) iv= ~v; if (!value) v=0; + if (a == NULL) + return 0; + 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)) { if (!value) return(1); /* Don't need to set */ diff --git a/src/lib/libcrypto/asn1/a_bool.c b/src/lib/libcrypto/asn1/a_bool.c index 24333ea4d5..331acdf053 100644 --- a/src/lib/libcrypto/asn1/a_bool.c +++ b/src/lib/libcrypto/asn1/a_bool.c @@ -75,10 +75,10 @@ int i2d_ASN1_BOOLEAN(int a, unsigned char **pp) return(r); } -int d2i_ASN1_BOOLEAN(int *a, unsigned char **pp, long length) +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length) { int ret= -1; - unsigned char *p; + const unsigned char *p; long len; int inf,tag,xclass; int i=0; diff --git a/src/lib/libcrypto/asn1/a_bytes.c b/src/lib/libcrypto/asn1/a_bytes.c index 2407f7c87a..92d630cdba 100644 --- a/src/lib/libcrypto/asn1/a_bytes.c +++ b/src/lib/libcrypto/asn1/a_bytes.c @@ -60,14 +60,15 @@ #include "cryptlib.h" #include -static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c); +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c); /* type is a 'bitmap' of acceptable string types. */ -ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, unsigned char **pp, +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, long length, int type) { ASN1_STRING *ret=NULL; - unsigned char *p,*s; + const unsigned char *p; + unsigned char *s; long len; int inf,tag,xclass; int i=0; @@ -153,11 +154,12 @@ int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass) return(r); } -ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, unsigned char **pp, long length, - int Ptag, int Pclass) +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass) { ASN1_STRING *ret=NULL; - unsigned char *p,*s; + const unsigned char *p; + unsigned char *s; long len; int inf,tag,xclass; int i=0; @@ -185,7 +187,7 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, unsigned char **pp, long length, if (inf & V_ASN1_CONSTRUCTED) { - ASN1_CTX c; + ASN1_const_CTX c; c.pp=pp; c.p=p; @@ -247,7 +249,7 @@ err: * them into the one structure that is then returned */ /* There have been a few bug fixes for this function from * Paul Keogh , many thanks to him */ -static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c) +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c) { ASN1_STRING *os=NULL; BUF_MEM b; @@ -268,7 +270,7 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c) { if (c->inf & 1) { - c->eos=ASN1_check_infinite_end(&c->p, + c->eos=ASN1_const_check_infinite_end(&c->p, (long)(c->max-c->p)); if (c->eos) break; } @@ -296,7 +298,7 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c) num+=os->length; } - if (!asn1_Finish(c)) goto err; + if (!asn1_const_Finish(c)) goto err; a->length=num; if (a->data != NULL) OPENSSL_free(a->data); diff --git a/src/lib/libcrypto/asn1/a_d2i_fp.c b/src/lib/libcrypto/asn1/a_d2i_fp.c index b67b75e7c2..ece40bc4c0 100644 --- a/src/lib/libcrypto/asn1/a_d2i_fp.c +++ b/src/lib/libcrypto/asn1/a_d2i_fp.c @@ -66,11 +66,10 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); #ifndef NO_OLD_ASN1 #ifndef OPENSSL_NO_FP_API -char *ASN1_d2i_fp(char *(*xnew)(), char *(*d2i)(), FILE *in, - unsigned char **x) +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x) { BIO *b; - char *ret; + void *ret; if ((b=BIO_new(BIO_s_file())) == NULL) { @@ -84,12 +83,11 @@ char *ASN1_d2i_fp(char *(*xnew)(), char *(*d2i)(), FILE *in, } #endif -char *ASN1_d2i_bio(char *(*xnew)(), char *(*d2i)(), BIO *in, - unsigned char **x) +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x) { BUF_MEM *b = NULL; - unsigned char *p; - char *ret=NULL; + const unsigned char *p; + void *ret=NULL; int len; len = asn1_d2i_read_bio(in, &b); @@ -107,14 +105,14 @@ err: void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) { BUF_MEM *b = NULL; - unsigned char *p; + const unsigned char *p; void *ret=NULL; int len; len = asn1_d2i_read_bio(in, &b); if(len < 0) goto err; - p=(unsigned char *)b->data; + p=(const unsigned char *)b->data; ret=ASN1_item_d2i(x,&p,len, it); err: if (b != NULL) BUF_MEM_free(b); @@ -129,7 +127,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) if ((b=BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_D2I_FP,ERR_R_BUF_LIB); + ASN1err(ASN1_F_ASN1_ITEM_D2I_FP,ERR_R_BUF_LIB); return(NULL); } BIO_set_fp(b,in,BIO_NOCLOSE); @@ -146,7 +144,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) unsigned char *p; int i; int ret=-1; - ASN1_CTX c; + ASN1_const_CTX c; int want=HEADER_SIZE; int eos=0; #if defined(__GNUC__) && defined(__ia64) @@ -160,7 +158,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) b=BUF_MEM_new(); if (b == NULL) { - ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); return -1; } @@ -173,13 +171,13 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) if (!BUF_MEM_grow_clean(b,len+want)) { - ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } i=BIO_read(in,&(b->data[len]),want); if ((i < 0) && ((len-off) == 0)) { - ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA); + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA); goto err; } if (i > 0) @@ -199,7 +197,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) if (e != ASN1_R_TOO_LONG) goto err; else - ERR_get_error(); /* clear error */ + ERR_clear_error(); /* clear error */ } i=c.p-p;/* header length */ off+=i; /* end of data */ @@ -228,7 +226,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) want-=(len-off); if (!BUF_MEM_grow_clean(b,len+want)) { - ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } while (want > 0) @@ -236,7 +234,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) i=BIO_read(in,&(b->data[len]),want); if (i <= 0) { - ASN1err(ASN1_F_ASN1_D2I_BIO, + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA); goto err; } diff --git a/src/lib/libcrypto/asn1/a_digest.c b/src/lib/libcrypto/asn1/a_digest.c index 7182e9fa5d..d00d9e22b1 100644 --- a/src/lib/libcrypto/asn1/a_digest.c +++ b/src/lib/libcrypto/asn1/a_digest.c @@ -72,7 +72,7 @@ #ifndef NO_ASN1_OLD -int ASN1_digest(int (*i2d)(), const EVP_MD *type, char *data, +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, unsigned char *md, unsigned int *len) { int i; diff --git a/src/lib/libcrypto/asn1/a_dup.c b/src/lib/libcrypto/asn1/a_dup.c index 58a017884c..199d50f521 100644 --- a/src/lib/libcrypto/asn1/a_dup.c +++ b/src/lib/libcrypto/asn1/a_dup.c @@ -62,22 +62,23 @@ #ifndef NO_OLD_ASN1 -char *ASN1_dup(int (*i2d)(), char *(*d2i)(), char *x) +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x) { unsigned char *b,*p; - long i; + const unsigned char *p2; + int i; char *ret; if (x == NULL) return(NULL); - i=(long)i2d(x,NULL); - b=(unsigned char *)OPENSSL_malloc((unsigned int)i+10); + i=i2d(x,NULL); + b=OPENSSL_malloc(i+10); if (b == NULL) { ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); } p= b; i=i2d(x,&p); - p= b; - ret=d2i(NULL,&p,i); + p2= b; + ret=d2i(NULL,&p2,i); OPENSSL_free(b); return(ret); } @@ -91,7 +92,8 @@ char *ASN1_dup(int (*i2d)(), char *(*d2i)(), char *x) void *ASN1_item_dup(const ASN1_ITEM *it, void *x) { - unsigned char *b = NULL, *p; + unsigned char *b = NULL; + const unsigned char *p; long i; void *ret; @@ -99,7 +101,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, void *x) i=ASN1_item_i2d(x,&b,it); if (b == NULL) - { ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); } + { ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); } p= b; ret=ASN1_item_d2i(NULL,&p,i, it); OPENSSL_free(b); diff --git a/src/lib/libcrypto/asn1/a_enum.c b/src/lib/libcrypto/asn1/a_enum.c index 03ede68d1c..fe9aa13b9c 100644 --- a/src/lib/libcrypto/asn1/a_enum.c +++ b/src/lib/libcrypto/asn1/a_enum.c @@ -59,6 +59,7 @@ #include #include "cryptlib.h" #include +#include /* * Code for ENUMERATED type: identical to INTEGER apart from a different tag. @@ -67,12 +68,13 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *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_ENUMERATED; - if (a->length < (sizeof(long)+1)) + if (a->length < (int)(sizeof(long)+1)) { if (a->data != NULL) OPENSSL_free(a->data); @@ -116,7 +118,7 @@ long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a) else if (i != V_ASN1_ENUMERATED) return -1; - if (a->length > sizeof(long)) + if (a->length > (int)sizeof(long)) { /* hmm... a bit ugly */ return(0xffffffffL); @@ -147,7 +149,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR); goto err; } - if(bn->neg) ret->type = V_ASN1_NEG_ENUMERATED; + if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED; else ret->type=V_ASN1_ENUMERATED; j=BN_num_bits(bn); len=((j == 0)?0:((j/8)+1)); @@ -175,6 +177,6 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn) if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB); - else if(ai->type == V_ASN1_NEG_ENUMERATED) ret->neg = 1; + else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1); return(ret); } diff --git a/src/lib/libcrypto/asn1/a_gentm.c b/src/lib/libcrypto/asn1/a_gentm.c index 0dfd576211..def79062a5 100644 --- a/src/lib/libcrypto/asn1/a_gentm.c +++ b/src/lib/libcrypto/asn1/a_gentm.c @@ -181,7 +181,7 @@ err: return(0); } -int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, char *str) +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) { ASN1_GENERALIZEDTIME t; diff --git a/src/lib/libcrypto/asn1/a_hdr.c b/src/lib/libcrypto/asn1/a_hdr.c index b1aad81f77..d1c2a7b9e3 100644 --- a/src/lib/libcrypto/asn1/a_hdr.c +++ b/src/lib/libcrypto/asn1/a_hdr.c @@ -76,17 +76,17 @@ int i2d_ASN1_HEADER(ASN1_HEADER *a, unsigned char **pp) M_ASN1_I2D_finish(); } -ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a, unsigned char **pp, +ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a, const unsigned char **pp, long length) { M_ASN1_D2I_vars(a,ASN1_HEADER *,ASN1_HEADER_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get(ret->header,d2i_ASN1_OCTET_STRING); + M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->header,d2i_ASN1_OCTET_STRING); if (ret->meth != NULL) { - M_ASN1_D2I_get(ret->data,ret->meth->d2i); + M_ASN1_D2I_get_x(void,ret->data,ret->meth->d2i); } else { diff --git a/src/lib/libcrypto/asn1/a_i2d_fp.c b/src/lib/libcrypto/asn1/a_i2d_fp.c index f4f1b73ebe..a3ad76d356 100644 --- a/src/lib/libcrypto/asn1/a_i2d_fp.c +++ b/src/lib/libcrypto/asn1/a_i2d_fp.c @@ -64,7 +64,7 @@ #ifndef NO_OLD_ASN1 #ifndef OPENSSL_NO_FP_API -int ASN1_i2d_fp(int (*i2d)(), FILE *out, unsigned char *x) +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) { BIO *b; int ret; @@ -81,7 +81,7 @@ int ASN1_i2d_fp(int (*i2d)(), FILE *out, unsigned char *x) } #endif -int ASN1_i2d_bio(int (*i2d)(), BIO *out, unsigned char *x) +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) { char *b; unsigned char *p; @@ -124,7 +124,7 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) if ((b=BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_I2D_FP,ERR_R_BUF_LIB); + ASN1err(ASN1_F_ASN1_ITEM_I2D_FP,ERR_R_BUF_LIB); return(0); } BIO_set_fp(b,out,BIO_NOCLOSE); @@ -142,7 +142,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) n = ASN1_item_i2d(x, &b, it); if (b == NULL) { - ASN1err(ASN1_F_ASN1_I2D_BIO,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO,ERR_R_MALLOC_FAILURE); return(0); } diff --git a/src/lib/libcrypto/asn1/a_int.c b/src/lib/libcrypto/asn1/a_int.c index 21cc64bb23..f8d198efb1 100644 --- a/src/lib/libcrypto/asn1/a_int.c +++ b/src/lib/libcrypto/asn1/a_int.c @@ -59,6 +59,7 @@ #include #include "cryptlib.h" #include +#include ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) { return M_ASN1_INTEGER_dup(x);} @@ -174,11 +175,12 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len) { ASN1_INTEGER *ret=NULL; - unsigned char *p,*to,*s, *pend; + const unsigned char *p, *pend; + unsigned char *to,*s; int i; if ((a == NULL) || ((*a) == NULL)) @@ -254,7 +256,7 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **pp, *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); @@ -266,11 +268,12 @@ err: * 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; @@ -332,12 +335,13 @@ 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) OPENSSL_free(a->data); @@ -381,7 +385,7 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a) else if (i != V_ASN1_INTEGER) return -1; - if (a->length > sizeof(long)) + if (a->length > (int)sizeof(long)) { /* hmm... a bit ugly */ return(0xffffffffL); @@ -412,7 +416,8 @@ 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)); @@ -445,7 +450,8 @@ BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn) if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB); - else if(ai->type == V_ASN1_NEG_INTEGER) ret->neg = 1; + else if(ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); return(ret); } diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c index 208b3ec395..2d4800a22a 100644 --- a/src/lib/libcrypto/asn1/a_mbstr.c +++ b/src/lib/libcrypto/asn1/a_mbstr.c @@ -107,7 +107,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, case MBSTRING_BMP: if(len & 1) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_BMPSTRING_LENGTH); return -1; } @@ -116,7 +116,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, case MBSTRING_UNIV: if(len & 3) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); return -1; } @@ -128,7 +128,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* This counts the characters and does utf8 syntax checking */ ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); if(ret < 0) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING); return -1; } @@ -139,19 +139,19 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, break; default: - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_UNKNOWN_FORMAT); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); return -1; } if((minsize > 0) && (nchar < minsize)) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_SHORT); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize); ERR_add_error_data(2, "minsize=", strbuf); return -1; } if((maxsize > 0) && (nchar > maxsize)) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_LONG); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize); ERR_add_error_data(2, "maxsize=", strbuf); return -1; @@ -159,7 +159,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* Now work out minimal type (if any) */ if(traverse_string(in, len, inform, type_str, &mask) < 0) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_ILLEGAL_CHARACTERS); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); return -1; } @@ -193,7 +193,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, free_out = 1; dest = ASN1_STRING_type_new(str_type); if(!dest) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY, + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); return -1; } @@ -202,7 +202,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* If both the same type just copy across */ if(inform == outform) { if(!ASN1_STRING_set(dest, in, len)) { - ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE); return -1; } return str_type; @@ -233,7 +233,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, } if(!(p = OPENSSL_malloc(outlen + 1))) { if(free_out) ASN1_STRING_free(dest); - ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE); return -1; } dest->length = outlen; diff --git a/src/lib/libcrypto/asn1/a_meth.c b/src/lib/libcrypto/asn1/a_meth.c index 63158e9cab..50bea917e3 100644 --- a/src/lib/libcrypto/asn1/a_meth.c +++ b/src/lib/libcrypto/asn1/a_meth.c @@ -62,16 +62,16 @@ #include static ASN1_METHOD ia5string_meth={ - (int (*)()) i2d_ASN1_IA5STRING, - (char *(*)()) d2i_ASN1_IA5STRING, - (char *(*)()) ASN1_STRING_new, - (void (*)()) ASN1_STRING_free}; + (I2D_OF(void)) i2d_ASN1_IA5STRING, + (D2I_OF(void)) d2i_ASN1_IA5STRING, + (void *(*)(void))ASN1_STRING_new, + (void (*)(void *))ASN1_STRING_free}; static ASN1_METHOD bit_string_meth={ - (int (*)()) i2d_ASN1_BIT_STRING, - (char *(*)()) d2i_ASN1_BIT_STRING, - (char *(*)()) ASN1_STRING_new, - (void (*)()) ASN1_STRING_free}; + (I2D_OF(void)) i2d_ASN1_BIT_STRING, + (D2I_OF(void)) d2i_ASN1_BIT_STRING, + (void *(*)(void))ASN1_STRING_new, + (void (*)(void *))ASN1_STRING_free}; ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void) { diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c index 0a8e6c287c..dc980421d0 100644 --- a/src/lib/libcrypto/asn1/a_object.c +++ b/src/lib/libcrypto/asn1/a_object.c @@ -57,10 +57,12 @@ */ #include +#include #include "cryptlib.h" #include #include #include +#include int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) { @@ -83,10 +85,12 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) 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); @@ -98,7 +102,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 { @@ -122,6 +126,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; @@ -134,7 +139,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) { @@ -143,14 +163,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) + { + 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++] = (unsigned char)BN_div_word(bl, 0x80L); + } + else { - tmp[i++]=(unsigned char)l&0x7f; - l>>=7L; - if (l == 0L) break; + + for (;;) + { + tmp[i++]=(unsigned char)l&0x7f; + l>>=7L; + if (l == 0L) break; + } + } if (out != NULL) { @@ -166,8 +214,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); } @@ -178,21 +234,31 @@ 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,sizeof buf,a); - if (i > sizeof buf) i=sizeof buf; - BIO_write(bp,buf,i); + if (i > (int)(sizeof(buf) - 1)) + { + p = OPENSSL_malloc(i + 1); + if (!p) + return -1; + i2t_ASN1_OBJECT(p,i + 1,a); + } + if (i <= 0) + return BIO_write(bp, "", 9); + 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) { - unsigned char *p; + const unsigned char *p; long len; int tag,xclass; int inf,i; @@ -219,11 +285,11 @@ err: ASN1_OBJECT_free(ret); return(NULL); } -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len) { ASN1_OBJECT *ret=NULL; - unsigned char *p; + const unsigned char *p; int i; /* only the ASN1_OBJECTs from the 'table' will have values @@ -255,7 +321,7 @@ ASN1_OBJECT *c2i_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); diff --git a/src/lib/libcrypto/asn1/a_octet.c b/src/lib/libcrypto/asn1/a_octet.c index 9690bae0f1..24fd0f8e5a 100644 --- a/src/lib/libcrypto/asn1/a_octet.c +++ b/src/lib/libcrypto/asn1/a_octet.c @@ -66,6 +66,6 @@ ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *x) int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b) { return M_ASN1_OCTET_STRING_cmp(a, b); } -int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, unsigned char *d, int len) +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len) { return M_ASN1_OCTET_STRING_set(x, d, len); } diff --git a/src/lib/libcrypto/asn1/a_set.c b/src/lib/libcrypto/asn1/a_set.c index e24061c545..958558c204 100644 --- a/src/lib/libcrypto/asn1/a_set.c +++ b/src/lib/libcrypto/asn1/a_set.c @@ -85,8 +85,8 @@ static int SetBlobCmp(const void *elem1, const void *elem2 ) } /* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */ -int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag, - int ex_class, int is_set) +int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, + int ex_class, int is_set) { int ret=0,r; int i; @@ -97,7 +97,7 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag, if (a == NULL) return(0); for (i=sk_num(a)-1; i>=0; i--) - ret+=func(sk_value(a,i),NULL); + ret+=i2d(sk_value(a,i),NULL); r=ASN1_object_size(1,ret,ex_tag); if (pp == NULL) return(r); @@ -111,7 +111,7 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag, if(!is_set || (sk_num(a) < 2)) { for (i=0; ipkey_type == NID_dsaWithSHA1) + if (type->pkey_type == NID_dsaWithSHA1 || + type->pkey_type == NID_ecdsa_with_SHA1) { - /* special case: RFC 2459 tells us to omit 'parameters' - * with id-dsa-with-sha1 */ + /* special case: RFC 3279 tells us to omit 'parameters' + * with id-dsa-with-sha1 and ecdsa-with-SHA1 */ ASN1_TYPE_free(a->parameter); a->parameter = NULL; } @@ -247,12 +248,12 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, a->algorithm=OBJ_nid2obj(type->pkey_type); if (a->algorithm == NULL) { - ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); + ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); goto err; } if (a->algorithm->length == 0) { - ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); goto err; } } @@ -262,7 +263,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, if ((buf_in == NULL) || (buf_out == NULL)) { outl=0; - ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE); goto err; } @@ -272,7 +273,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, (unsigned int *)&outl,pkey)) { outl=0; - ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB); + ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB); goto err; } if (signature->data != NULL) OPENSSL_free(signature->data); diff --git a/src/lib/libcrypto/asn1/a_strex.c b/src/lib/libcrypto/asn1/a_strex.c index a07122ba47..c2dbb6f9a5 100644 --- a/src/lib/libcrypto/asn1/a_strex.c +++ b/src/lib/libcrypto/asn1/a_strex.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -58,12 +58,12 @@ #include #include +#include "cryptlib.h" #include #include #include #include "charmap.h" -#include "cryptlib.h" /* ASN1_STRING_print_ex() and X509_NAME_print_ex(). * Enhanced string and name printing routines handling @@ -170,7 +170,7 @@ static int do_buf(unsigned char *buf, int buflen, q = buf + buflen; outlen = 0; while(p != q) { - if(p == buf) orflags = CHARTYPE_FIRST_ESC_2253; + if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253; else orflags = 0; switch(type & BUF_TYPE_WIDTH_MASK) { case 4: @@ -194,8 +194,10 @@ static int do_buf(unsigned char *buf, int buflen, if(i < 0) return -1; /* Invalid UTF8String */ p += i; break; + default: + return -1; /* invalid width */ } - if (p == q) orflags = CHARTYPE_LAST_ESC_2253; + if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253; if(type & BUF_TYPE_CONVUTF8) { unsigned char utfbuf[6]; int utflen; @@ -223,7 +225,7 @@ static int do_buf(unsigned char *buf, int buflen, static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen) { - const static char hexdig[] = "0123456789ABCDEF"; + static const char hexdig[] = "0123456789ABCDEF"; unsigned char *p, *q; char hextmp[2]; if(arg) { @@ -279,7 +281,7 @@ static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING * otherwise it is the number of bytes per character */ -const static signed char tag2nbyte[] = { +static const signed char tag2nbyte[] = { -1, -1, -1, -1, -1, /* 0-4 */ -1, -1, -1, -1, -1, /* 5-9 */ -1, -1, 0, -1, /* 10-13 */ @@ -356,12 +358,13 @@ static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STR } len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); - if(outlen < 0) return -1; + if(len < 0) return -1; outlen += len; if(quotes) outlen += 2; if(!arg) return outlen; if(quotes && !io_ch(arg, "\"", 1)) return -1; - do_buf(str->data, str->length, type, flags, NULL, io_ch, arg); + if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0) + return -1; if(quotes && !io_ch(arg, "\"", 1)) return -1; return outlen; } @@ -513,7 +516,7 @@ int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags) return do_name_ex(send_bio_chars, out, nm, indent, flags); } - +#ifndef OPENSSL_NO_FP_API int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags) { if(flags == XN_FLAG_COMPAT) @@ -528,17 +531,19 @@ int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long fla } return do_name_ex(send_fp_chars, fp, nm, indent, flags); } +#endif int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) { return do_print_ex(send_bio_chars, out, flags, str); } - +#ifndef OPENSSL_NO_FP_API int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) { return do_print_ex(send_fp_chars, fp, flags, str); } +#endif /* Utility function: convert any string type to UTF8, returns number of bytes * in output string or a negative error code @@ -553,12 +558,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) if((type < 0) || (type > 30)) return -1; mbflag = tag2nbyte[type]; if(mbflag == -1) return -1; - if (mbflag == 0) - mbflag = MBSTRING_UTF8; - else if (mbflag == 4) - mbflag = MBSTRING_UNIV; - else - mbflag |= MBSTRING_FLAG; + mbflag |= MBSTRING_FLAG; stmp.data = NULL; ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); if(ret < 0) return ret; diff --git a/src/lib/libcrypto/asn1/a_type.c b/src/lib/libcrypto/asn1/a_type.c index 2292d49b93..36beceacdb 100644 --- a/src/lib/libcrypto/asn1/a_type.c +++ b/src/lib/libcrypto/asn1/a_type.c @@ -57,8 +57,9 @@ */ #include -#include #include "cryptlib.h" +#include +#include int ASN1_TYPE_get(ASN1_TYPE *a) { @@ -79,6 +80,31 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) a->value.ptr=value; } +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) + { + if (!value || (type == V_ASN1_BOOLEAN)) + { + void *p = (void *)value; + ASN1_TYPE_set(a, type, p); + } + else if (type == V_ASN1_OBJECT) + { + ASN1_OBJECT *odup; + odup = OBJ_dup(value); + if (!odup) + return 0; + ASN1_TYPE_set(a, type, odup); + } + else + { + ASN1_STRING *sdup; + sdup = ASN1_STRING_dup((ASN1_STRING *)value); + if (!sdup) + return 0; + ASN1_TYPE_set(a, type, sdup); + } + return 1; + } IMPLEMENT_STACK_OF(ASN1_TYPE) IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) diff --git a/src/lib/libcrypto/asn1/a_utctm.c b/src/lib/libcrypto/asn1/a_utctm.c index 7b25fed331..d31c028193 100644 --- a/src/lib/libcrypto/asn1/a_utctm.c +++ b/src/lib/libcrypto/asn1/a_utctm.c @@ -162,7 +162,7 @@ err: return(0); } -int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, char *str) +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) { ASN1_UTCTIME t; diff --git a/src/lib/libcrypto/asn1/a_verify.c b/src/lib/libcrypto/asn1/a_verify.c index 18ef0acf00..fdce6e4380 100644 --- a/src/lib/libcrypto/asn1/a_verify.c +++ b/src/lib/libcrypto/asn1/a_verify.c @@ -73,8 +73,8 @@ #ifndef NO_ASN1_OLD -int ASN1_verify(int (*i2d)(), X509_ALGOR *a, ASN1_BIT_STRING *signature, - char *data, EVP_PKEY *pkey) +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey) { EVP_MD_CTX ctx; const EVP_MD *type; @@ -138,13 +138,13 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat type=EVP_get_digestbyname(OBJ_nid2sn(i)); if (type == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } if (!EVP_VerifyInit_ex(&ctx,type, NULL)) { - ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB); + ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } @@ -153,7 +153,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat if (buf_in == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } @@ -165,7 +165,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data, (unsigned int)signature->length,pkey) <= 0) { - ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB); + ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } diff --git a/src/lib/libcrypto/asn1/asn1.h b/src/lib/libcrypto/asn1/asn1.h index 0184b475a7..424cd348bb 100644 --- a/src/lib/libcrypto/asn1/asn1.h +++ b/src/lib/libcrypto/asn1/asn1.h @@ -60,17 +60,19 @@ #define HEADER_ASN1_H #include +#include #ifndef OPENSSL_NO_BIO #include #endif -#include -#include #include #include #include #include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif #ifdef OPENSSL_BUILD_SHLIBCRYPTO # undef OPENSSL_EXTERN @@ -147,19 +149,29 @@ extern "C" { #define B_ASN1_UTF8STRING 0x2000 #define B_ASN1_UTCTIME 0x4000 #define B_ASN1_GENERALIZEDTIME 0x8000 +#define B_ASN1_SEQUENCE 0x10000 /* For use with ASN1_mbstring_copy() */ #define MBSTRING_FLAG 0x1000 +#define MBSTRING_UTF8 (MBSTRING_FLAG) #define MBSTRING_ASC (MBSTRING_FLAG|1) #define MBSTRING_BMP (MBSTRING_FLAG|2) -#define MBSTRING_UNIV (MBSTRING_FLAG|3) -#define MBSTRING_UTF8 (MBSTRING_FLAG|4) +#define MBSTRING_UNIV (MBSTRING_FLAG|4) + +#define SMIME_OLDMIME 0x400 +#define SMIME_CRLFEOL 0x800 +#define SMIME_STREAM 0x1000 struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) #define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */ #define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */ +/* We MUST make sure that, except for constness, asn1_ctx_st and + asn1_const_ctx are exactly the same. Fortunately, as soon as + the old ASN1 parsing macros are gone, we can throw this away + as well... */ typedef struct asn1_ctx_st { unsigned char *p;/* work char pointer */ @@ -175,6 +187,21 @@ typedef struct asn1_ctx_st int line; /* used in error processing */ } ASN1_CTX; +typedef struct asn1_const_ctx_st + { + const unsigned char *p;/* work char pointer */ + int eos; /* end of sequence read for indefinite encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + const unsigned char *max; /* largest value of p allowed */ + const unsigned char *q;/* temporary variable */ + const unsigned char **pp;/* variable */ + int line; /* used in error processing */ + } ASN1_const_CTX; + /* These are used internally in the ASN1_OBJECT to keep track of * whether the names and data need to be free()ed */ #define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */ @@ -191,6 +218,18 @@ typedef struct asn1_object_st } ASN1_OBJECT; #define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */ +/* This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should + * be inserted in the memory buffer + */ +#define ASN1_STRING_FLAG_NDEF 0x010 + +/* This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been + * accessed. The flag will be reset when content has been written to it. + */ +#define ASN1_STRING_FLAG_CONT 0x020 + /* This is the base type that holds just about everything :-) */ typedef struct asn1_string_st { @@ -259,18 +298,19 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; #define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) +#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + #define DECLARE_ASN1_FUNCTIONS_name(type, name) \ - type *name##_new(void); \ - void name##_free(type *a); \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) #define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ - type *name##_new(void); \ - void name##_free(type *a); \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) #define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ - type *d2i_##name(type **a, unsigned char **in, long len); \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ int i2d_##name(type *a, unsigned char **out); \ DECLARE_ASN1_ITEM(itname) @@ -279,10 +319,37 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; int i2d_##name(const type *a, unsigned char **out); \ DECLARE_ASN1_ITEM(name) +#define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + #define DECLARE_ASN1_FUNCTIONS_const(name) \ - name *name##_new(void); \ - void name##_free(name *a); + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) +#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +#define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +#define I2D_OF(type) int (*)(type *,unsigned char **) +#define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +#define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +#define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +#define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); /* The following macros and typedefs allow an ASN1_ITEM * to be embedded in a structure and referenced. Since @@ -467,6 +534,7 @@ typedef struct asn1_type_st * contain the set or sequence bytes */ ASN1_STRING * set; ASN1_STRING * sequence; + ASN1_VALUE * asn1_value; } value; } ASN1_TYPE; @@ -475,17 +543,17 @@ DECLARE_ASN1_SET_OF(ASN1_TYPE) typedef struct asn1_method_st { - int (*i2d)(); - char *(*d2i)(); - char *(*create)(); - void (*destroy)(); + i2d_of_void *i2d; + d2i_of_void *d2i; + void *(*create)(void); + void (*destroy)(void *); } ASN1_METHOD; /* This is used when parsing some Netscape objects */ typedef struct asn1_header_st { ASN1_OCTET_STRING *header; - char *data; + void *data; ASN1_METHOD *meth; } ASN1_HEADER; @@ -551,6 +619,7 @@ typedef struct BIT_STRING_BITNAME_st { B_ASN1_UNIVERSALSTRING|\ B_ASN1_BMPSTRING|\ B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ B_ASN1_UNKNOWN #define B_ASN1_DIRECTORYSTRING \ @@ -696,13 +765,14 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) int ASN1_TYPE_get(ASN1_TYPE *a); void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); ASN1_OBJECT * ASN1_OBJECT_new(void ); void ASN1_OBJECT_free(ASN1_OBJECT *a); int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp); -ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,unsigned char **pp, +ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, long length); -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); DECLARE_ASN1_ITEM(ASN1_OBJECT) @@ -718,6 +788,7 @@ int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b); /* Since this is used to store all sorts of things, via macros, for now, make its data void * */ int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); int ASN1_STRING_length(ASN1_STRING *x); void ASN1_STRING_length_set(ASN1_STRING *x, int n); int ASN1_STRING_type(ASN1_STRING *x); @@ -725,7 +796,7 @@ unsigned char * ASN1_STRING_data(ASN1_STRING *x); DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,unsigned char **pp, +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp, long length); int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); @@ -741,13 +812,13 @@ int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, BIT_STRING_BITNAME *tbl); int i2d_ASN1_BOOLEAN(int a,unsigned char **pp); -int d2i_ASN1_BOOLEAN(int *a,unsigned char **pp,long length); +int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length); DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp, +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); -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 * ASN1_INTEGER_dup(ASN1_INTEGER *x); int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y); @@ -756,7 +827,7 @@ DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) int ASN1_UTCTIME_check(ASN1_UTCTIME *a); ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t); -int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, char *str); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); #if 0 time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); @@ -764,12 +835,12 @@ time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a); ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t); -int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, char *str); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a); int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b); -int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, unsigned char *data, int len); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len); DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) @@ -792,15 +863,17 @@ DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) DECLARE_ASN1_FUNCTIONS(ASN1_TIME) +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t); int ASN1_TIME_check(ASN1_TIME *t); ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); -int i2d_ASN1_SET(STACK *a, unsigned char **pp, - int (*func)(), int ex_tag, int ex_class, int is_set); -STACK * d2i_ASN1_SET(STACK **a, unsigned char **pp, long length, - char *(*func)(), void (*free_func)(void *), - int ex_tag, int ex_class); +int i2d_ASN1_SET(STACK *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); +STACK * d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length, + d2i_of_void *d2i, void (*free_func)(void *), + int ex_tag, int ex_class); #ifndef OPENSSL_NO_BIO int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); @@ -832,33 +905,70 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn); int ASN1_PRINTABLE_type(const unsigned char *s, int max); int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); -ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, unsigned char **pp, +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, long length, int Ptag, int Pclass); unsigned long ASN1_tag2bit(int tag); /* type is one or more of the B_ASN1_ values. */ -ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,unsigned char **pp, +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp, long length,int type); /* PARSING */ int asn1_Finish(ASN1_CTX *c); +int asn1_const_Finish(ASN1_const_CTX *c); /* SPECIALS */ -int ASN1_get_object(unsigned char **pp, long *plength, int *ptag, +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax); int ASN1_check_infinite_end(unsigned char **p,long len); +int ASN1_const_check_infinite_end(const unsigned char **p,long len); void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); int ASN1_object_size(int constructed, int length, int tag); /* Used to implement other functions */ -char *ASN1_dup(int (*i2d)(),char *(*d2i)(),char *x); +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); + +#define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) void *ASN1_item_dup(const ASN1_ITEM *it, void *x); +/* ASN1 alloc/free macros for when a type is only used internally */ + +#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +#define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + #ifndef OPENSSL_NO_FP_API -char *ASN1_d2i_fp(char *(*xnew)(),char *(*d2i)(),FILE *fp,unsigned char **x); +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x); + +#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); -int ASN1_i2d_fp(int (*i2d)(),FILE *out,unsigned char *x); +int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x); + +#define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); #endif @@ -866,23 +976,41 @@ int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); #ifndef OPENSSL_NO_BIO -char *ASN1_d2i_bio(char *(*xnew)(),char *(*d2i)(),BIO *bp,unsigned char **x); +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x); + +#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); -int ASN1_i2d_bio(int (*i2d)(),BIO *out,unsigned char *x); +int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x); + +#define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a); int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a); int ASN1_TIME_print(BIO *fp,ASN1_TIME *a); int ASN1_STRING_print(BIO *bp,ASN1_STRING *v); int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); -int ASN1_parse(BIO *bp,unsigned char *pp,long len,int indent); -int ASN1_parse_dump(BIO *bp,unsigned char *pp,long len,int indent,int dump); +int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent); +int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump); #endif const char *ASN1_tag2str(int tag); /* Used to load and write netscape format cert/key */ int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp); -ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,unsigned char **pp, long length); +ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length); ASN1_HEADER *ASN1_HEADER_new(void ); void ASN1_HEADER_free(ASN1_HEADER *a); @@ -903,13 +1031,20 @@ int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num, unsigned char *data, int max_len); -STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(), - void (*free_func)(void *) ); -unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, - int *len ); -void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)()); +STACK *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, void (*free_func)(void *)); +unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d, + unsigned char **buf, int *len ); +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); -ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct); +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); + +#define ASN1_pack_string_of(type,obj,i2d,oct) \ + (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ + CHECKED_I2D_OF(type, i2d), \ + oct)) + ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); void ASN1_STRING_set_default_mask(unsigned long mask); @@ -932,11 +1067,25 @@ void ASN1_STRING_TABLE_cleanup(void); /* Old API compatible functions */ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); -ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it); +ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it); int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); void ASN1_add_oid_module(void); +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + +typedef int asn1_output_data_fn(BIO *out, BIO *data, ASN1_VALUE *val, int flags, + const ASN1_ITEM *it); + +int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, + asn1_output_data_fn *data_fn, + const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -950,49 +1099,70 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_A2I_ASN1_ENUMERATED 101 #define ASN1_F_A2I_ASN1_INTEGER 102 #define ASN1_F_A2I_ASN1_STRING 103 -#define ASN1_F_ASN1_BIT_STRING_SET_BIT 176 +#define ASN1_F_APPEND_EXP 176 +#define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +#define ASN1_F_ASN1_CB 177 #define ASN1_F_ASN1_CHECK_TLEN 104 #define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 #define ASN1_F_ASN1_COLLECT 106 -#define ASN1_F_ASN1_D2I_BIO 107 #define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 #define ASN1_F_ASN1_D2I_FP 109 -#define ASN1_F_ASN1_DIGEST 177 +#define ASN1_F_ASN1_D2I_READ_BIO 107 +#define ASN1_F_ASN1_DIGEST 184 #define ASN1_F_ASN1_DO_ADB 110 #define ASN1_F_ASN1_DUP 111 #define ASN1_F_ASN1_ENUMERATED_SET 112 #define ASN1_F_ASN1_ENUMERATED_TO_BN 113 -#define ASN1_F_ASN1_FIND_END 182 -#define ASN1_F_ASN1_GENERALIZEDTIME_SET 178 +#define ASN1_F_ASN1_EX_C2I 204 +#define ASN1_F_ASN1_FIND_END 190 +#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +#define ASN1_F_ASN1_GENERATE_V3 178 #define ASN1_F_ASN1_GET_OBJECT 114 #define ASN1_F_ASN1_HEADER_NEW 115 #define ASN1_F_ASN1_I2D_BIO 116 #define ASN1_F_ASN1_I2D_FP 117 #define ASN1_F_ASN1_INTEGER_SET 118 #define ASN1_F_ASN1_INTEGER_TO_BN 119 +#define ASN1_F_ASN1_ITEM_D2I_FP 206 +#define ASN1_F_ASN1_ITEM_DUP 191 +#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 #define ASN1_F_ASN1_ITEM_EX_D2I 120 -#define ASN1_F_ASN1_ITEM_NEW 121 -#define ASN1_F_ASN1_MBSTRING_COPY 122 +#define ASN1_F_ASN1_ITEM_I2D_BIO 192 +#define ASN1_F_ASN1_ITEM_I2D_FP 193 +#define ASN1_F_ASN1_ITEM_PACK 198 +#define ASN1_F_ASN1_ITEM_SIGN 195 +#define ASN1_F_ASN1_ITEM_UNPACK 199 +#define ASN1_F_ASN1_ITEM_VERIFY 197 +#define ASN1_F_ASN1_MBSTRING_NCOPY 122 #define ASN1_F_ASN1_OBJECT_NEW 123 +#define ASN1_F_ASN1_OUTPUT_DATA 207 #define ASN1_F_ASN1_PACK_STRING 124 -#define ASN1_F_ASN1_PBE_SET 125 +#define ASN1_F_ASN1_PCTX_NEW 205 +#define ASN1_F_ASN1_PKCS5_PBE_SET 125 #define ASN1_F_ASN1_SEQ_PACK 126 #define ASN1_F_ASN1_SEQ_UNPACK 127 #define ASN1_F_ASN1_SIGN 128 -#define ASN1_F_ASN1_STRING_SET 179 +#define ASN1_F_ASN1_STR2TYPE 179 +#define ASN1_F_ASN1_STRING_SET 186 #define ASN1_F_ASN1_STRING_TABLE_ADD 129 #define ASN1_F_ASN1_STRING_TYPE_NEW 130 -#define ASN1_F_ASN1_TEMPLATE_D2I 131 #define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 #define ASN1_F_ASN1_TEMPLATE_NEW 133 +#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 #define ASN1_F_ASN1_TIME_SET 175 #define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 #define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 #define ASN1_F_ASN1_UNPACK_STRING 136 -#define ASN1_F_ASN1_UTCTIME_SET 180 +#define ASN1_F_ASN1_UTCTIME_SET 187 #define ASN1_F_ASN1_VERIFY 137 +#define ASN1_F_B64_READ_ASN1 208 +#define ASN1_F_B64_WRITE_ASN1 209 +#define ASN1_F_BITSTR_CB 180 #define ASN1_F_BN_TO_ASN1_ENUMERATED 138 #define ASN1_F_BN_TO_ASN1_INTEGER 139 +#define ASN1_F_C2I_ASN1_BIT_STRING 189 +#define ASN1_F_C2I_ASN1_INTEGER 194 +#define ASN1_F_C2I_ASN1_OBJECT 196 #define ASN1_F_COLLECT_DATA 140 #define ASN1_F_D2I_ASN1_BIT_STRING 141 #define ASN1_F_D2I_ASN1_BOOLEAN 142 @@ -1009,29 +1179,39 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_D2I_NETSCAPE_RSA_2 153 #define ASN1_F_D2I_PRIVATEKEY 154 #define ASN1_F_D2I_PUBLICKEY 155 +#define ASN1_F_D2I_RSA_NET 200 +#define ASN1_F_D2I_RSA_NET_2 201 #define ASN1_F_D2I_X509 156 #define ASN1_F_D2I_X509_CINF 157 -#define ASN1_F_D2I_X509_NAME 158 #define ASN1_F_D2I_X509_PKEY 159 -#define ASN1_F_I2D_ASN1_SET 181 +#define ASN1_F_I2D_ASN1_SET 188 #define ASN1_F_I2D_ASN1_TIME 160 #define ASN1_F_I2D_DSA_PUBKEY 161 -#define ASN1_F_I2D_NETSCAPE_RSA 162 +#define ASN1_F_I2D_EC_PUBKEY 181 #define ASN1_F_I2D_PRIVATEKEY 163 #define ASN1_F_I2D_PUBLICKEY 164 +#define ASN1_F_I2D_RSA_NET 162 #define ASN1_F_I2D_RSA_PUBKEY 165 #define ASN1_F_LONG_C2I 166 #define ASN1_F_OID_MODULE_INIT 174 +#define ASN1_F_PARSE_TAGGING 182 #define ASN1_F_PKCS5_PBE2_SET 167 +#define ASN1_F_PKCS5_PBE_SET 202 +#define ASN1_F_SMIME_READ_ASN1 210 +#define ASN1_F_SMIME_TEXT 211 #define ASN1_F_X509_CINF_NEW 168 #define ASN1_F_X509_CRL_ADD0_REVOKED 169 #define ASN1_F_X509_INFO_NEW 170 -#define ASN1_F_X509_NAME_NEW 171 +#define ASN1_F_X509_NAME_ENCODE 203 +#define ASN1_F_X509_NAME_EX_D2I 158 +#define ASN1_F_X509_NAME_EX_NEW 171 #define ASN1_F_X509_NEW 172 #define ASN1_F_X509_PKEY_NEW 173 /* Reason codes. */ #define ASN1_R_ADDING_OBJECT 171 +#define ASN1_R_ASN1_PARSE_ERROR 198 +#define ASN1_R_ASN1_SIG_PARSE_ERROR 199 #define ASN1_R_AUX_ERROR 100 #define ASN1_R_BAD_CLASS 101 #define ASN1_R_BAD_OBJECT_HEADER 102 @@ -1044,6 +1224,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_DATA_IS_WRONG 109 #define ASN1_R_DECODE_ERROR 110 #define ASN1_R_DECODING_ERROR 111 +#define ASN1_R_DEPTH_EXCEEDED 174 #define ASN1_R_ENCODE_ERROR 112 #define ASN1_R_ERROR_GETTING_TIME 173 #define ASN1_R_ERROR_LOADING_SECTION 172 @@ -1058,39 +1239,68 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_FIELD_MISSING 121 #define ASN1_R_FIRST_NUM_TOO_LARGE 122 #define ASN1_R_HEADER_TOO_LONG 123 +#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +#define ASN1_R_ILLEGAL_BOOLEAN 176 #define ASN1_R_ILLEGAL_CHARACTERS 124 +#define ASN1_R_ILLEGAL_FORMAT 177 +#define ASN1_R_ILLEGAL_HEX 178 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +#define ASN1_R_ILLEGAL_INTEGER 180 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 181 #define ASN1_R_ILLEGAL_NULL 125 +#define ASN1_R_ILLEGAL_NULL_VALUE 182 +#define ASN1_R_ILLEGAL_OBJECT 183 #define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 #define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 #define ASN1_R_ILLEGAL_TAGGED_ANY 127 +#define ASN1_R_ILLEGAL_TIME_VALUE 184 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 #define ASN1_R_INVALID_BMPSTRING_LENGTH 129 #define ASN1_R_INVALID_DIGIT 130 +#define ASN1_R_INVALID_MIME_TYPE 200 +#define ASN1_R_INVALID_MODIFIER 186 +#define ASN1_R_INVALID_NUMBER 187 #define ASN1_R_INVALID_SEPARATOR 131 #define ASN1_R_INVALID_TIME_FORMAT 132 #define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 #define ASN1_R_INVALID_UTF8STRING 134 #define ASN1_R_IV_TOO_LARGE 135 #define ASN1_R_LENGTH_ERROR 136 +#define ASN1_R_LIST_ERROR 188 +#define ASN1_R_MIME_NO_CONTENT_TYPE 201 +#define ASN1_R_MIME_PARSE_ERROR 202 +#define ASN1_R_MIME_SIG_PARSE_ERROR 203 #define ASN1_R_MISSING_EOC 137 #define ASN1_R_MISSING_SECOND_NUMBER 138 +#define ASN1_R_MISSING_VALUE 189 #define ASN1_R_MSTRING_NOT_UNIVERSAL 139 #define ASN1_R_MSTRING_WRONG_TAG 140 -#define ASN1_R_NESTED_ASN1_STRING 174 +#define ASN1_R_NESTED_ASN1_STRING 197 #define ASN1_R_NON_HEX_CHARACTERS 141 +#define ASN1_R_NOT_ASCII_FORMAT 190 #define ASN1_R_NOT_ENOUGH_DATA 142 +#define ASN1_R_NO_CONTENT_TYPE 204 #define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +#define ASN1_R_NO_MULTIPART_BODY_FAILURE 205 +#define ASN1_R_NO_MULTIPART_BOUNDARY 206 +#define ASN1_R_NO_SIG_CONTENT_TYPE 207 #define ASN1_R_NULL_IS_WRONG_LENGTH 144 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 #define ASN1_R_ODD_NUMBER_OF_CHARS 145 #define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 #define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 #define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 #define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 #define ASN1_R_SHORT_LINE 150 +#define ASN1_R_SIG_INVALID_MIME_TYPE 208 +#define ASN1_R_STREAMING_NOT_SUPPORTED 209 #define ASN1_R_STRING_TOO_LONG 151 #define ASN1_R_STRING_TOO_SHORT 152 #define ASN1_R_TAG_VALUE_TOO_HIGH 153 #define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 193 #define ASN1_R_TOO_LONG 155 #define ASN1_R_TYPE_NOT_CONSTRUCTED 156 #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 @@ -1100,10 +1310,13 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 #define ASN1_R_UNKNOWN_OBJECT_TYPE 162 #define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +#define ASN1_R_UNKNOWN_TAG 194 +#define ASN1_R_UNKOWN_FORMAT 195 #define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 #define ASN1_R_UNSUPPORTED_CIPHER 165 #define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 #define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +#define ASN1_R_UNSUPPORTED_TYPE 196 #define ASN1_R_WRONG_TAG 168 #define ASN1_R_WRONG_TYPE 169 diff --git a/src/lib/libcrypto/asn1/asn1_err.c b/src/lib/libcrypto/asn1/asn1_err.c index 315d0a0807..f8a3e2e6cd 100644 --- a/src/lib/libcrypto/asn1/asn1_err.c +++ b/src/lib/libcrypto/asn1/asn1_err.c @@ -1,6 +1,6 @@ /* crypto/asn1/asn1_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,49 +74,70 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"}, {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"}, {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"}, +{ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"}, {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"}, +{ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"}, {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"}, {ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"}, {ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"}, -{ERR_FUNC(ASN1_F_ASN1_D2I_BIO), "ASN1_d2i_bio"}, {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"}, {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"}, +{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"}, {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"}, {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"}, {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"}, {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"}, {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, +{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"}, {ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, +{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"}, {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_new"}, {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"}, {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"}, {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"}, {ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"}, {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"}, -{ERR_FUNC(ASN1_F_ASN1_ITEM_NEW), "ASN1_item_new"}, -{ERR_FUNC(ASN1_F_ASN1_MBSTRING_COPY), "ASN1_mbstring_copy"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"}, +{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"}, +{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"}, {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, +{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"}, {ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, -{ERR_FUNC(ASN1_F_ASN1_PBE_SET), "ASN1_PBE_SET"}, +{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"}, +{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"}, +{ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"}, {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"}, {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"}, {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"}, -{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_D2I), "ASN1_TEMPLATE_D2I"}, {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"}, {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"}, +{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"}, {ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"}, {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"}, {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"}, {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"}, {ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"}, {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"}, +{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"}, +{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"}, +{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"}, {ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"}, {ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"}, +{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"}, +{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"}, +{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"}, {ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"}, {ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"}, {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"}, @@ -133,24 +154,32 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"}, {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"}, {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"}, +{ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"}, +{ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"}, {ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, {ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, -{ERR_FUNC(ASN1_F_D2I_X509_NAME), "D2I_X509_NAME"}, {ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, {ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, {ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"}, -{ERR_FUNC(ASN1_F_I2D_NETSCAPE_RSA), "i2d_Netscape_RSA"}, +{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"}, {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"}, {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"}, +{ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"}, {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"}, {ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"}, {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, +{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET), "PKCS5_pbe2_set"}, +{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, +{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, +{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, {ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"}, {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"}, {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"}, -{ERR_FUNC(ASN1_F_X509_NAME_NEW), "X509_NAME_NEW"}, +{ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"}, +{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"}, +{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"}, {ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"}, {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"}, {0,NULL} @@ -159,6 +188,8 @@ static ERR_STRING_DATA ASN1_str_functs[]= static ERR_STRING_DATA ASN1_str_reasons[]= { {ERR_REASON(ASN1_R_ADDING_OBJECT) ,"adding object"}, +{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR) ,"asn1 parse error"}, +{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"}, {ERR_REASON(ASN1_R_AUX_ERROR) ,"aux error"}, {ERR_REASON(ASN1_R_BAD_CLASS) ,"bad class"}, {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) ,"bad object header"}, @@ -171,6 +202,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_DATA_IS_WRONG) ,"data is wrong"}, {ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"}, +{ERR_REASON(ASN1_R_DEPTH_EXCEEDED) ,"depth exceeded"}, {ERR_REASON(ASN1_R_ENCODE_ERROR) ,"encode error"}, {ERR_REASON(ASN1_R_ERROR_GETTING_TIME) ,"error getting time"}, {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"}, @@ -185,39 +217,68 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_FIELD_MISSING) ,"field missing"}, {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE) ,"first num too large"}, {ERR_REASON(ASN1_R_HEADER_TOO_LONG) ,"header too long"}, +{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT),"illegal bitstring format"}, +{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN) ,"illegal boolean"}, {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS) ,"illegal characters"}, +{ERR_REASON(ASN1_R_ILLEGAL_FORMAT) ,"illegal format"}, +{ERR_REASON(ASN1_R_ILLEGAL_HEX) ,"illegal hex"}, +{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) ,"illegal implicit tag"}, +{ERR_REASON(ASN1_R_ILLEGAL_INTEGER) ,"illegal integer"}, +{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING),"illegal nested tagging"}, {ERR_REASON(ASN1_R_ILLEGAL_NULL) ,"illegal null"}, +{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE) ,"illegal null value"}, +{ERR_REASON(ASN1_R_ILLEGAL_OBJECT) ,"illegal object"}, {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) ,"illegal optional any"}, {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),"illegal options on item template"}, {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY) ,"illegal tagged any"}, +{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"}, +{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"}, {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"}, {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"}, {ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"}, +{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"}, +{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"}, +{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"}, {ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"}, {ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"}, {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"}, {ERR_REASON(ASN1_R_INVALID_UTF8STRING) ,"invalid utf8string"}, {ERR_REASON(ASN1_R_IV_TOO_LARGE) ,"iv too large"}, {ERR_REASON(ASN1_R_LENGTH_ERROR) ,"length error"}, +{ERR_REASON(ASN1_R_LIST_ERROR) ,"list error"}, +{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) ,"mime no content type"}, +{ERR_REASON(ASN1_R_MIME_PARSE_ERROR) ,"mime parse error"}, +{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) ,"mime sig parse error"}, {ERR_REASON(ASN1_R_MISSING_EOC) ,"missing eoc"}, {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"}, +{ERR_REASON(ASN1_R_MISSING_VALUE) ,"missing value"}, {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL),"mstring not universal"}, {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG) ,"mstring wrong tag"}, {ERR_REASON(ASN1_R_NESTED_ASN1_STRING) ,"nested asn1 string"}, {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) ,"non hex characters"}, +{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"}, {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"}, +{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"}, {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"}, +{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, +{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, +{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"}, {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"}, +{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"}, {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS) ,"odd number of chars"}, {ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),"private key header missing"}, {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE),"second number too large"}, {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH),"sequence length mismatch"}, {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"}, +{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"}, {ERR_REASON(ASN1_R_SHORT_LINE) ,"short line"}, +{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"}, +{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED),"streaming not supported"}, {ERR_REASON(ASN1_R_STRING_TOO_LONG) ,"string too long"}, {ERR_REASON(ASN1_R_STRING_TOO_SHORT) ,"string too short"}, {ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH) ,"tag value too high"}, {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"}, +{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"}, {ERR_REASON(ASN1_R_TOO_LONG) ,"too long"}, {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"}, {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"}, @@ -227,10 +288,13 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"}, {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"}, {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"}, +{ERR_REASON(ASN1_R_UNKNOWN_TAG) ,"unknown tag"}, +{ERR_REASON(ASN1_R_UNKOWN_FORMAT) ,"unkown format"}, {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"}, {ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"}, {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"}, +{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) ,"unsupported type"}, {ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"}, {ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"}, {0,NULL} @@ -240,15 +304,12 @@ static ERR_STRING_DATA ASN1_str_reasons[]= void ERR_load_ASN1_strings(void) { - static int init=1; +#ifndef OPENSSL_NO_ERR - if (init) + if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) { - init=0; -#ifndef OPENSSL_NO_ERR ERR_load_strings(0,ASN1_str_functs); ERR_load_strings(0,ASN1_str_reasons); -#endif - } +#endif } diff --git a/src/lib/libcrypto/asn1/asn1_lib.c b/src/lib/libcrypto/asn1/asn1_lib.c index 97b9b35f4b..5af559ef8d 100644 --- a/src/lib/libcrypto/asn1/asn1_lib.c +++ b/src/lib/libcrypto/asn1/asn1_lib.c @@ -62,11 +62,11 @@ #include #include -static int asn1_get_length(unsigned char **pp,int *inf,long *rl,int max); +static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max); static void asn1_put_length(unsigned char **pp, int length); -const char *ASN1_version="ASN.1" OPENSSL_VERSION_PTEXT; +const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT; -int ASN1_check_infinite_end(unsigned char **p, long len) +static int _asn1_check_infinite_end(const unsigned char **p, long len) { /* If there is 0 or 1 byte left, the length check should pick * things up */ @@ -80,13 +80,23 @@ int ASN1_check_infinite_end(unsigned char **p, long len) return(0); } +int ASN1_check_infinite_end(unsigned char **p, long len) + { + return _asn1_check_infinite_end((const unsigned char **)p, len); + } -int ASN1_get_object(unsigned char **pp, long *plength, int *ptag, int *pclass, - long omax) +int ASN1_const_check_infinite_end(const unsigned char **p, long len) + { + return _asn1_check_infinite_end(p, len); + } + + +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax) { int i,ret; long l; - unsigned char *p= *pp; + const unsigned char *p= *pp; int tag,xclass,inf; long max=omax; @@ -141,11 +151,11 @@ err: return(0x80); } -static int asn1_get_length(unsigned char **pp, int *inf, long *rl, int max) +static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max) { - unsigned char *p= *pp; + const unsigned char *p= *pp; unsigned long ret=0; - int i; + unsigned int i; if (max-- < 1) return(0); if (*p == 0x80) @@ -205,13 +215,22 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, } p += ttag; } - if ((constructed == 2) && (length == 0)) - *(p++)=0x80; /* der_put_length would output 0 instead */ + if (constructed == 2) + *(p++)=0x80; else asn1_put_length(&p,length); *pp=p; } +int ASN1_put_eoc(unsigned char **pp) + { + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; + } + static void asn1_put_length(unsigned char **pp, int length) { unsigned char *p= *pp; @@ -249,8 +268,8 @@ int ASN1_object_size(int constructed, int length, int tag) ret++; } } - if ((length == 0) && (constructed == 2)) - ret+=2; + if (constructed == 2) + return ret + 3; ret++; if (length > 127) { @@ -263,11 +282,11 @@ int ASN1_object_size(int constructed, int length, int tag) return(ret); } -int asn1_Finish(ASN1_CTX *c) +static int _asn1_Finish(ASN1_const_CTX *c) { if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos)) { - if (!ASN1_check_infinite_end(&c->p,c->slen)) + if (!ASN1_const_check_infinite_end(&c->p,c->slen)) { c->error=ERR_R_MISSING_ASN1_EOS; return(0); @@ -282,9 +301,19 @@ int asn1_Finish(ASN1_CTX *c) return(1); } -int asn1_GetSequence(ASN1_CTX *c, long *length) +int asn1_Finish(ASN1_CTX *c) + { + return _asn1_Finish((ASN1_const_CTX *)c); + } + +int asn1_const_Finish(ASN1_const_CTX *c) { - unsigned char *q; + return _asn1_Finish(c); + } + +int asn1_GetSequence(ASN1_const_CTX *c, long *length) + { + const unsigned char *q; q=c->p; c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass), @@ -364,6 +393,14 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) return(1); } +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) + { + if (str->data) + OPENSSL_free(str->data); + str->data = data; + str->length = len; + } + ASN1_STRING *ASN1_STRING_new(void) { return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); @@ -411,7 +448,7 @@ int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b) return(i); } -void asn1_add_error(unsigned char *address, int offset) +void asn1_add_error(const unsigned char *address, int offset) { char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1]; diff --git a/src/lib/libcrypto/asn1/asn1_mac.h b/src/lib/libcrypto/asn1/asn1_mac.h index a48649ceeb..d958ca60d9 100644 --- a/src/lib/libcrypto/asn1/asn1_mac.h +++ b/src/lib/libcrypto/asn1/asn1_mac.h @@ -73,11 +73,11 @@ extern "C" { ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) #define M_ASN1_D2I_vars(a,type,func) \ - ASN1_CTX c; \ + ASN1_const_CTX c; \ type ret=NULL; \ \ - c.pp=(unsigned char **)pp; \ - c.q= *(unsigned char **)pp; \ + c.pp=(const unsigned char **)pp; \ + c.q= *(const unsigned char **)pp; \ c.error=ERR_R_NESTED_ASN1_ERROR; \ if ((a == NULL) || ((*a) == NULL)) \ { if ((ret=(type)func()) == NULL) \ @@ -85,13 +85,13 @@ extern "C" { else ret=(*a); #define M_ASN1_D2I_Init() \ - c.p= *(unsigned char **)pp; \ + c.p= *(const unsigned char **)pp; \ c.max=(length == 0)?0:(c.p+length); #define M_ASN1_D2I_Finish_2(a) \ - if (!asn1_Finish(&c)) \ + if (!asn1_const_Finish(&c)) \ { c.line=__LINE__; goto err; } \ - *(unsigned char **)pp=c.p; \ + *(const unsigned char **)pp=c.p; \ if (a != NULL) (*a)=ret; \ return(ret); @@ -99,7 +99,7 @@ extern "C" { M_ASN1_D2I_Finish_2(a); \ err:\ ASN1_MAC_H_err((e),c.error,c.line); \ - asn1_add_error(*(unsigned char **)pp,(int)(c.q- *pp)); \ + asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \ if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ return(NULL) @@ -123,15 +123,22 @@ err:\ #define M_ASN1_D2I_end_sequence() \ (((c.inf&1) == 0)?(c.slen <= 0): \ - (c.eos=ASN1_check_infinite_end(&c.p,c.slen))) + (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen))) /* Don't use this with d2i_ASN1_BOOLEAN() */ -#define M_ASN1_D2I_get(b,func) \ +#define M_ASN1_D2I_get(b, func) \ c.q=c.p; \ if (func(&(b),&c.p,c.slen) == NULL) \ {c.line=__LINE__; goto err; } \ c.slen-=(c.p-c.q); +/* Don't use this with d2i_ASN1_BOOLEAN() */ +#define M_ASN1_D2I_get_x(type,b,func) \ + c.q=c.p; \ + if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + /* use this instead () */ #define M_ASN1_D2I_get_int(b,func) \ c.q=c.p; \ @@ -278,7 +285,7 @@ err:\ { c.line=__LINE__; goto err; } \ if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ { c.error=ERR_R_MISSING_ASN1_EOS; \ c.line=__LINE__; goto err; } \ }\ @@ -353,8 +360,12 @@ err:\ return(NULL) -#define M_ASN1_next (*c.p) -#define M_ASN1_next_prev (*c.q) +/* BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately, + some macros that use ASN1_const_CTX still insist on writing in the input + stream. ARGH! ARGH! ARGH! Let's get rid of this macro package. + Please? -- Richard Levitte */ +#define M_ASN1_next (*((unsigned char *)(c.p))) +#define M_ASN1_next_prev (*((unsigned char *)(c.q))) /*************************************************/ @@ -551,8 +562,8 @@ err:\ #define M_ASN1_I2D_finish() *pp=p; \ return(r); -int asn1_GetSequence(ASN1_CTX *c, long *length); -void asn1_add_error(unsigned char *address,int offset); +int asn1_GetSequence(ASN1_const_CTX *c, long *length); +void asn1_add_error(const unsigned char *address,int offset); #ifdef __cplusplus } #endif diff --git a/src/lib/libcrypto/asn1/asn1_par.c b/src/lib/libcrypto/asn1/asn1_par.c index 676d434f03..501b62a4b1 100644 --- a/src/lib/libcrypto/asn1/asn1_par.c +++ b/src/lib/libcrypto/asn1/asn1_par.c @@ -64,7 +64,7 @@ static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed, int indent); -static int asn1_parse2(BIO *bp, unsigned char **pp, long length, +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump); static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, int indent) @@ -88,7 +88,10 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, BIO_snprintf(str,sizeof str,"cont [ %d ]",tag); else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) BIO_snprintf(str,sizeof str,"appl [ %d ]",tag); - else p = ASN1_tag2str(tag); + else if (tag > 30) + BIO_snprintf(str,sizeof str,"",tag); + else + p = ASN1_tag2str(tag); if (p2 != NULL) { @@ -103,20 +106,20 @@ err: return(0); } -int ASN1_parse(BIO *bp, unsigned char *pp, long len, int indent) +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent) { return(asn1_parse2(bp,&pp,len,0,0,indent,0)); } -int ASN1_parse_dump(BIO *bp, unsigned char *pp, long len, int indent, int dump) +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump) { return(asn1_parse2(bp,&pp,len,0,0,indent,dump)); } -static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump) { - unsigned char *p,*ep,*tot,*op,*opp; + const unsigned char *p,*ep,*tot,*op,*opp; long len; int tag,xclass,ret=0; int nl,hl,j,r; @@ -215,7 +218,7 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, { if (BIO_write(bp,":",1) <= 0) goto end; if ((len > 0) && - BIO_write(bp,(char *)p,(int)len) + BIO_write(bp,(const char *)p,(int)len) != (int)len) goto end; } @@ -256,9 +259,11 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, opp=op; os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl); - if (os != NULL) + if (os != NULL && os->length > 0) { - opp=os->data; + opp = os->data; + /* testing whether the octet string is + * printable */ for (i=0; ilength; i++) { if (( (opp[i] < ' ') && @@ -271,28 +276,47 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, break; } } - if (printable && (os->length > 0)) + if (printable) + /* printable string */ { if (BIO_write(bp,":",1) <= 0) goto end; - if (BIO_write(bp,(char *)opp, + if (BIO_write(bp,(const char *)opp, os->length) <= 0) goto end; } - if (!printable && (os->length > 0) - && dump) + else if (!dump) + /* not printable => print octet string + * as hex dump */ + { + if (BIO_write(bp,"[HEX DUMP]:",11) <= 0) + goto end; + for (i=0; ilength; i++) + { + if (BIO_printf(bp,"%02X" + , opp[i]) <= 0) + goto end; + } + } + else + /* print the normal dump */ { if (!nl) { if (BIO_write(bp,"\n",1) <= 0) goto end; } - if (BIO_dump_indent(bp,(char *)opp, - ((dump == -1 || dump > os->length)?os->length:dump), + if (BIO_dump_indent(bp, + (const char *)opp, + ((dump == -1 || dump > + os->length)?os->length:dump), dump_indent) <= 0) goto end; nl=1; } + } + if (os != NULL) + { M_ASN1_OCTET_STRING_free(os); os=NULL; } @@ -368,7 +392,7 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset, if (BIO_write(bp,"\n",1) <= 0) goto end; } - if (BIO_dump_indent(bp,(char *)p, + if (BIO_dump_indent(bp,(const char *)p, ((dump == -1 || dump > len)?len:dump), dump_indent) <= 0) goto end; @@ -398,7 +422,7 @@ end: const char *ASN1_tag2str(int tag) { - const static char *tag2str[] = { + static const char *tag2str[] = { "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ diff --git a/src/lib/libcrypto/asn1/asn1t.h b/src/lib/libcrypto/asn1/asn1t.h index ed372f8554..bf315e65ed 100644 --- a/src/lib/libcrypto/asn1/asn1t.h +++ b/src/lib/libcrypto/asn1/asn1t.h @@ -99,7 +99,7 @@ extern "C" { #define ASN1_ITEM_start(itname) \ const ASN1_ITEM * itname##_it(void) \ { \ - static const ASN1_ITEM local_it = { \ + static const ASN1_ITEM local_it = { #define ASN1_ITEM_end(itname) \ }; \ @@ -112,7 +112,7 @@ extern "C" { /* Macros to aid ASN1 template writing */ #define ASN1_ITEM_TEMPLATE(tname) \ - const static ASN1_TEMPLATE tname##_item_tt + static const ASN1_TEMPLATE tname##_item_tt #define ASN1_ITEM_TEMPLATE_END(tname) \ ;\ @@ -150,7 +150,7 @@ extern "C" { */ #define ASN1_SEQUENCE(tname) \ - const static ASN1_TEMPLATE tname##_seq_tt[] + static const ASN1_TEMPLATE tname##_seq_tt[] #define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) @@ -166,22 +166,40 @@ extern "C" { #stname \ ASN1_ITEM_end(tname) +#define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + #define ASN1_SEQUENCE_cb(tname, cb) \ - const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ ASN1_SEQUENCE(tname) #define ASN1_BROKEN_SEQUENCE(tname) \ - const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ ASN1_SEQUENCE(tname) #define ASN1_SEQUENCE_ref(tname, cb, lck) \ - const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ ASN1_SEQUENCE(tname) #define ASN1_SEQUENCE_enc(tname, enc, cb) \ - const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ ASN1_SEQUENCE(tname) +#define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + #define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) #define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) @@ -224,10 +242,10 @@ extern "C" { */ #define ASN1_CHOICE(tname) \ - const static ASN1_TEMPLATE tname##_ch_tt[] + static const ASN1_TEMPLATE tname##_ch_tt[] #define ASN1_CHOICE_cb(tname, cb) \ - const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ ASN1_CHOICE(tname) #define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) @@ -353,16 +371,24 @@ extern "C" { #define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) +/* EXPLICIT using indefinite length constructed form */ +#define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + /* Macros for the ASN1_ADB structure */ #define ASN1_ADB(name) \ - const static ASN1_ADB_TABLE name##_adbtbl[] + static const ASN1_ADB_TABLE name##_adbtbl[] #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION #define ASN1_ADB_END(name, flags, field, app_table, def, none) \ ;\ - const static ASN1_ADB name##_adb = {\ + static const ASN1_ADB name##_adb = {\ flags,\ offsetof(name, field),\ app_table,\ @@ -376,9 +402,9 @@ extern "C" { #define ASN1_ADB_END(name, flags, field, app_table, def, none) \ ;\ - const static ASN1_ITEM *name##_adb(void) \ + static const ASN1_ITEM *name##_adb(void) \ { \ - const static ASN1_ADB internal_adb = \ + static const ASN1_ADB internal_adb = \ {\ flags,\ offsetof(name, field),\ @@ -397,7 +423,7 @@ extern "C" { #define ADB_ENTRY(val, template) {val, template} #define ASN1_ADB_TEMPLATE(name) \ - const static ASN1_TEMPLATE name##_tt + static const ASN1_TEMPLATE name##_tt /* This is the ASN1 template structure that defines * a wrapper round the actual type. It determines the @@ -410,7 +436,7 @@ unsigned long flags; /* Various flags */ long tag; /* tag, not used if no tagging */ unsigned long offset; /* Offset of this field in structure */ #ifndef NO_ASN1_FIELD_NAMES -char *field_name; /* Field name */ +const char *field_name; /* Field name */ #endif ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ }; @@ -518,6 +544,13 @@ struct ASN1_ADB_TABLE_st { #define ASN1_TFLG_COMBINE (0x1<<10) +/* This flag when present in a SEQUENCE OF, SET OF + * or EXPLICIT causes indefinite length constructed + * encoding to be used if required. + */ + +#define ASN1_TFLG_NDEF (0x1<<11) + /* This is the actual ASN1 item itself */ struct ASN1_ITEM_st { @@ -570,19 +603,25 @@ const char *sname; /* Structure name */ * has a special meaning, it is used as a mask * of acceptable types using the B_ASN1 constants. * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * */ -#define ASN1_ITYPE_PRIMITIVE 0x0 +#define ASN1_ITYPE_PRIMITIVE 0x0 + +#define ASN1_ITYPE_SEQUENCE 0x1 -#define ASN1_ITYPE_SEQUENCE 0x1 +#define ASN1_ITYPE_CHOICE 0x2 -#define ASN1_ITYPE_CHOICE 0x2 +#define ASN1_ITYPE_COMPAT 0x3 -#define ASN1_ITYPE_COMPAT 0x3 +#define ASN1_ITYPE_EXTERN 0x4 -#define ASN1_ITYPE_EXTERN 0x4 +#define ASN1_ITYPE_MSTRING 0x5 -#define ASN1_ITYPE_MSTRING 0x5 +#define ASN1_ITYPE_NDEF_SEQUENCE 0x6 /* Cache for ASN1 tag and length, so we * don't keep re-reading it for things @@ -602,10 +641,10 @@ struct ASN1_TLC_st{ typedef ASN1_VALUE * ASN1_new_func(void); typedef void ASN1_free_func(ASN1_VALUE *a); -typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, unsigned char ** in, long length); +typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length); typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); -typedef int ASN1_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); @@ -613,7 +652,7 @@ typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); -typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); typedef struct ASN1_COMPAT_FUNCS_st { ASN1_new_func *asn1_new; @@ -743,6 +782,9 @@ typedef struct ASN1_AUX_st { #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ stname *fname##_new(void) \ { \ @@ -758,7 +800,7 @@ typedef struct ASN1_AUX_st { IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ - stname *d2i_##fname(stname **a, unsigned char **in, long len) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ { \ return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ } \ @@ -767,13 +809,19 @@ typedef struct ASN1_AUX_st { return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ } +#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + /* This includes evil casts to remove const: they will go away when full * ASN1 constification is done. */ #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ { \ - return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, (unsigned char **)in, len, ASN1_ITEM_rptr(itname));\ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ } \ int i2d_##fname(const stname *a, unsigned char **out) \ { \ @@ -798,7 +846,6 @@ typedef struct ASN1_AUX_st { DECLARE_ASN1_ITEM(ASN1_BOOLEAN) DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) -DECLARE_ASN1_ITEM(ASN1_ANY) DECLARE_ASN1_ITEM(ASN1_SEQUENCE) DECLARE_ASN1_ITEM(CBIGNUM) DECLARE_ASN1_ITEM(BIGNUM) @@ -815,8 +862,8 @@ int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt); -int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); @@ -824,7 +871,7 @@ int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLAT void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); -int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); @@ -838,7 +885,7 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it); +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it); #ifdef __cplusplus } diff --git a/src/lib/libcrypto/asn1/asn_moid.c b/src/lib/libcrypto/asn1/asn_moid.c index edb44c988f..9132350f10 100644 --- a/src/lib/libcrypto/asn1/asn_moid.c +++ b/src/lib/libcrypto/asn1/asn_moid.c @@ -3,7 +3,7 @@ * project 2001. */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,6 +57,7 @@ */ #include +#include #include #include "cryptlib.h" #include @@ -65,6 +66,8 @@ /* Simple ASN1 OID module: add all objects in a given section */ +static int do_create(char *value, char *name); + static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) { int i; @@ -80,7 +83,7 @@ static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { oval = sk_CONF_VALUE_value(sktmp, i); - if(OBJ_create(oval->value, oval->name, oval->name) == NID_undef) + if(!do_create(oval->value, oval->name)) { ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); return 0; @@ -98,3 +101,60 @@ void ASN1_add_oid_module(void) { CONF_module_add("oid_section", oid_module_init, oid_module_finish); } + +/* Create an OID based on a name value pair. Accept two formats. + * shortname = 1.2.3.4 + * shortname = some long name, 1.2.3.4 + */ + + +static int do_create(char *value, char *name) + { + int nid; + ASN1_OBJECT *oid; + char *ln, *ostr, *p, *lntmp; + p = strrchr(value, ','); + if (!p) + { + ln = name; + ostr = value; + } + else + { + ln = NULL; + ostr = p + 1; + if (!*ostr) + return 0; + while(isspace((unsigned char)*ostr)) ostr++; + } + + nid = OBJ_create(ostr, name, ln); + + if (nid == NID_undef) + return 0; + + if (p) + { + ln = value; + while(isspace((unsigned char)*ln)) ln++; + p--; + while(isspace((unsigned char)*p)) + { + if (p == ln) + return 0; + p--; + } + p++; + lntmp = OPENSSL_malloc((p - ln) + 1); + if (lntmp == NULL) + return 0; + memcpy(lntmp, ln, p - ln); + lntmp[p - ln] = 0; + oid = OBJ_nid2obj(nid); + oid->ln = lntmp; + } + + return 1; + } + + diff --git a/src/lib/libcrypto/asn1/asn_pack.c b/src/lib/libcrypto/asn1/asn_pack.c index e6051db2dc..e8b671b7b5 100644 --- a/src/lib/libcrypto/asn1/asn_pack.c +++ b/src/lib/libcrypto/asn1/asn_pack.c @@ -66,11 +66,11 @@ /* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ -STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(), - void (*free_func)(void *)) +STACK *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i,void (*free_func)(void *)) { STACK *sk; - unsigned char *pbuf; + const unsigned char *pbuf; pbuf = buf; if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL))) @@ -82,8 +82,8 @@ STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(), * OPENSSL_malloc'ed buffer */ -unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, - int *len) +unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d, + unsigned char **buf, int *len) { int safelen; unsigned char *safe, *p; @@ -106,9 +106,9 @@ unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, /* Extract an ASN1 object from an ASN1_STRING */ -void *ASN1_unpack_string (ASN1_STRING *oct, char *(*d2i)()) +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i) { - unsigned char *p; + const unsigned char *p; char *ret; p = oct->data; @@ -119,7 +119,7 @@ void *ASN1_unpack_string (ASN1_STRING *oct, char *(*d2i)()) /* Pack an ASN1 object into an ASN1_STRING */ -ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_STRING **oct) +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct) { unsigned char *p; ASN1_STRING *octmp; @@ -155,7 +155,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) if (!oct || !*oct) { if (!(octmp = ASN1_STRING_new ())) { - ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE); return NULL; } if (oct) *oct = octmp; @@ -167,11 +167,11 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) } if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) { - ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR); + ASN1err(ASN1_F_ASN1_ITEM_PACK,ASN1_R_ENCODE_ERROR); return NULL; } if (!octmp->data) { - ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE); return NULL; } return octmp; @@ -181,11 +181,11 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it) { - unsigned char *p; + const unsigned char *p; void *ret; p = oct->data; if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it))) - ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR); + ASN1err(ASN1_F_ASN1_ITEM_UNPACK,ASN1_R_DECODE_ERROR); return ret; } diff --git a/src/lib/libcrypto/asn1/d2i_pr.c b/src/lib/libcrypto/asn1/d2i_pr.c index 2e7d96af90..207ccda5ac 100644 --- a/src/lib/libcrypto/asn1/d2i_pr.c +++ b/src/lib/libcrypto/asn1/d2i_pr.c @@ -68,8 +68,11 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif -EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, unsigned char **pp, +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; @@ -107,6 +110,16 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, unsigned char **pp, goto err; } break; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + if ((ret->pkey.ec = d2i_ECPrivateKey(NULL, + (const unsigned char **)pp, length)) == NULL) + { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + break; #endif default: ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); @@ -122,11 +135,11 @@ err: /* This works like d2i_PrivateKey() except it automatically works out the type */ -EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp, +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length) { STACK_OF(ASN1_TYPE) *inkey; - unsigned char *p; + const unsigned char *p; int keytype; p = *pp; /* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): @@ -138,7 +151,10 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp, /* Since we only need to discern "traditional format" RSA and DSA * keys we can just count the elements. */ - if(sk_ASN1_TYPE_num(inkey) == 6) keytype = EVP_PKEY_DSA; + if(sk_ASN1_TYPE_num(inkey) == 6) + keytype = EVP_PKEY_DSA; + else if (sk_ASN1_TYPE_num(inkey) == 4) + keytype = EVP_PKEY_EC; else keytype = EVP_PKEY_RSA; sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); return d2i_PrivateKey(keytype, a, pp, length); diff --git a/src/lib/libcrypto/asn1/d2i_pu.c b/src/lib/libcrypto/asn1/d2i_pu.c index 71f2eb361b..3694f51a8c 100644 --- a/src/lib/libcrypto/asn1/d2i_pu.c +++ b/src/lib/libcrypto/asn1/d2i_pu.c @@ -68,8 +68,11 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif -EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, unsigned char **pp, +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; @@ -100,13 +103,23 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, unsigned char **pp, #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: - if ((ret->pkey.dsa=d2i_DSAPublicKey(NULL, - (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */ + if (!d2i_DSAPublicKey(&(ret->pkey.dsa), + (const unsigned char **)pp,length)) /* TMP UGLY CAST */ { ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB); goto err; } break; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + if (!o2i_ECPublicKey(&(ret->pkey.ec), + (const unsigned char **)pp, length)) + { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; #endif default: ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); diff --git a/src/lib/libcrypto/asn1/evp_asn1.c b/src/lib/libcrypto/asn1/evp_asn1.c index f92ce6cb5d..f3d9804860 100644 --- a/src/lib/libcrypto/asn1/evp_asn1.c +++ b/src/lib/libcrypto/asn1/evp_asn1.c @@ -141,9 +141,9 @@ int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data, int ret= -1,n; ASN1_INTEGER *ai=NULL; ASN1_OCTET_STRING *os=NULL; - unsigned char *p; + const unsigned char *p; long length; - ASN1_CTX c; + ASN1_const_CTX c; if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { diff --git a/src/lib/libcrypto/asn1/i2d_pr.c b/src/lib/libcrypto/asn1/i2d_pr.c index 1e951ae01d..0be52c5b76 100644 --- a/src/lib/libcrypto/asn1/i2d_pr.c +++ b/src/lib/libcrypto/asn1/i2d_pr.c @@ -67,6 +67,9 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) { @@ -83,6 +86,12 @@ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) return(i2d_DSAPrivateKey(a->pkey.dsa,pp)); } #endif +#ifndef OPENSSL_NO_EC + if (a->type == EVP_PKEY_EC) + { + return(i2d_ECPrivateKey(a->pkey.ec, pp)); + } +#endif ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return(-1); diff --git a/src/lib/libcrypto/asn1/i2d_pu.c b/src/lib/libcrypto/asn1/i2d_pu.c index 013d19bbf4..34286dbd35 100644 --- a/src/lib/libcrypto/asn1/i2d_pu.c +++ b/src/lib/libcrypto/asn1/i2d_pu.c @@ -67,6 +67,9 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) { @@ -79,6 +82,10 @@ int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: return(i2d_DSAPublicKey(a->pkey.dsa,pp)); +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + return(i2o_ECPublicKey(a->pkey.ec, pp)); #endif default: ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); diff --git a/src/lib/libcrypto/asn1/n_pkey.c b/src/lib/libcrypto/asn1/n_pkey.c index 766b51c538..60bc437938 100644 --- a/src/lib/libcrypto/asn1/n_pkey.c +++ b/src/lib/libcrypto/asn1/n_pkey.c @@ -56,9 +56,9 @@ * [including the GNU Public Licence.] */ -#ifndef OPENSSL_NO_RSA #include #include "cryptlib.h" +#ifndef OPENSSL_NO_RSA #include #include #include @@ -107,14 +107,20 @@ DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY) IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, - int (*cb)(), int sgckey); + int (*cb)(char *buf, int len, const char *prompt, + int verify), + int sgckey); -int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, int (*cb)()) +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb)(char *buf, int len, const char *prompt, + int verify)) { return i2d_RSA_NET(a, pp, cb, 0); } -int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey) +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb)(char *buf, int len, const char *prompt, int verify), + int sgckey) { int i, j, ret = 0; int rsalen, pkeylen, olen; @@ -164,7 +170,7 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey) /* Since its RC4 encrypted length is actual length */ if ((zz=(unsigned char *)OPENSSL_malloc(rsalen)) == NULL) { - ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE); goto err; } @@ -174,13 +180,13 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey) if ((zz=OPENSSL_malloc(pkeylen)) == NULL) { - ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_STRING_set(enckey->os, "private-key", -1)) { - ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE); goto err; } enckey->enckey->digest->data = zz; @@ -191,10 +197,10 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey) if (cb == NULL) cb=EVP_read_pw_string; - i=cb(buf,256,"Enter Private Key password:",1); + i=cb((char *)buf,256,"Enter Private Key password:",1); if (i != 0) { - ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ASN1_R_BAD_PASSWORD_READ); + ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ); goto err; } i = strlen((char *)buf); @@ -224,12 +230,16 @@ err: } -RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)()) +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb)(char *buf, int len, const char *prompt, + int verify)) { return d2i_RSA_NET(a, pp, length, cb, 0); } -RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, int (*cb)(), int sgckey) +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb)(char *buf, int len, const char *prompt, int verify), + int sgckey) { RSA *ret=NULL; const unsigned char *p, *kp; @@ -239,20 +249,20 @@ RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, int (*cb)(), in enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length); if(!enckey) { - ASN1err(ASN1_F_D2I_NETSCAPE_RSA,ASN1_R_DECODING_ERROR); + ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR); return NULL; } if ((enckey->os->length != 11) || (strncmp("private-key", (char *)enckey->os->data,11) != 0)) { - ASN1err(ASN1_F_D2I_NETSCAPE_RSA,ASN1_R_PRIVATE_KEY_HEADER_MISSING); + ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING); NETSCAPE_ENCRYPTED_PKEY_free(enckey); return NULL; } if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) { - ASN1err(ASN1_F_D2I_NETSCAPE_RSA_2,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM); + ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM); goto err; } kp = enckey->enckey->digest->data; @@ -269,7 +279,8 @@ RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, int (*cb)(), in } static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, - int (*cb)(), int sgckey) + int (*cb)(char *buf, int len, const char *prompt, + int verify), int sgckey) { NETSCAPE_PKEY *pkey=NULL; RSA *ret=NULL; @@ -279,10 +290,10 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, unsigned char key[EVP_MAX_KEY_LENGTH]; EVP_CIPHER_CTX ctx; - i=cb(buf,256,"Enter Private Key password:",0); + i=cb((char *)buf,256,"Enter Private Key password:",0); if (i != 0) { - ASN1err(ASN1_F_D2I_NETSCAPE_RSA_2,ASN1_R_BAD_PASSWORD_READ); + ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ); goto err; } @@ -307,14 +318,14 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL) { - ASN1err(ASN1_F_D2I_NETSCAPE_RSA_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY); + ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY); goto err; } zz=pkey->private_key->data; if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL) { - ASN1err(ASN1_F_D2I_NETSCAPE_RSA_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY); + ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY); goto err; } err: diff --git a/src/lib/libcrypto/asn1/p5_pbe.c b/src/lib/libcrypto/asn1/p5_pbe.c index ec788267e0..da91170094 100644 --- a/src/lib/libcrypto/asn1/p5_pbe.c +++ b/src/lib/libcrypto/asn1/p5_pbe.c @@ -82,17 +82,17 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, ASN1_TYPE *astype=NULL; if (!(pbe = PBEPARAM_new ())) { - ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } if(iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(pbe->iter, iter)) { - ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!(pbe->salt->data = OPENSSL_malloc (saltlen))) { - ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } pbe->salt->length = saltlen; @@ -101,13 +101,14 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, goto err; if (!(astype = ASN1_TYPE_new())) { - ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } astype->type = V_ASN1_SEQUENCE; - if(!ASN1_pack_string(pbe, i2d_PBEPARAM, &astype->value.sequence)) { - ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + if(!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM, + &astype->value.sequence)) { + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free (pbe); @@ -115,7 +116,7 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, al = OBJ_nid2obj(alg); /* never need to free al */ if (!(algor = X509_ALGOR_new())) { - ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); goto err; } ASN1_OBJECT_free(algor->algorithm); diff --git a/src/lib/libcrypto/asn1/p5_pbev2.c b/src/lib/libcrypto/asn1/p5_pbev2.c index e0dc0ec4ee..c834a38ddf 100644 --- a/src/lib/libcrypto/asn1/p5_pbev2.c +++ b/src/lib/libcrypto/asn1/p5_pbev2.c @@ -115,7 +115,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, /* Create random IV */ if (EVP_CIPHER_iv_length(cipher) && RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) - goto err; + goto err; EVP_CIPHER_CTX_init(&ctx); @@ -164,7 +164,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; - if(!ASN1_pack_string(kdf, i2d_PBKDF2PARAM, + if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM, &pbe2->keyfunc->parameter->value.sequence)) goto merr; pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; @@ -180,7 +180,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, /* Encode PBE2PARAM into parameter */ - if(!ASN1_pack_string(pbe2, i2d_PBE2PARAM, + if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM, &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; diff --git a/src/lib/libcrypto/asn1/t_crl.c b/src/lib/libcrypto/asn1/t_crl.c index 757c148df8..929b3e5904 100644 --- a/src/lib/libcrypto/asn1/t_crl.c +++ b/src/lib/libcrypto/asn1/t_crl.c @@ -72,7 +72,7 @@ int X509_CRL_print_fp(FILE *fp, X509_CRL *x) if ((b=BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_PRINT_FP,ERR_R_BUF_LIB); + X509err(X509_F_X509_CRL_PRINT_FP,ERR_R_BUF_LIB); return(0); } BIO_set_fp(b,fp,BIO_NOCLOSE); @@ -121,7 +121,7 @@ int X509_CRL_print(BIO *out, X509_CRL *x) r = sk_X509_REVOKED_value(rev, i); BIO_printf(out," Serial Number: "); i2a_ASN1_INTEGER(out,r->serialNumber); - BIO_printf(out,"\n Revocation Date: ",""); + BIO_printf(out,"\n Revocation Date: "); ASN1_TIME_print(out,r->revocationDate); BIO_printf(out,"\n"); X509V3_extensions_print(out, "CRL entry extensions", diff --git a/src/lib/libcrypto/asn1/t_pkey.c b/src/lib/libcrypto/asn1/t_pkey.c index d15006e654..afb95d6712 100644 --- a/src/lib/libcrypto/asn1/t_pkey.c +++ b/src/lib/libcrypto/asn1/t_pkey.c @@ -55,9 +55,15 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ #include #include "cryptlib.h" +#include #include #include #ifndef OPENSSL_NO_RSA @@ -69,26 +75,33 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif -static int print(BIO *fp,const char *str,BIGNUM *num, +static int print(BIO *fp,const char *str, const BIGNUM *num, unsigned char *buf,int off); +#ifndef OPENSSL_NO_EC +static int print_bin(BIO *fp, const char *str, const unsigned char *num, + size_t len, int off); +#endif #ifndef OPENSSL_NO_RSA #ifndef OPENSSL_NO_FP_API int RSA_print_fp(FILE *fp, const RSA *x, int off) - { - BIO *b; - int ret; + { + BIO *b; + int ret; - if ((b=BIO_new(BIO_s_file())) == NULL) + if ((b=BIO_new(BIO_s_file())) == NULL) { RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB); - return(0); + return(0); } - BIO_set_fp(b,fp,BIO_NOCLOSE); - ret=RSA_print(b,x,off); - BIO_free(b); - return(ret); - } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=RSA_print(b,x,off); + BIO_free(b); + return(ret); + } #endif int RSA_print(BIO *bp, const RSA *x, int off) @@ -96,7 +109,7 @@ int RSA_print(BIO *bp, const RSA *x, int off) char str[128]; const char *s; unsigned char *m=NULL; - int ret=0; + int ret=0, mod_len = 0; size_t buf_len=0, i; if (x->n) @@ -130,27 +143,37 @@ int RSA_print(BIO *bp, const RSA *x, int off) goto err; } + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + if (x->d != NULL) { if(!BIO_indent(bp,off,128)) goto err; - if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->n)) + if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len) <= 0) goto err; } if (x->d == NULL) - BIO_snprintf(str,sizeof str,"Modulus (%d bit):",BN_num_bits(x->n)); + BIO_snprintf(str,sizeof str,"Modulus (%d bit):", mod_len); else BUF_strlcpy(str,"modulus:",sizeof str); if (!print(bp,str,x->n,m,off)) goto err; s=(x->d == NULL)?"Exponent:":"publicExponent:"; - if (!print(bp,s,x->e,m,off)) goto err; - if (!print(bp,"privateExponent:",x->d,m,off)) goto err; - if (!print(bp,"prime1:",x->p,m,off)) goto err; - if (!print(bp,"prime2:",x->q,m,off)) goto err; - if (!print(bp,"exponent1:",x->dmp1,m,off)) goto err; - if (!print(bp,"exponent2:",x->dmq1,m,off)) goto err; - if (!print(bp,"coefficient:",x->iqmp,m,off)) goto err; + if ((x->e != NULL) && !print(bp,s,x->e,m,off)) + goto err; + if ((x->d != NULL) && !print(bp,"privateExponent:",x->d,m,off)) + goto err; + if ((x->p != NULL) && !print(bp,"prime1:",x->p,m,off)) + goto err; + if ((x->q != NULL) && !print(bp,"prime2:",x->q,m,off)) + goto err; + if ((x->dmp1 != NULL) && !print(bp,"exponent1:",x->dmp1,m,off)) + goto err; + if ((x->dmq1 != NULL) && !print(bp,"exponent2:",x->dmq1,m,off)) + goto err; + if ((x->iqmp != NULL) && !print(bp,"coefficient:",x->iqmp,m,off)) + goto err; ret=1; err: if (m != NULL) OPENSSL_free(m); @@ -185,6 +208,11 @@ int DSA_print(BIO *bp, const DSA *x, int off) if (x->p) buf_len = (size_t)BN_num_bytes(x->p); + else + { + DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS); + goto err; + } if (x->q) if (buf_len < (i = (size_t)BN_num_bytes(x->q))) buf_len = i; @@ -227,16 +255,334 @@ err: } #endif /* !OPENSSL_NO_DSA */ -static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf, +#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECPKParameters_print(b, x, off); + BIO_free(b); + return(ret); + } + +int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); + return(0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = EC_KEY_print(b, x, off); + BIO_free(b); + return(ret); + } +#endif + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) + { + unsigned char *buffer=NULL; + size_t buf_len=0, i; + int ret=0, reason=ERR_R_BIO_LIB; + BN_CTX *ctx=NULL; + const EC_POINT *point=NULL; + BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL, + *order=NULL, *cofactor=NULL; + const unsigned char *seed; + size_t seed_len=0; + + static const char *gen_compressed = "Generator (compressed):"; + static const char *gen_uncompressed = "Generator (uncompressed):"; + static const char *gen_hybrid = "Generator (hybrid):"; + + if (!x) + { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + if (EC_GROUP_get_asn1_flag(x)) + { + /* the curve parameter are given by an asn1 OID */ + int nid; + + if (!BIO_indent(bp, off, 128)) + goto err; + + nid = EC_GROUP_get_curve_name(x); + if (nid == 0) + goto err; + + if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) + goto err; + if (BIO_printf(bp, "\n") <= 0) + goto err; + } + else + { + /* explicit parameters */ + int is_char_two = 0; + point_conversion_form_t form; + int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); + + if (tmp_nid == NID_X9_62_characteristic_two_field) + is_char_two = 1; + + if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || + (b = BN_new()) == NULL || (order = BN_new()) == NULL || + (cofactor = BN_new()) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (is_char_two) + { + if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) + { + reason = ERR_R_EC_LIB; + goto err; + } + } + else /* prime field */ + { + if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) + { + reason = ERR_R_EC_LIB; + goto err; + } + } + + if ((point = EC_GROUP_get0_generator(x)) == NULL) + { + reason = ERR_R_EC_LIB; + goto err; + } + if (!EC_GROUP_get_order(x, order, NULL) || + !EC_GROUP_get_cofactor(x, cofactor, NULL)) + { + reason = ERR_R_EC_LIB; + goto err; + } + + form = EC_GROUP_get_point_conversion_form(x); + + if ((gen = EC_POINT_point2bn(x, point, + form, NULL, ctx)) == NULL) + { + reason = ERR_R_EC_LIB; + goto err; + } + + buf_len = (size_t)BN_num_bytes(p); + if (buf_len < (i = (size_t)BN_num_bytes(a))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(b))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(gen))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(order))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) + buf_len = i; + + if ((seed = EC_GROUP_get0_seed(x)) != NULL) + seed_len = EC_GROUP_get_seed_len(x); + + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (!BIO_indent(bp, off, 128)) + goto err; + + /* print the 'short name' of the field type */ + if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) + <= 0) + goto err; + + if (is_char_two) + { + /* print the 'short name' of the base type OID */ + int basis_type = EC_GROUP_get_basis_type(x); + if (basis_type == 0) + goto err; + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (BIO_printf(bp, "Basis Type: %s\n", + OBJ_nid2sn(basis_type)) <= 0) + goto err; + + /* print the polynomial */ + if ((p != NULL) && !print(bp, "Polynomial:", p, buffer, + off)) + goto err; + } + else + { + if ((p != NULL) && !print(bp, "Prime:", p, buffer,off)) + goto err; + } + if ((a != NULL) && !print(bp, "A: ", a, buffer, off)) + goto err; + if ((b != NULL) && !print(bp, "B: ", b, buffer, off)) + goto err; + if (form == POINT_CONVERSION_COMPRESSED) + { + if ((gen != NULL) && !print(bp, gen_compressed, gen, + buffer, off)) + goto err; + } + else if (form == POINT_CONVERSION_UNCOMPRESSED) + { + if ((gen != NULL) && !print(bp, gen_uncompressed, gen, + buffer, off)) + goto err; + } + else /* form == POINT_CONVERSION_HYBRID */ + { + if ((gen != NULL) && !print(bp, gen_hybrid, gen, + buffer, off)) + goto err; + } + if ((order != NULL) && !print(bp, "Order: ", order, + buffer, off)) goto err; + if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor, + buffer, off)) goto err; + if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) + goto err; + } + ret=1; +err: + if (!ret) + ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (gen) + BN_free(gen); + if (order) + BN_free(order); + if (cofactor) + BN_free(cofactor); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return(ret); + } + +int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) + { + unsigned char *buffer=NULL; + size_t buf_len=0, i; + int ret=0, reason=ERR_R_BIO_LIB; + BIGNUM *pub_key=NULL, *order=NULL; + BN_CTX *ctx=NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) + { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + public_key = EC_KEY_get0_public_key(x); + if ((pub_key = EC_POINT_point2bn(group, public_key, + EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) + { + reason = ERR_R_EC_LIB; + goto err; + } + + buf_len = (size_t)BN_num_bytes(pub_key); + priv_key = EC_KEY_get0_private_key(x); + if (priv_key != NULL) + { + if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len) + buf_len = i; + } + + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (priv_key != NULL) + { + if (!BIO_indent(bp, off, 128)) + goto err; + if ((order = BN_new()) == NULL) + goto err; + if (!EC_GROUP_get_order(group, order, NULL)) + goto err; + if (BIO_printf(bp, "Private-Key: (%d bit)\n", + BN_num_bits(order)) <= 0) goto err; + } + + if ((priv_key != NULL) && !print(bp, "priv:", priv_key, + buffer, off)) + goto err; + if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, + buffer, off)) + goto err; + if (!ECPKParameters_print(bp, group, off)) + goto err; + ret=1; +err: + if (!ret) + ECerr(EC_F_EC_KEY_PRINT, reason); + if (pub_key) + BN_free(pub_key); + if (order) + BN_free(order); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return(ret); + } +#endif /* OPENSSL_NO_EC */ + +static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf, int off) { int n,i; const char *neg; if (num == NULL) return(1); - neg=(num->neg)?"-":""; + neg = (BN_is_negative(num))?"-":""; if(!BIO_indent(bp,off,128)) return 0; + if (BN_is_zero(num)) + { + if (BIO_printf(bp, "%s 0\n", number) <= 0) + return 0; + return 1; + } if (BN_num_bytes(num) <= BN_BYTES) { @@ -272,23 +618,63 @@ static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf, return(1); } +#ifndef OPENSSL_NO_EC +static int print_bin(BIO *fp, const char *name, const unsigned char *buf, + size_t len, int off) + { + size_t i; + char str[128]; + + if (buf == NULL) + return 1; + if (off) + { + if (off > 128) + off=128; + memset(str,' ',off); + if (BIO_write(fp, str, off) <= 0) + return 0; + } + + if (BIO_printf(fp,"%s", name) <= 0) + return 0; + + for (i=0; ip) buf_len = (size_t)BN_num_bytes(x->p); + else + { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } if (x->g) if (buf_len < (i = (size_t)BN_num_bytes(x->g))) buf_len = i; @@ -333,30 +724,35 @@ err: #ifndef OPENSSL_NO_DSA #ifndef OPENSSL_NO_FP_API int DSAparams_print_fp(FILE *fp, const DSA *x) - { - BIO *b; - int ret; + { + BIO *b; + int ret; - if ((b=BIO_new(BIO_s_file())) == NULL) + if ((b=BIO_new(BIO_s_file())) == NULL) { DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB); - return(0); + return(0); } - BIO_set_fp(b,fp,BIO_NOCLOSE); - ret=DSAparams_print(b, x); - BIO_free(b); - return(ret); - } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=DSAparams_print(b, x); + BIO_free(b); + return(ret); + } #endif int DSAparams_print(BIO *bp, const DSA *x) { unsigned char *m=NULL; - int reason=ERR_R_BUF_LIB,ret=0; + int ret=0; size_t buf_len=0,i; if (x->p) buf_len = (size_t)BN_num_bytes(x->p); + else + { + DSAerr(DSA_F_DSAPARAMS_PRINT,DSA_R_MISSING_PARAMETERS); + goto err; + } if (x->q) if (buf_len < (i = (size_t)BN_num_bytes(x->q))) buf_len = i; @@ -366,7 +762,7 @@ int DSAparams_print(BIO *bp, const DSA *x) m=(unsigned char *)OPENSSL_malloc(buf_len+10); if (m == NULL) { - reason=ERR_R_MALLOC_FAILURE; + DSAerr(DSA_F_DSAPARAMS_PRINT,ERR_R_MALLOC_FAILURE); goto err; } @@ -374,14 +770,70 @@ int DSAparams_print(BIO *bp, const DSA *x) BN_num_bits(x->p)) <= 0) goto err; if (!print(bp,"p:",x->p,m,4)) goto err; - if (!print(bp,"q:",x->q,m,4)) goto err; - if (!print(bp,"g:",x->g,m,4)) goto err; + if ((x->q != NULL) && !print(bp,"q:",x->q,m,4)) goto err; + if ((x->g != NULL) && !print(bp,"g:",x->g,m,4)) goto err; ret=1; err: if (m != NULL) OPENSSL_free(m); - DSAerr(DSA_F_DSAPARAMS_PRINT,reason); return(ret); } #endif /* !OPENSSL_NO_DSA */ +#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_FP_API +int ECParameters_print_fp(FILE *fp, const EC_KEY *x) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); + return(0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECParameters_print(b, x); + BIO_free(b); + return(ret); + } +#endif + +int ECParameters_print(BIO *bp, const EC_KEY *x) + { + int reason=ERR_R_EC_LIB, ret=0; + BIGNUM *order=NULL; + const EC_GROUP *group; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) + { + reason = ERR_R_PASSED_NULL_PARAMETER;; + goto err; + } + + if ((order = BN_new()) == NULL) + { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (!EC_GROUP_get_order(group, order, NULL)) + { + reason = ERR_R_EC_LIB; + goto err; + } + + if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n", + BN_num_bits(order)) <= 0) + goto err; + if (!ECPKParameters_print(bp, group, 4)) + goto err; + ret=1; +err: + if (order) + BN_free(order); + ECerr(EC_F_ECPARAMETERS_PRINT, reason); + return(ret); + } + +#endif diff --git a/src/lib/libcrypto/asn1/t_req.c b/src/lib/libcrypto/asn1/t_req.c index 740cee80c0..5557e06584 100644 --- a/src/lib/libcrypto/asn1/t_req.c +++ b/src/lib/libcrypto/asn1/t_req.c @@ -63,6 +63,12 @@ #include #include #include +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif #ifndef OPENSSL_NO_FP_API int X509_REQ_print_fp(FILE *fp, X509_REQ *x) @@ -159,6 +165,14 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long DSA_print(bp,pkey->pkey.dsa,16); } else +#endif +#ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) + { + BIO_printf(bp, "%12sEC Public Key: \n",""); + EC_KEY_print(bp, pkey->pkey.ec, 16); + } + else #endif BIO_printf(bp,"%12sUnknown Public Key:\n",""); @@ -230,7 +244,7 @@ get_next: } } } - if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) + if(!(cflag & X509_FLAG_NO_EXTENSIONS)) { exts = X509_REQ_get_extensions(x); if(exts) @@ -246,9 +260,9 @@ get_next: obj=X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bp,obj); j=X509_EXTENSION_get_critical(ex); - if (BIO_printf(bp,": %s\n",j?"critical":"","") <= 0) + if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0) goto err; - if(!X509V3_EXT_print(bp, ex, 0, 16)) + if(!X509V3_EXT_print(bp, ex, cflag, 16)) { BIO_printf(bp, "%16s", ""); M_ASN1_OCTET_STRING_print(bp,ex->value); @@ -266,7 +280,7 @@ get_next: return(1); err: - X509err(X509_F_X509_REQ_PRINT,ERR_R_BUF_LIB); + X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB); return(0); } diff --git a/src/lib/libcrypto/asn1/t_spki.c b/src/lib/libcrypto/asn1/t_spki.c index 5abfbc815e..c2a5797dd8 100644 --- a/src/lib/libcrypto/asn1/t_spki.c +++ b/src/lib/libcrypto/asn1/t_spki.c @@ -60,6 +60,13 @@ #include "cryptlib.h" #include #include +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#include /* Print out an SPKI */ @@ -93,6 +100,15 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) } else #endif +#ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) + { + BIO_printf(out, " EC Public Key:\n"); + EC_KEY_print(out, pkey->pkey.ec,2); + } + else +#endif + BIO_printf(out," Unknown Public Key:\n"); EVP_PKEY_free(pkey); } diff --git a/src/lib/libcrypto/asn1/t_x509.c b/src/lib/libcrypto/asn1/t_x509.c index 30f68561b7..26d3361722 100644 --- a/src/lib/libcrypto/asn1/t_x509.c +++ b/src/lib/libcrypto/asn1/t_x509.c @@ -66,6 +66,9 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif #include #include #include @@ -83,7 +86,7 @@ int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cfla if ((b=BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_PRINT_FP,ERR_R_BUF_LIB); + X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB); return(0); } BIO_set_fp(b,fp,BIO_NOCLOSE); @@ -228,6 +231,14 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) DSA_print(bp,pkey->pkey.dsa,16); } else +#endif +#ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) + { + BIO_printf(bp, "%12sEC Public Key:\n",""); + EC_KEY_print(bp, pkey->pkey.ec, 16); + } + else #endif BIO_printf(bp,"%12sUnknown Public Key:\n",""); @@ -434,19 +445,18 @@ err: int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) { char *s,*c,*b; - int ret=0,l,ll,i,first=1; + int ret=0,l,i; - ll=80-2-obase; + l=80-2-obase; - b=s=X509_NAME_oneline(name,NULL,0); - if (!*s) + b=X509_NAME_oneline(name,NULL,0); + if (!*b) { OPENSSL_free(b); return 1; } - s++; /* skip the first slash */ + s=b+1; /* skip the first slash */ - l=ll; c=s; for (;;) { @@ -468,20 +478,9 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) (*s == '\0')) #endif { - if ((l <= 0) && !first) - { - first=0; - if (BIO_write(bp,"\n",1) != 1) goto err; - for (i=0; i #include -static int asn1_check_eoc(unsigned char **in, long len); -static int asn1_find_end(unsigned char **in, long len, char inf); -static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); -static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); -static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, - unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx); -static int asn1_template_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); -static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); +static int asn1_check_eoc(const unsigned char **in, long len); +static int asn1_find_end(const unsigned char **in, long len, char inf); + +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, + char inf, int tag, int aclass); + +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *inf, char *cst, + const unsigned char **in, long len, + int exptag, int expclass, char opt, + ASN1_TLC *ctx); + +static int asn1_template_ex_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx); +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx); +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); /* Table to convert tags to bit values, used for MSTRING type */ -static unsigned long tag2bit[32]={ +static const unsigned long tag2bit[32] = { 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ -0, 0, B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ +B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ @@ -90,14 +106,14 @@ B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 2 }; unsigned long ASN1_tag2bit(int tag) -{ - if((tag < 0) || (tag > 30)) return 0; + { + if ((tag < 0) || (tag > 30)) return 0; return tag2bit[tag]; -} + } /* Macro to initialize and invalidate the cache */ -#define asn1_tlc_clear(c) if(c) (c)->valid = 0 +#define asn1_tlc_clear(c) if (c) (c)->valid = 0 /* Decode an ASN1 item, this currently behaves just * like a standard 'd2i' function. 'in' points to @@ -107,113 +123,147 @@ unsigned long ASN1_tag2bit(int tag) * case. */ -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it) -{ +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, const ASN1_ITEM *it) + { ASN1_TLC c; ASN1_VALUE *ptmpval = NULL; - if(!pval) pval = &ptmpval; - asn1_tlc_clear(&c); - if(ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + if (!pval) + pval = &ptmpval; + c.valid = 0; + if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) return *pval; return NULL; -} + } -int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt) -{ +int ASN1_template_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, const ASN1_TEMPLATE *tt) + { ASN1_TLC c; - asn1_tlc_clear(&c); + c.valid = 0; return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); -} + } /* Decode an item, taking care of IMPLICIT tagging, if any. * If 'opt' set and tag mismatch return -1 to handle OPTIONAL */ -int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) -{ +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) + { const ASN1_TEMPLATE *tt, *errtt = NULL; const ASN1_COMPAT_FUNCS *cf; const ASN1_EXTERN_FUNCS *ef; const ASN1_AUX *aux = it->funcs; ASN1_aux_cb *asn1_cb; - unsigned char *p, *q, imphack = 0, oclass; + const unsigned char *p = NULL, *q; + unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ + unsigned char imphack = 0, oclass; char seq_eoc, seq_nolen, cst, isopt; long tmplen; int i; int otag; int ret = 0; ASN1_VALUE *pchval, **pchptr, *ptmpval; - if(!pval) return 0; - if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; + if (!pval) + return 0; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; else asn1_cb = 0; - switch(it->itype) { - + switch(it->itype) + { case ASN1_ITYPE_PRIMITIVE: - if(it->templates) { - /* tagging or OPTIONAL is currently illegal on an item template - * because the flags can't get passed down. In practice this isn't - * a problem: we include the relevant flags from the item template - * in the template itself. + if (it->templates) + { + /* tagging or OPTIONAL is currently illegal on an item + * template because the flags can't get passed down. + * In practice this isn't a problem: we include the + * relevant flags from the item template in the + * template itself. */ - if ((tag != -1) || opt) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); + if ((tag != -1) || opt) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); goto err; - } - return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx); + } + return asn1_template_ex_d2i(pval, in, len, + it->templates, opt, ctx); } - return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); + return asn1_d2i_ex_primitive(pval, in, len, it, + tag, aclass, opt, ctx); break; case ASN1_ITYPE_MSTRING: p = *in; /* Just read in tag and class */ - ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, + &p, len, -1, 0, 1, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; - } + } + /* Must be UNIVERSAL class */ - if(oclass != V_ASN1_UNIVERSAL) { + if (oclass != V_ASN1_UNIVERSAL) + { /* If OPTIONAL, assume this is OK */ - if(opt) return -1; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); + if (opt) return -1; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_MSTRING_NOT_UNIVERSAL); goto err; - } + } /* Check tag matches bit map */ - if(!(ASN1_tag2bit(otag) & it->utype)) { + if (!(ASN1_tag2bit(otag) & it->utype)) + { /* If OPTIONAL, assume this is OK */ - if(opt) return -1; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); + if (opt) + return -1; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_MSTRING_WRONG_TAG); goto err; - } - return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); + } + return asn1_d2i_ex_primitive(pval, in, len, + it, otag, 0, 0, ctx); case ASN1_ITYPE_EXTERN: /* Use new style d2i */ ef = it->funcs; - return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); + return ef->asn1_ex_d2i(pval, in, len, + it, tag, aclass, opt, ctx); case ASN1_ITYPE_COMPAT: /* we must resort to old style evil hackery */ cf = it->funcs; /* If OPTIONAL see if it is there */ - if(opt) { + if (opt) + { int exptag; p = *in; - if(tag == -1) exptag = it->utype; + if (tag == -1) + exptag = it->utype; else exptag = tag; - /* Don't care about anything other than presence of expected tag */ - ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, &p, len, exptag, aclass, 1, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + /* Don't care about anything other than presence + * of expected tag */ + + ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, + &p, len, exptag, aclass, 1, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; + } + if (ret == -1) + return -1; } - if(ret == -1) return -1; - } + /* This is the old style evil hack IMPLICIT handling: * since the underlying code is expecting a tag and * class other than the one present we change the @@ -229,245 +279,332 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 * buffer. */ - if(tag != -1) { - p = *in; - imphack = *p; - *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype); - } + if (tag != -1) + { + wp = *(unsigned char **)in; + imphack = *wp; + if (p == NULL) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; + } + *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) + | it->utype); + } ptmpval = cf->asn1_d2i(pval, in, len); - if(tag != -1) *p = imphack; + if (tag != -1) + *wp = imphack; + + if (ptmpval) + return 1; - if(ptmpval) return 1; ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; case ASN1_ITYPE_CHOICE: - if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) goto auxerr; /* Allocate structure */ - if(!*pval) { - if(!ASN1_item_ex_new(pval, it)) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; + if (!*pval && !ASN1_item_ex_new(pval, it)) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; } - } /* CHOICE type, try each possibility in turn */ pchval = NULL; p = *in; - for(i = 0, tt=it->templates; i < it->tcount; i++, tt++) { + for (i = 0, tt=it->templates; i < it->tcount; i++, tt++) + { pchptr = asn1_get_field_ptr(pval, tt); /* We mark field as OPTIONAL so its absence * can be recognised. */ ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); /* If field not present, try the next one */ - if(ret == -1) continue; + if (ret == -1) + continue; /* If positive return, read OK, break loop */ - if(ret > 0) break; + if (ret > 0) + break; /* Otherwise must be an ASN1 parsing error */ errtt = tt; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; - } + } + /* Did we fall off the end without reading anything? */ - if(i == it->tcount) { + if (i == it->tcount) + { /* If OPTIONAL, this is OK */ - if(opt) { + if (opt) + { /* Free and zero it */ ASN1_item_ex_free(pval, it); return -1; - } - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); + } + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_NO_MATCHING_CHOICE_TYPE); goto err; - } + } + asn1_set_choice_selector(pval, i, it); *in = p; - if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) goto auxerr; return 1; + case ASN1_ITYPE_NDEF_SEQUENCE: case ASN1_ITYPE_SEQUENCE: p = *in; tmplen = len; /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ - if(tag == -1) { + if (tag == -1) + { tag = V_ASN1_SEQUENCE; aclass = V_ASN1_UNIVERSAL; - } + } /* Get SEQUENCE length and update len, p */ - ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, + &p, len, tag, aclass, opt, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; - } else if(ret == -1) return -1; - if(aux && (aux->flags & ASN1_AFLG_BROKEN)) { + } + else if (ret == -1) + return -1; + if (aux && (aux->flags & ASN1_AFLG_BROKEN)) + { len = tmplen - (p - *in); seq_nolen = 1; - } else seq_nolen = seq_eoc; /* If indefinite we don't do a length check */ - if(!cst) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + } + /* If indefinite we don't do a length check */ + else seq_nolen = seq_eoc; + if (!cst) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_SEQUENCE_NOT_CONSTRUCTED); goto err; - } + } - if(!*pval) { - if(!ASN1_item_ex_new(pval, it)) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; + if (!*pval && !ASN1_item_ex_new(pval, it)) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; } - } - if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) + + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) goto auxerr; /* Get each field entry */ - for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) + { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); - if(!seqtt) goto err; + if (!seqtt) + goto err; pseqval = asn1_get_field_ptr(pval, seqtt); /* Have we ran out of data? */ - if(!len) break; + if (!len) + break; q = p; - if(asn1_check_eoc(&p, len)) { - if(!seq_eoc) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); + if (asn1_check_eoc(&p, len)) + { + if (!seq_eoc) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_UNEXPECTED_EOC); goto err; - } + } len -= p - q; seq_eoc = 0; q = p; break; - } - /* This determines the OPTIONAL flag value. The field cannot - * be omitted if it is the last of a SEQUENCE and there is - * still data to be read. This isn't strictly necessary but - * it increases efficiency in some cases. + } + /* This determines the OPTIONAL flag value. The field + * cannot be omitted if it is the last of a SEQUENCE + * and there is still data to be read. This isn't + * strictly necessary but it increases efficiency in + * some cases. */ - if(i == (it->tcount - 1)) isopt = 0; + if (i == (it->tcount - 1)) + isopt = 0; else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); - /* attempt to read in field, allowing each to be OPTIONAL */ - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); - if(!ret) { + /* attempt to read in field, allowing each to be + * OPTIONAL */ + + ret = asn1_template_ex_d2i(pseqval, &p, len, + seqtt, isopt, ctx); + if (!ret) + { errtt = seqtt; goto err; - } else if(ret == -1) { - /* OPTIONAL component absent. Free and zero the field + } + else if (ret == -1) + { + /* OPTIONAL component absent. + * Free and zero the field. */ ASN1_template_free(pseqval, seqtt); continue; - } + } /* Update length */ len -= p - q; - } + } + /* Check for EOC if expecting one */ - if(seq_eoc && !asn1_check_eoc(&p, len)) { + if (seq_eoc && !asn1_check_eoc(&p, len)) + { ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); goto err; - } + } /* Check all data read */ - if(!seq_nolen && len) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); + if (!seq_nolen && len) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_SEQUENCE_LENGTH_MISMATCH); goto err; - } + } /* If we get here we've got no more data in the SEQUENCE, * however we may not have read all fields so check all * remaining are OPTIONAL and clear any that are. */ - for(; i < it->tcount; tt++, i++) { + for (; i < it->tcount; tt++, i++) + { const ASN1_TEMPLATE *seqtt; seqtt = asn1_do_adb(pval, tt, 1); - if(!seqtt) goto err; - if(seqtt->flags & ASN1_TFLG_OPTIONAL) { + if (!seqtt) + goto err; + if (seqtt->flags & ASN1_TFLG_OPTIONAL) + { ASN1_VALUE **pseqval; pseqval = asn1_get_field_ptr(pval, seqtt); ASN1_template_free(pseqval, seqtt); - } else { + } + else + { errtt = seqtt; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_FIELD_MISSING); goto err; + } } - } /* Save encoding */ - if(!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr; + if (!asn1_enc_save(pval, *in, p - *in, it)) + goto auxerr; *in = p; - if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) goto auxerr; return 1; default: return 0; - } + } auxerr: ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); err: ASN1_item_ex_free(pval, it); - if(errtt) ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); - else ERR_add_error_data(2, "Type=", it->sname); + if (errtt) + ERR_add_error_data(4, "Field=", errtt->field_name, + ", Type=", it->sname); + else + ERR_add_error_data(2, "Type=", it->sname); return 0; -} + } -/* Templates are handled with two separate functions. One handles any EXPLICIT tag and the other handles the - * rest. +/* Templates are handled with two separate functions. + * One handles any EXPLICIT tag and the other handles the rest. */ -static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) -{ +static int asn1_template_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long inlen, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx) + { int flags, aclass; int ret; long len; - unsigned char *p, *q; + const unsigned char *p, *q; char exp_eoc; - if(!val) return 0; + if (!val) + return 0; flags = tt->flags; aclass = flags & ASN1_TFLG_TAG_CLASS; p = *in; /* Check if EXPLICIT tag expected */ - if(flags & ASN1_TFLG_EXPTAG) { + if (flags & ASN1_TFLG_EXPTAG) + { char cst; - /* Need to work out amount of data available to the inner content and where it - * starts: so read in EXPLICIT header to get the info. + /* Need to work out amount of data available to the inner + * content and where it starts: so read in EXPLICIT header to + * get the info. */ - ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, &p, inlen, tt->tag, aclass, opt, ctx); + ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, + &p, inlen, tt->tag, aclass, opt, ctx); q = p; - if(!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + if (!ret) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); return 0; - } else if(ret == -1) return -1; - if(!cst) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); + } + else if (ret == -1) + return -1; + if (!cst) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); return 0; - } + } /* We've found the field so it can't be OPTIONAL now */ ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + if (!ret) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); return 0; - } + } /* We read the field in OK so update length */ len -= p - q; - if(exp_eoc) { + if (exp_eoc) + { /* If NDEF we must have an EOC here */ - if(!asn1_check_eoc(&p, len)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC); + if (!asn1_check_eoc(&p, len)) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_MISSING_EOC); goto err; + } } - } else { - /* Otherwise we must hit the EXPLICIT tag end or its an error */ - if(len) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_EXPLICIT_LENGTH_MISMATCH); + else + { + /* Otherwise we must hit the EXPLICIT tag end or its + * an error */ + if (len) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_EXPLICIT_LENGTH_MISMATCH); goto err; + } } } - } else - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); + else + return asn1_template_noexp_d2i(val, in, inlen, + tt, opt, ctx); *in = p; return 1; @@ -476,98 +613,145 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen ASN1_template_free(val, tt); *val = NULL; return 0; -} + } -static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) -{ +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx) + { int flags, aclass; int ret; - unsigned char *p, *q; - if(!val) return 0; + const unsigned char *p, *q; + if (!val) + return 0; flags = tt->flags; aclass = flags & ASN1_TFLG_TAG_CLASS; p = *in; q = p; - if(flags & ASN1_TFLG_SK_MASK) { + if (flags & ASN1_TFLG_SK_MASK) + { /* SET OF, SEQUENCE OF */ int sktag, skaclass; char sk_eoc; /* First work out expected inner tag value */ - if(flags & ASN1_TFLG_IMPTAG) { + if (flags & ASN1_TFLG_IMPTAG) + { sktag = tt->tag; skaclass = aclass; - } else { + } + else + { skaclass = V_ASN1_UNIVERSAL; - if(flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET; - else sktag = V_ASN1_SEQUENCE; - } + if (flags & ASN1_TFLG_SET_OF) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } /* Get the tag */ - ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, + &p, len, sktag, skaclass, opt, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); return 0; - } else if(ret == -1) return -1; - if(!*val) *val = (ASN1_VALUE *)sk_new_null(); - else { + } + else if (ret == -1) + return -1; + if (!*val) + *val = (ASN1_VALUE *)sk_new_null(); + else + { /* We've got a valid STACK: free up any items present */ STACK *sktmp = (STACK *)*val; ASN1_VALUE *vtmp; - while(sk_num(sktmp) > 0) { + while(sk_num(sktmp) > 0) + { vtmp = (ASN1_VALUE *)sk_pop(sktmp); - ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); + ASN1_item_ex_free(&vtmp, + ASN1_ITEM_ptr(tt->item)); + } } - } - if(!*val) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE); + if (!*val) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_MALLOC_FAILURE); goto err; - } + } + /* Read as many items as we can */ - while(len > 0) { + while(len > 0) + { ASN1_VALUE *skfield; q = p; /* See if EOC found */ - if(asn1_check_eoc(&p, len)) { - if(!sk_eoc) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_UNEXPECTED_EOC); + if (asn1_check_eoc(&p, len)) + { + if (!sk_eoc) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ASN1_R_UNEXPECTED_EOC); goto err; - } + } len -= p - q; sk_eoc = 0; break; - } + } skfield = NULL; - if(!ASN1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); + if (!ASN1_item_ex_d2i(&skfield, &p, len, + ASN1_ITEM_ptr(tt->item), + -1, 0, 0, ctx)) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; - } + } len -= p - q; - if(!sk_push((STACK *)*val, (char *)skfield)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_MALLOC_FAILURE); + if (!sk_push((STACK *)*val, (char *)skfield)) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_MALLOC_FAILURE); goto err; + } } - } - if(sk_eoc) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC); + if (sk_eoc) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); goto err; + } } - } else if(flags & ASN1_TFLG_IMPTAG) { + else if (flags & ASN1_TFLG_IMPTAG) + { /* IMPLICIT tagging */ - ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); + ret = ASN1_item_ex_d2i(val, &p, len, + ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; - } else if(ret == -1) return -1; - } else { + } + else if (ret == -1) + return -1; + } + else + { /* Nothing special */ - ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, opt, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); + ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), + -1, 0, opt, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); goto err; - } else if(ret == -1) return -1; - } + } + else if (ret == -1) + return -1; + } *in = p; return 1; @@ -576,85 +760,115 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long le ASN1_template_free(val, tt); *val = NULL; return 0; -} + } -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) -{ +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long inlen, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) + { int ret = 0, utype; long plen; char cst, inf, free_cont = 0; - unsigned char *p; + const unsigned char *p; BUF_MEM buf; - unsigned char *cont = NULL; + const unsigned char *cont = NULL; long len; - if(!pval) { + if (!pval) + { ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); return 0; /* Should never happen */ - } + } - if(it->itype == ASN1_ITYPE_MSTRING) { + if (it->itype == ASN1_ITYPE_MSTRING) + { utype = tag; tag = -1; - } else utype = it->utype; + } + else + utype = it->utype; - if(utype == V_ASN1_ANY) { + if (utype == V_ASN1_ANY) + { /* If type is ANY need to figure out type from tag */ unsigned char oclass; - if(tag >= 0) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); + if (tag >= 0) + { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_ILLEGAL_TAGGED_ANY); return 0; - } - if(opt) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_OPTIONAL_ANY); + } + if (opt) + { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_ILLEGAL_OPTIONAL_ANY); return 0; - } + } p = *in; - ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx); - if(!ret) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, + &p, inlen, -1, 0, 0, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ERR_R_NESTED_ASN1_ERROR); return 0; + } + if (oclass != V_ASN1_UNIVERSAL) + utype = V_ASN1_OTHER; } - if(oclass != V_ASN1_UNIVERSAL) utype = V_ASN1_OTHER; - } - if(tag == -1) { + if (tag == -1) + { tag = utype; aclass = V_ASN1_UNIVERSAL; - } + } p = *in; /* Check header */ - ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx); - if(!ret) { + ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, + &p, inlen, tag, aclass, opt, ctx); + if (!ret) + { ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); return 0; - } else if(ret == -1) return -1; - - ret = 0; + } + else if (ret == -1) + return -1; + ret = 0; /* SEQUENCE, SET and "OTHER" are left in encoded form */ - if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { - /* Clear context cache for type OTHER because the auto clear when - * we have a exact match wont work + if ((utype == V_ASN1_SEQUENCE) + || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) + { + /* Clear context cache for type OTHER because the auto clear + * when we have a exact match wont work */ - if(utype == V_ASN1_OTHER) { + if (utype == V_ASN1_OTHER) + { asn1_tlc_clear(ctx); + } /* SEQUENCE and SET must be constructed */ - } else if(!cst) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_CONSTRUCTED); + else if (!cst) + { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_TYPE_NOT_CONSTRUCTED); return 0; - } + } cont = *in; /* If indefinite length constructed find the real end */ - if(inf) { - if(!asn1_find_end(&p, plen, inf)) goto err; + if (inf) + { + if (!asn1_find_end(&p, plen, inf)) + goto err; len = p - cont; - } else { + } + else + { len = p - cont + plen; p += plen; buf.data = NULL; + } } - } else if(cst) { + else if (cst) + { buf.length = 0; buf.max = 0; buf.data = NULL; @@ -664,36 +878,46 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl * internally irrespective of the type. So instead just check * for UNIVERSAL class and ignore the tag. */ - if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err; + if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) + { + free_cont = 1; + goto err; + } len = buf.length; /* Append a final null to string */ - if(!BUF_MEM_grow_clean(&buf, len + 1)) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + if (!BUF_MEM_grow_clean(&buf, len + 1)) + { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ERR_R_MALLOC_FAILURE); return 0; - } + } buf.data[len] = 0; - cont = (unsigned char *)buf.data; + cont = (const unsigned char *)buf.data; free_cont = 1; - } else { + } + else + { cont = p; len = plen; p += plen; - } + } /* We now have content length and type: translate into a structure */ - if(!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) goto err; + if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) + goto err; *in = p; ret = 1; err: - if(free_cont && buf.data) OPENSSL_free(buf.data); + if (free_cont && buf.data) OPENSSL_free(buf.data); return ret; -} + } /* Translate ASN1 content octets into a structure */ -int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) -{ +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) + { ASN1_VALUE **opval = NULL; ASN1_STRING *stmp; ASN1_TYPE *typ = NULL; @@ -701,43 +925,62 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char const ASN1_PRIMITIVE_FUNCS *pf; ASN1_INTEGER **tint; pf = it->funcs; - if(pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it); + + if (pf && pf->prim_c2i) + return pf->prim_c2i(pval, cont, len, utype, free_cont, it); /* If ANY type clear type and set pointer to internal value */ - if(it->utype == V_ASN1_ANY) { - if(!*pval) { + if (it->utype == V_ASN1_ANY) + { + if (!*pval) + { typ = ASN1_TYPE_new(); + if (typ == NULL) + goto err; *pval = (ASN1_VALUE *)typ; - } else typ = (ASN1_TYPE *)*pval; - if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); + } + else + typ = (ASN1_TYPE *)*pval; + + if (utype != typ->type) + ASN1_TYPE_set(typ, utype, NULL); opval = pval; - pval = (ASN1_VALUE **)&typ->value.ptr; - } - switch(utype) { + pval = &typ->value.asn1_value; + } + switch(utype) + { case V_ASN1_OBJECT: - if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err; + if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) + goto err; break; case V_ASN1_NULL: - if(len) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH); + if (len) + { + ASN1err(ASN1_F_ASN1_EX_C2I, + ASN1_R_NULL_IS_WRONG_LENGTH); goto err; - } + } *pval = (ASN1_VALUE *)1; break; case V_ASN1_BOOLEAN: - if(len != 1) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + if (len != 1) + { + ASN1err(ASN1_F_ASN1_EX_C2I, + ASN1_R_BOOLEAN_IS_WRONG_LENGTH); goto err; - } else { + } + else + { ASN1_BOOLEAN *tbool; tbool = (ASN1_BOOLEAN *)pval; *tbool = *cont; - } + } break; case V_ASN1_BIT_STRING: - if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err; + if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) + goto err; break; case V_ASN1_INTEGER: @@ -745,7 +988,8 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char case V_ASN1_ENUMERATED: case V_ASN1_NEG_ENUMERATED: tint = (ASN1_INTEGER **)pval; - if(!c2i_ASN1_INTEGER(tint, &cont, len)) goto err; + if (!c2i_ASN1_INTEGER(tint, &cont, len)) + goto err; /* Fixup type to match the expected form */ (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); break; @@ -769,46 +1013,59 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char case V_ASN1_SEQUENCE: default: /* All based on ASN1_STRING and handled the same */ - if(!*pval) { + if (!*pval) + { stmp = ASN1_STRING_type_new(utype); - if(!stmp) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + if (!stmp) + { + ASN1err(ASN1_F_ASN1_EX_C2I, + ERR_R_MALLOC_FAILURE); goto err; - } + } *pval = (ASN1_VALUE *)stmp; - } else { + } + else + { stmp = (ASN1_STRING *)*pval; stmp->type = utype; - } + } /* If we've already allocated a buffer use it */ - if(*free_cont) { - if(stmp->data) OPENSSL_free(stmp->data); - stmp->data = cont; + if (*free_cont) + { + if (stmp->data) + OPENSSL_free(stmp->data); + stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ stmp->length = len; *free_cont = 0; - } else { - if(!ASN1_STRING_set(stmp, cont, len)) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + } + else + { + if (!ASN1_STRING_set(stmp, cont, len)) + { + ASN1err(ASN1_F_ASN1_EX_C2I, + ERR_R_MALLOC_FAILURE); ASN1_STRING_free(stmp); *pval = NULL; goto err; + } } - } break; - } + } /* If ASN1_ANY and NULL type fix up value */ - if(typ && utype==V_ASN1_NULL) typ->value.ptr = NULL; + if (typ && (utype == V_ASN1_NULL)) + typ->value.ptr = NULL; ret = 1; err: - if(!ret) + if (!ret) { ASN1_TYPE_free(typ); if (opval) *opval = NULL; } return ret; -} + } + /* This function finds the end of an ASN1 structure when passed its maximum * length, whether it is indefinite length and a pointer to the content. @@ -816,11 +1073,11 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char * recurse on each indefinite length header. */ -static int asn1_find_end(unsigned char **in, long len, char inf) +static int asn1_find_end(const unsigned char **in, long len, char inf) { int expected_eoc; long plen; - unsigned char *p = *in, *q; + const unsigned char *p = *in, *q; /* If not indefinite length constructed just add length */ if (inf == 0) { @@ -830,7 +1087,7 @@ static int asn1_find_end(unsigned char **in, long len, char inf) expected_eoc = 1; /* Indefinite length constructed form. Find the end when enough EOCs * are found. If more indefinite length constructed headers - * are encountered increment the expected eoc count otherwise justi + * are encountered increment the expected eoc count otherwise just * skip to the end of the data. */ while (len > 0) @@ -865,38 +1122,55 @@ static int asn1_find_end(unsigned char **in, long len, char inf) *in = p; return 1; } - /* This function collects the asn1 data from a constructred string * type into a buffer. The values of 'in' and 'len' should refer * to the contents of the constructed type and 'inf' should be set * if it is indefinite length. */ -static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) -{ - unsigned char *p, *q; +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, + char inf, int tag, int aclass) + { + const unsigned char *p, *q; long plen; char cst, ininf; p = *in; inf &= 1; - while(len > 0) { + /* If no buffer and not indefinite length constructed just pass over + * the encoded data */ + if (!buf && !inf) + { + *in += len; + return 1; + } + while(len > 0) + { q = p; /* Check for EOC */ - if(asn1_check_eoc(&p, len)) { - /* EOC is illegal outside indefinite length constructed form */ - if(!inf) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); + if (asn1_check_eoc(&p, len)) + { + /* EOC is illegal outside indefinite length + * constructed form */ + if (!inf) + { + ASN1err(ASN1_F_ASN1_COLLECT, + ASN1_R_UNEXPECTED_EOC); return 0; - } + } inf = 0; break; - } - if(!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, len, tag, aclass, 0, NULL)) { + } + + if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, + len, tag, aclass, 0, NULL)) + { ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); return 0; - } + } + /* If indefinite length constructed update max length */ - if(cst) { + if (cst) + { #ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS if (!asn1_collect(buf, &p, plen, ininf, tag, aclass)) return 0; @@ -904,47 +1178,51 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); return 0; #endif - } else { - if(plen && !collect_data(buf, &p, plen)) return 0; - } + } + else if (plen && !collect_data(buf, &p, plen)) + return 0; len -= p - q; - } - if(inf) { + } + if (inf) + { ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); return 0; - } + } *in = p; return 1; -} - -static int collect_data(BUF_MEM *buf, unsigned char **p, long plen) -{ - int len; - if(buf) { - len = buf->length; - if(!BUF_MEM_grow_clean(buf, len + plen)) { - ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); - return 0; + } + +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) + { + int len; + if (buf) + { + len = buf->length; + if (!BUF_MEM_grow_clean(buf, len + plen)) + { + ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); + return 0; } - memcpy(buf->data + len, *p, plen); + memcpy(buf->data + len, *p, plen); } - *p += plen; - return 1; -} + *p += plen; + return 1; + } /* Check for ASN1 EOC and swallow it if found */ -static int asn1_check_eoc(unsigned char **in, long len) -{ - unsigned char *p; - if(len < 2) return 0; +static int asn1_check_eoc(const unsigned char **in, long len) + { + const unsigned char *p; + if (len < 2) return 0; p = *in; - if(!p[0] && !p[1]) { + if (!p[0] && !p[1]) + { *in += 2; return 1; - } + } return 0; -} + } /* Check an ASN1 tag and length: a bit like ASN1_get_object * but it sets the length for indefinite length constructed @@ -953,25 +1231,32 @@ static int asn1_check_eoc(unsigned char **in, long len) * header length just read. */ -static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, - unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx) -{ +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *inf, char *cst, + const unsigned char **in, long len, + int exptag, int expclass, char opt, + ASN1_TLC *ctx) + { int i; int ptag, pclass; long plen; - unsigned char *p, *q; + const unsigned char *p, *q; p = *in; q = p; - if(ctx && ctx->valid) { + if (ctx && ctx->valid) + { i = ctx->ret; plen = ctx->plen; pclass = ctx->pclass; ptag = ctx->ptag; p += ctx->hdrlen; - } else { + } + else + { i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); - if(ctx) { + if (ctx) + { ctx->ret = i; ctx->plen = plen; ctx->pclass = pclass; @@ -981,43 +1266,57 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *i /* If definite length, and no error, length + * header can't exceed total amount of data available. */ - if(!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); + if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) + { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, + ASN1_R_TOO_LONG); asn1_tlc_clear(ctx); return 0; + } } } - } - if(i & 0x80) { + if (i & 0x80) + { ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); asn1_tlc_clear(ctx); return 0; - } - if(exptag >= 0) { - if((exptag != ptag) || (expclass != pclass)) { - /* If type is OPTIONAL, not an error, but indicate missing - * type. + } + if (exptag >= 0) + { + if ((exptag != ptag) || (expclass != pclass)) + { + /* If type is OPTIONAL, not an error: + * indicate missing type. */ - if(opt) return -1; + if (opt) return -1; asn1_tlc_clear(ctx); ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); return 0; - } - /* We have a tag and class match, so assume we are going to do something with it */ + } + /* We have a tag and class match: + * assume we are going to do something with it */ asn1_tlc_clear(ctx); - } + } + + if (i & 1) + plen = len - (p - q); - if(i & 1) plen = len - (p - q); + if (inf) + *inf = i & 1; - if(inf) *inf = i & 1; + if (cst) + *cst = i & V_ASN1_CONSTRUCTED; - if(cst) *cst = i & V_ASN1_CONSTRUCTED; + if (olen) + *olen = plen; - if(olen) *olen = plen; - if(oclass) *oclass = pclass; - if(otag) *otag = ptag; + if (oclass) + *oclass = pclass; + + if (otag) + *otag = ptag; *in = p; return 1; -} + } diff --git a/src/lib/libcrypto/asn1/tasn_enc.c b/src/lib/libcrypto/asn1/tasn_enc.c index c675c3c832..be19b36acd 100644 --- a/src/lib/libcrypto/asn1/tasn_enc.c +++ b/src/lib/libcrypto/asn1/tasn_enc.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,88 +59,119 @@ #include #include +#include "cryptlib.h" #include #include #include -static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); -static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *seq, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int isset); +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, + int tag, int aclass); +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, + int do_sort, int iclass); +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, + int tag, int aclass); +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it, int flags); + +/* Top level i2d equivalents: the 'ndef' variant instructs the encoder + * to use indefinite length constructed encoding, where appropriate + */ + +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it) + { + return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); + } + +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) + { + return asn1_item_flags_i2d(val, out, it, 0); + } -/* Encode an ASN1 item, this is compatible with the +/* Encode an ASN1 item, this is use by the * standard 'i2d' function. 'out' points to - * a buffer to output the data to, in future we will - * have more advanced versions that can output data - * a piece at a time and this will simply be a special - * case. + * a buffer to output the data to. * * The new i2d has one additional feature. If the output * buffer is NULL (i.e. *out == NULL) then a buffer is * allocated and populated with the encoding. */ - -int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) -{ - if(out && !*out) { +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it, int flags) + { + if (out && !*out) + { unsigned char *p, *buf; int len; - len = ASN1_item_ex_i2d(&val, NULL, it, -1, 0); - if(len <= 0) return len; + len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); + if (len <= 0) + return len; buf = OPENSSL_malloc(len); - if(!buf) return -1; + if (!buf) + return -1; p = buf; - ASN1_item_ex_i2d(&val, &p, it, -1, 0); + ASN1_item_ex_i2d(&val, &p, it, -1, flags); *out = buf; return len; + } + + return ASN1_item_ex_i2d(&val, out, it, -1, flags); } - - return ASN1_item_ex_i2d(&val, out, it, -1, 0); -} /* Encode an item, taking care of IMPLICIT tagging (if any). * This function performs the normal item handling: it can be * used in external types. */ -int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) -{ +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) + { const ASN1_TEMPLATE *tt = NULL; unsigned char *p = NULL; - int i, seqcontlen, seqlen; - ASN1_STRING *strtmp; + int i, seqcontlen, seqlen, ndef = 1; const ASN1_COMPAT_FUNCS *cf; const ASN1_EXTERN_FUNCS *ef; const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; - if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return 0; - if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; - else asn1_cb = 0; + ASN1_aux_cb *asn1_cb = 0; + + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return 0; - switch(it->itype) { + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + + switch(it->itype) + { case ASN1_ITYPE_PRIMITIVE: - if(it->templates) - return ASN1_template_i2d(pval, out, it->templates); + if (it->templates) + return asn1_template_ex_i2d(pval, out, it->templates, + tag, aclass); return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); break; case ASN1_ITYPE_MSTRING: - strtmp = (ASN1_STRING *)*pval; - return asn1_i2d_ex_primitive(pval, out, it, -1, 0); + return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); case ASN1_ITYPE_CHOICE: - if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) return 0; i = asn1_get_choice_selector(pval, it); - if((i >= 0) && (i < it->tcount)) { + if ((i >= 0) && (i < it->tcount)) + { ASN1_VALUE **pchval; const ASN1_TEMPLATE *chtt; chtt = it->templates + i; pchval = asn1_get_field_ptr(pval, chtt); - return ASN1_template_i2d(pchval, out, chtt); - } + return asn1_template_ex_i2d(pchval, out, chtt, + -1, aclass); + } /* Fixme: error condition if selector out of range */ - if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) return 0; break; @@ -152,136 +183,236 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it case ASN1_ITYPE_COMPAT: /* old style hackery... */ cf = it->funcs; - if(out) p = *out; + if (out) + p = *out; i = cf->asn1_i2d(*pval, out); /* Fixup for IMPLICIT tag: note this messes up for tags > 30, * but so did the old code. Tags > 30 are very rare anyway. */ - if(out && (tag != -1)) + if (out && (tag != -1)) *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); return i; + case ASN1_ITYPE_NDEF_SEQUENCE: + /* Use indefinite length constructed if requested */ + if (aclass & ASN1_TFLG_NDEF) ndef = 2; + /* fall through */ + case ASN1_ITYPE_SEQUENCE: i = asn1_enc_restore(&seqcontlen, out, pval, it); /* An error occurred */ - if(i < 0) return 0; + if (i < 0) + return 0; /* We have a valid cached encoding... */ - if(i > 0) return seqcontlen; + if (i > 0) + return seqcontlen; /* Otherwise carry on */ seqcontlen = 0; /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ - if(tag == -1) { + if (tag == -1) + { tag = V_ASN1_SEQUENCE; - aclass = V_ASN1_UNIVERSAL; - } - if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) + /* Retain any other flags in aclass */ + aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) + | V_ASN1_UNIVERSAL; + } + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) return 0; /* First work out sequence content length */ - for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) + { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); - if(!seqtt) return 0; + if (!seqtt) + return 0; pseqval = asn1_get_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ - /* FIXME: special handling of indefinite length encoding */ - seqcontlen += ASN1_template_i2d(pseqval, NULL, seqtt); - } - seqlen = ASN1_object_size(1, seqcontlen, tag); - if(!out) return seqlen; + seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, + -1, aclass); + } + + seqlen = ASN1_object_size(ndef, seqcontlen, tag); + if (!out) + return seqlen; /* Output SEQUENCE header */ - ASN1_put_object(out, 1, seqcontlen, tag, aclass); - for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + ASN1_put_object(out, ndef, seqcontlen, tag, aclass); + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) + { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); - if(!seqtt) return 0; + if (!seqtt) + return 0; pseqval = asn1_get_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ - ASN1_template_i2d(pseqval, out, seqtt); - } - if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) + asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); + } + if (ndef == 2) + ASN1_put_eoc(out); + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) return 0; return seqlen; default: return 0; - } + + } return 0; -} + } -int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt) -{ - int i, ret, flags, aclass; +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt) + { + return asn1_template_ex_i2d(pval, out, tt, -1, 0); + } + +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int iclass) + { + int i, ret, flags, ttag, tclass, ndef; flags = tt->flags; - aclass = flags & ASN1_TFLG_TAG_CLASS; - if(flags & ASN1_TFLG_SK_MASK) { + /* Work out tag and class to use: tagging may come + * either from the template or the arguments, not both + * because this would create ambiguity. Additionally + * the iclass argument may contain some additional flags + * which should be noted and passed down to other levels. + */ + if (flags & ASN1_TFLG_TAG_MASK) + { + /* Error if argument and template tagging */ + if (tag != -1) + /* FIXME: error code here */ + return -1; + /* Get tagging from template */ + ttag = tt->tag; + tclass = flags & ASN1_TFLG_TAG_CLASS; + } + else if (tag != -1) + { + /* No template tagging, get from arguments */ + ttag = tag; + tclass = iclass & ASN1_TFLG_TAG_CLASS; + } + else + { + ttag = -1; + tclass = 0; + } + /* + * Remove any class mask from iflag. + */ + iclass &= ~ASN1_TFLG_TAG_CLASS; + + /* At this point 'ttag' contains the outer tag to use, + * 'tclass' is the class and iclass is any flags passed + * to this function. + */ + + /* if template and arguments require ndef, use it */ + if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF)) + ndef = 2; + else ndef = 1; + + if (flags & ASN1_TFLG_SK_MASK) + { /* SET OF, SEQUENCE OF */ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; int isset, sktag, skaclass; int skcontlen, sklen; ASN1_VALUE *skitem; - if(!*pval) return 0; - if(flags & ASN1_TFLG_SET_OF) { + + if (!*pval) + return 0; + + if (flags & ASN1_TFLG_SET_OF) + { isset = 1; /* 2 means we reorder */ - if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2; - } else isset = 0; - /* First work out inner tag value */ - if(flags & ASN1_TFLG_IMPTAG) { - sktag = tt->tag; - skaclass = aclass; - } else { + if (flags & ASN1_TFLG_SEQUENCE_OF) + isset = 2; + } + else isset = 0; + + /* Work out inner tag value: if EXPLICIT + * or no tagging use underlying type. + */ + if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) + { + sktag = ttag; + skaclass = tclass; + } + else + { skaclass = V_ASN1_UNIVERSAL; - if(isset) sktag = V_ASN1_SET; + if (isset) + sktag = V_ASN1_SET; else sktag = V_ASN1_SEQUENCE; - } - /* Now work out length of items */ + } + + /* Determine total length of items */ skcontlen = 0; - for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) + { skitem = sk_ASN1_VALUE_value(sk, i); - skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0); - } - sklen = ASN1_object_size(1, skcontlen, sktag); + skcontlen += ASN1_item_ex_i2d(&skitem, NULL, + ASN1_ITEM_ptr(tt->item), + -1, iclass); + } + sklen = ASN1_object_size(ndef, skcontlen, sktag); /* If EXPLICIT need length of surrounding tag */ - if(flags & ASN1_TFLG_EXPTAG) - ret = ASN1_object_size(1, sklen, tt->tag); + if (flags & ASN1_TFLG_EXPTAG) + ret = ASN1_object_size(ndef, sklen, ttag); else ret = sklen; - if(!out) return ret; + if (!out) + return ret; /* Now encode this lot... */ /* EXPLICIT tag */ - if(flags & ASN1_TFLG_EXPTAG) - ASN1_put_object(out, 1, sklen, tt->tag, aclass); + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_object(out, ndef, sklen, ttag, tclass); /* SET or SEQUENCE and IMPLICIT tag */ - ASN1_put_object(out, 1, skcontlen, sktag, skaclass); - /* And finally the stuff itself */ - asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset); + ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); + /* And the stuff itself */ + asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), + isset, iclass); + if (ndef == 2) + { + ASN1_put_eoc(out); + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_eoc(out); + } return ret; - } - - if(flags & ASN1_TFLG_EXPTAG) { + } + + if (flags & ASN1_TFLG_EXPTAG) + { /* EXPLICIT tagging */ /* Find length of tagged item */ - i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0); - if(!i) return 0; + i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), + -1, iclass); + if (!i) + return 0; /* Find length of EXPLICIT tag */ - ret = ASN1_object_size(1, i, tt->tag); - if(out) { + ret = ASN1_object_size(ndef, i, ttag); + if (out) + { /* Output tag and item */ - ASN1_put_object(out, 1, i, tt->tag, aclass); - ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0); - } + ASN1_put_object(out, ndef, i, ttag, tclass); + ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), + -1, iclass); + if (ndef == 2) + ASN1_put_eoc(out); + } return ret; - } - if(flags & ASN1_TFLG_IMPTAG) { - /* IMPLICIT tagging */ - return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), tt->tag, aclass); - } - /* Nothing special: treat as normal */ - return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0); + } + + /* Either normal or IMPLICIT tagging: combine class and flags */ + return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), + ttag, tclass | iclass); + } /* Temporary structure used to hold DER encoding of items for SET OF */ @@ -293,72 +424,90 @@ typedef struct { } DER_ENC; static int der_cmp(const void *a, const void *b) -{ + { const DER_ENC *d1 = a, *d2 = b; int cmplen, i; cmplen = (d1->length < d2->length) ? d1->length : d2->length; i = memcmp(d1->data, d2->data, cmplen); - if(i) return i; + if (i) + return i; return d1->length - d2->length; -} + } /* Output the content octets of SET OF or SEQUENCE OF */ -static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort) -{ +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, + int do_sort, int iclass) + { int i; ASN1_VALUE *skitem; unsigned char *tmpdat = NULL, *p = NULL; DER_ENC *derlst = NULL, *tder; - if(do_sort) { + if (do_sort) + { /* Don't need to sort less than 2 items */ - if(sk_ASN1_VALUE_num(sk) < 2) do_sort = 0; - else { - derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*derlst)); + if (sk_ASN1_VALUE_num(sk) < 2) + do_sort = 0; + else + { + derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) + * sizeof(*derlst)); tmpdat = OPENSSL_malloc(skcontlen); - if(!derlst || !tmpdat) return 0; + if (!derlst || !tmpdat) + return 0; + } } - } /* If not sorting just output each item */ - if(!do_sort) { - for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + if (!do_sort) + { + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) + { skitem = sk_ASN1_VALUE_value(sk, i); - ASN1_item_i2d(skitem, out, item); - } + ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); + } return 1; - } + } p = tmpdat; + /* Doing sort: build up a list of each member's DER encoding */ - for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) + { skitem = sk_ASN1_VALUE_value(sk, i); tder->data = p; - tder->length = ASN1_item_i2d(skitem, &p, item); + tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); tder->field = skitem; - } + } + /* Now sort them */ qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); /* Output sorted DER encoding */ p = *out; - for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) + { memcpy(p, tder->data, tder->length); p += tder->length; - } + } *out = p; /* If do_sort is 2 then reorder the STACK */ - if(do_sort == 2) { - for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) - sk_ASN1_VALUE_set(sk, i, tder->field); - } + if (do_sort == 2) + { + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); + i++, tder++) + (void)sk_ASN1_VALUE_set(sk, i, tder->field); + } OPENSSL_free(derlst); OPENSSL_free(tmpdat); return 1; -} + } -static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) -{ +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) + { int len; int utype; int usetag; + int ndef = 0; utype = it->utype; @@ -374,33 +523,48 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A * because the call to asn1_ex_i2c() could change * utype. */ - if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || + if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) usetag = 0; else usetag = 1; /* -1 means omit type */ - if(len == -1) return 0; + if (len == -1) + return 0; + + /* -2 return is special meaning use ndef */ + if (len == -2) + { + ndef = 2; + len = 0; + } /* If not implicitly tagged get tag from underlying type */ - if(tag == -1) tag = utype; + if (tag == -1) tag = utype; /* Output tag+length followed by content octets */ - if(out) { - if(usetag) ASN1_put_object(out, 0, len, tag, aclass); + if (out) + { + if (usetag) + ASN1_put_object(out, ndef, len, tag, aclass); asn1_ex_i2c(pval, *out, &utype, it); - *out += len; - } + if (ndef) + ASN1_put_eoc(out); + else + *out += len; + } - if(usetag) return ASN1_object_size(0, len, tag); + if (usetag) + return ASN1_object_size(ndef, len, tag); return len; -} + } /* Produce content octets from a structure */ -int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) -{ +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, + const ASN1_ITEM *it) + { ASN1_BOOLEAN *tbool = NULL; ASN1_STRING *strtmp; ASN1_OBJECT *otmp; @@ -409,28 +573,36 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ int len; const ASN1_PRIMITIVE_FUNCS *pf; pf = it->funcs; - if(pf && pf->prim_i2c) return pf->prim_i2c(pval, cout, putype, it); + if (pf && pf->prim_i2c) + return pf->prim_i2c(pval, cout, putype, it); /* Should type be omitted? */ - if((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { - if(!*pval) return -1; - } + if ((it->itype != ASN1_ITYPE_PRIMITIVE) + || (it->utype != V_ASN1_BOOLEAN)) + { + if (!*pval) return -1; + } - if(it->itype == ASN1_ITYPE_MSTRING) { + if (it->itype == ASN1_ITYPE_MSTRING) + { /* If MSTRING type set the underlying type */ strtmp = (ASN1_STRING *)*pval; utype = strtmp->type; *putype = utype; - } else if(it->utype == V_ASN1_ANY) { + } + else if (it->utype == V_ASN1_ANY) + { /* If ANY set type and pointer to value */ ASN1_TYPE *typ; typ = (ASN1_TYPE *)*pval; utype = typ->type; *putype = utype; - pval = (ASN1_VALUE **)&typ->value.ptr; - } else utype = *putype; + pval = &typ->value.asn1_value; + } + else utype = *putype; - switch(utype) { + switch(utype) + { case V_ASN1_OBJECT: otmp = (ASN1_OBJECT *)*pval; cont = otmp->data; @@ -444,12 +616,15 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ case V_ASN1_BOOLEAN: tbool = (ASN1_BOOLEAN *)pval; - if(*tbool == -1) return -1; + if (*tbool == -1) + return -1; if (it->utype != V_ASN1_ANY) { /* Default handling if value == size field then omit */ - if(*tbool && (it->size > 0)) return -1; - if(!*tbool && !it->size) return -1; + if (*tbool && (it->size > 0)) + return -1; + if (!*tbool && !it->size) + return -1; } c = (unsigned char)*tbool; cont = &c; @@ -457,7 +632,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ break; case V_ASN1_BIT_STRING: - return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); + return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, + cout ? &cout : NULL); break; case V_ASN1_INTEGER: @@ -467,7 +643,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ /* These are all have the same content format * as ASN1_INTEGER */ - return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); + return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, + cout ? &cout : NULL); break; case V_ASN1_OCTET_STRING: @@ -489,12 +666,25 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ default: /* All based on ASN1_STRING and handled the same */ strtmp = (ASN1_STRING *)*pval; + /* Special handling for NDEF */ + if ((it->size == ASN1_TFLG_NDEF) + && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) + { + if (cout) + { + strtmp->data = cout; + strtmp->length = 0; + } + /* Special return code */ + return -2; + } cont = strtmp->data; len = strtmp->length; break; - } - if(cout && len) memcpy(cout, cont, len); + } + if (cout && len) + memcpy(cout, cont, len); return len; -} + } diff --git a/src/lib/libcrypto/asn1/tasn_fre.c b/src/lib/libcrypto/asn1/tasn_fre.c index 2dd844159e..bb7c1e2af4 100644 --- a/src/lib/libcrypto/asn1/tasn_fre.c +++ b/src/lib/libcrypto/asn1/tasn_fre.c @@ -67,33 +67,40 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c /* Free up an ASN1 structure */ void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) -{ + { asn1_item_combine_free(&val, it, 0); -} + } void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { asn1_item_combine_free(pval, it, 0); -} + } static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) -{ + { const ASN1_TEMPLATE *tt = NULL, *seqtt; const ASN1_EXTERN_FUNCS *ef; const ASN1_COMPAT_FUNCS *cf; const ASN1_AUX *aux = it->funcs; ASN1_aux_cb *asn1_cb; int i; - if(!pval) return; - if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return; - if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; - else asn1_cb = 0; + if (!pval) + return; + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; - switch(it->itype) { + switch(it->itype) + { case ASN1_ITYPE_PRIMITIVE: - if(it->templates) ASN1_template_free(pval, it->templates); - else ASN1_primitive_free(pval, it); + if (it->templates) + ASN1_template_free(pval, it->templates); + else + ASN1_primitive_free(pval, it); break; case ASN1_ITYPE_MSTRING: @@ -101,41 +108,51 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c break; case ASN1_ITYPE_CHOICE: - if(asn1_cb) { + if (asn1_cb) + { i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); - if(i == 2) return; - } + if (i == 2) + return; + } i = asn1_get_choice_selector(pval, it); - if(asn1_cb) asn1_cb(ASN1_OP_FREE_PRE, pval, it); - if((i >= 0) && (i < it->tcount)) { + if ((i >= 0) && (i < it->tcount)) + { ASN1_VALUE **pchval; tt = it->templates + i; pchval = asn1_get_field_ptr(pval, tt); ASN1_template_free(pchval, tt); - } - if(asn1_cb) asn1_cb(ASN1_OP_FREE_POST, pval, it); - if(!combine) { + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it); + if (!combine) + { OPENSSL_free(*pval); *pval = NULL; - } + } break; case ASN1_ITYPE_COMPAT: cf = it->funcs; - if(cf && cf->asn1_free) cf->asn1_free(*pval); + if (cf && cf->asn1_free) + cf->asn1_free(*pval); break; case ASN1_ITYPE_EXTERN: ef = it->funcs; - if(ef && ef->asn1_ex_free) ef->asn1_ex_free(pval, it); + if (ef && ef->asn1_ex_free) + ef->asn1_ex_free(pval, it); break; + case ASN1_ITYPE_NDEF_SEQUENCE: case ASN1_ITYPE_SEQUENCE: - if(asn1_do_lock(pval, -1, it) > 0) return; - if(asn1_cb) { + if (asn1_do_lock(pval, -1, it) > 0) + return; + if (asn1_cb) + { i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); - if(i == 2) return; - } + if (i == 2) + return; + } asn1_enc_free(pval, it); /* If we free up as normal we will invalidate any * ANY DEFINED BY field and we wont be able to @@ -143,64 +160,84 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c * free up in reverse order. */ tt = it->templates + it->tcount - 1; - for(i = 0; i < it->tcount; tt--, i++) { + for (i = 0; i < it->tcount; tt--, i++) + { ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 0); - if(!seqtt) continue; + if (!seqtt) + continue; pseqval = asn1_get_field_ptr(pval, seqtt); ASN1_template_free(pseqval, seqtt); - } - if(asn1_cb) asn1_cb(ASN1_OP_FREE_POST, pval, it); - if(!combine) { + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it); + if (!combine) + { OPENSSL_free(*pval); *pval = NULL; - } + } break; + } } -} void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ + { int i; - if(tt->flags & ASN1_TFLG_SK_MASK) { + if (tt->flags & ASN1_TFLG_SK_MASK) + { STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; - for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) + { ASN1_VALUE *vtmp; vtmp = sk_ASN1_VALUE_value(sk, i); - asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); - } + asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), + 0); + } sk_ASN1_VALUE_free(sk); *pval = NULL; - } else asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), + } + else + asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), tt->flags & ASN1_TFLG_COMBINE); -} + } void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { int utype; - if(it) { + if (it) + { const ASN1_PRIMITIVE_FUNCS *pf; pf = it->funcs; - if(pf && pf->prim_free) { + if (pf && pf->prim_free) + { pf->prim_free(pval, it); return; + } } - } /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ - if(!it) { + if (!it) + { ASN1_TYPE *typ = (ASN1_TYPE *)*pval; utype = typ->type; - pval = (ASN1_VALUE **)&typ->value.ptr; - if(!*pval) return; - } else if(it->itype == ASN1_ITYPE_MSTRING) { + pval = &typ->value.asn1_value; + if (!*pval) + return; + } + else if (it->itype == ASN1_ITYPE_MSTRING) + { utype = -1; - if(!*pval) return; - } else { + if (!*pval) + return; + } + else + { utype = it->utype; - if((utype != V_ASN1_BOOLEAN) && !*pval) return; - } + if ((utype != V_ASN1_BOOLEAN) && !*pval) + return; + } - switch(utype) { + switch(utype) + { case V_ASN1_OBJECT: ASN1_OBJECT_free((ASN1_OBJECT *)*pval); break; @@ -224,6 +261,6 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) ASN1_STRING_free((ASN1_STRING *)*pval); *pval = NULL; break; - } + } *pval = NULL; -} + } diff --git a/src/lib/libcrypto/asn1/tasn_new.c b/src/lib/libcrypto/asn1/tasn_new.c index a0e3db574f..531dad365c 100644 --- a/src/lib/libcrypto/asn1/tasn_new.c +++ b/src/lib/libcrypto/asn1/tasn_new.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -64,27 +64,30 @@ #include #include -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) -{ + { ASN1_VALUE *ret = NULL; - if(ASN1_item_ex_new(&ret, it) > 0) return ret; + if (ASN1_item_ex_new(&ret, it) > 0) + return ret; return NULL; -} + } /* Allocate an ASN1 structure */ int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { return asn1_item_ex_combine_new(pval, it, 0); -} + } -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) -{ +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine) + { const ASN1_TEMPLATE *tt = NULL; const ASN1_COMPAT_FUNCS *cf; const ASN1_EXTERN_FUNCS *ef; @@ -92,133 +95,155 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int ASN1_aux_cb *asn1_cb; ASN1_VALUE **pseqval; int i; - if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; - else asn1_cb = 0; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; - if(!combine) *pval = NULL; + if (!combine) *pval = NULL; #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_push_info(it->sname); + if (it->sname) + CRYPTO_push_info(it->sname); #endif - switch(it->itype) { + switch(it->itype) + { case ASN1_ITYPE_EXTERN: ef = it->funcs; - if(ef && ef->asn1_ex_new) { - if(!ef->asn1_ex_new(pval, it)) + if (ef && ef->asn1_ex_new) + { + if (!ef->asn1_ex_new(pval, it)) goto memerr; - } + } break; case ASN1_ITYPE_COMPAT: cf = it->funcs; - if(cf && cf->asn1_new) { + if (cf && cf->asn1_new) { *pval = cf->asn1_new(); - if(!*pval) goto memerr; + if (!*pval) + goto memerr; } break; case ASN1_ITYPE_PRIMITIVE: - if(it->templates) { - if(!ASN1_template_new(pval, it->templates)) + if (it->templates) + { + if (!ASN1_template_new(pval, it->templates)) goto memerr; - } else { - if(!ASN1_primitive_new(pval, it)) + } + else if (!ASN1_primitive_new(pval, it)) goto memerr; - } break; case ASN1_ITYPE_MSTRING: - if(!ASN1_primitive_new(pval, it)) + if (!ASN1_primitive_new(pval, it)) goto memerr; break; case ASN1_ITYPE_CHOICE: - if(asn1_cb) { + if (asn1_cb) + { i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); - if(!i) goto auxerr; - if(i==2) { + if (!i) + goto auxerr; + if (i==2) + { #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_pop_info(); + if (it->sname) + CRYPTO_pop_info(); #endif return 1; + } } - } - if(!combine) { + if (!combine) + { *pval = OPENSSL_malloc(it->size); - if(!*pval) goto memerr; + if (!*pval) + goto memerr; memset(*pval, 0, it->size); - } + } asn1_set_choice_selector(pval, -1, it); - if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) goto auxerr; break; + case ASN1_ITYPE_NDEF_SEQUENCE: case ASN1_ITYPE_SEQUENCE: - if(asn1_cb) { + if (asn1_cb) + { i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); - if(!i) goto auxerr; - if(i==2) { + if (!i) + goto auxerr; + if (i==2) + { #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_pop_info(); + if (it->sname) + CRYPTO_pop_info(); #endif return 1; + } } - } - if(!combine) { + if (!combine) + { *pval = OPENSSL_malloc(it->size); - if(!*pval) goto memerr; + if (!*pval) + goto memerr; memset(*pval, 0, it->size); asn1_do_lock(pval, 0, it); asn1_enc_init(pval, it); - } - for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + } + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) + { pseqval = asn1_get_field_ptr(pval, tt); - if(!ASN1_template_new(pseqval, tt)) goto memerr; - } - if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) + if (!ASN1_template_new(pseqval, tt)) + goto memerr; + } + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) goto auxerr; break; } #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_pop_info(); + if (it->sname) CRYPTO_pop_info(); #endif return 1; memerr: - ASN1err(ASN1_F_ASN1_ITEM_NEW, ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_pop_info(); + if (it->sname) CRYPTO_pop_info(); #endif return 0; auxerr: - ASN1err(ASN1_F_ASN1_ITEM_NEW, ASN1_R_AUX_ERROR); + ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); ASN1_item_ex_free(pval, it); #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_pop_info(); + if (it->sname) CRYPTO_pop_info(); #endif return 0; -} + } static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { const ASN1_EXTERN_FUNCS *ef; - switch(it->itype) { + switch(it->itype) + { case ASN1_ITYPE_EXTERN: ef = it->funcs; - if(ef && ef->asn1_ex_clear) + if (ef && ef->asn1_ex_clear) ef->asn1_ex_clear(pval, it); else *pval = NULL; break; case ASN1_ITYPE_PRIMITIVE: - if(it->templates) + if (it->templates) asn1_template_clear(pval, it->templates); else asn1_primitive_clear(pval, it); @@ -231,75 +256,90 @@ static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) case ASN1_ITYPE_COMPAT: case ASN1_ITYPE_CHOICE: case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_NDEF_SEQUENCE: *pval = NULL; break; + } } -} int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ + { const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); int ret; - if(tt->flags & ASN1_TFLG_OPTIONAL) { + if (tt->flags & ASN1_TFLG_OPTIONAL) + { asn1_template_clear(pval, tt); return 1; - } + } /* If ANY DEFINED BY nothing to do */ - if(tt->flags & ASN1_TFLG_ADB_MASK) { + if (tt->flags & ASN1_TFLG_ADB_MASK) + { *pval = NULL; return 1; - } + } #ifdef CRYPTO_MDEBUG - if(tt->field_name) CRYPTO_push_info(tt->field_name); + if (tt->field_name) + CRYPTO_push_info(tt->field_name); #endif /* If SET OF or SEQUENCE OF, its a STACK */ - if(tt->flags & ASN1_TFLG_SK_MASK) { + if (tt->flags & ASN1_TFLG_SK_MASK) + { STACK_OF(ASN1_VALUE) *skval; skval = sk_ASN1_VALUE_new_null(); - if(!skval) { + if (!skval) + { ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); ret = 0; goto done; - } + } *pval = (ASN1_VALUE *)skval; ret = 1; goto done; - } + } /* Otherwise pass it back to the item routine */ ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); done: #ifdef CRYPTO_MDEBUG - if(it->sname) CRYPTO_pop_info(); + if (it->sname) + CRYPTO_pop_info(); #endif return ret; -} + } static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ + { /* If ADB or STACK just NULL the field */ - if(tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) + if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) *pval = NULL; else asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); -} + } -/* NB: could probably combine most of the real XXX_new() behaviour and junk all the old - * functions. +/* NB: could probably combine most of the real XXX_new() behaviour and junk + * all the old functions. */ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { ASN1_TYPE *typ; int utype; - const ASN1_PRIMITIVE_FUNCS *pf; - pf = it->funcs; - if(pf && pf->prim_new) return pf->prim_new(pval, it); - if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; - else utype = it->utype; - switch(utype) { + + if (it && it->funcs) + { + const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; + if (pf->prim_new) + return pf->prim_new(pval, it); + } + + if (!it || (it->itype == ASN1_ITYPE_MSTRING)) + utype = -1; + else + utype = it->utype; + switch(utype) + { case V_ASN1_OBJECT: *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); return 1; @@ -317,7 +357,8 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) case V_ASN1_ANY: typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); - if(!typ) return 0; + if (!typ) + return 0; typ->value.ptr = NULL; typ->type = -1; *pval = (ASN1_VALUE *)typ; @@ -326,26 +367,29 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) default: *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); break; - } - if(*pval) return 1; + } + if (*pval) + return 1; return 0; -} + } void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { int utype; - const ASN1_PRIMITIVE_FUNCS *pf; - pf = it->funcs; - if(pf) { - if(pf->prim_clear) + if (it && it->funcs) + { + const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; + if (pf->prim_clear) pf->prim_clear(pval, it); else *pval = NULL; return; - } - if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; - else utype = it->utype; - if(utype == V_ASN1_BOOLEAN) + } + if (!it || (it->itype == ASN1_ITYPE_MSTRING)) + utype = -1; + else + utype = it->utype; + if (utype == V_ASN1_BOOLEAN) *(ASN1_BOOLEAN *)pval = it->size; else *pval = NULL; -} + } diff --git a/src/lib/libcrypto/asn1/tasn_typ.c b/src/lib/libcrypto/asn1/tasn_typ.c index 804d2eeba2..6f17f1bec7 100644 --- a/src/lib/libcrypto/asn1/tasn_typ.c +++ b/src/lib/libcrypto/asn1/tasn_typ.c @@ -131,3 +131,7 @@ IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) + +/* Special, OCTET STRING with indefinite length constructed support */ + +IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) diff --git a/src/lib/libcrypto/asn1/tasn_utl.c b/src/lib/libcrypto/asn1/tasn_utl.c index 8996ce8c13..34d520b180 100644 --- a/src/lib/libcrypto/asn1/tasn_utl.c +++ b/src/lib/libcrypto/asn1/tasn_utl.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,23 +74,23 @@ */ int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { int *sel = offset2ptr(*pval, it->utype); return *sel; -} + } /* Given an ASN1_ITEM CHOICE type set * the selector value, return old value. */ int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it) -{ + { int *sel, ret; sel = offset2ptr(*pval, it->utype); ret = *sel; *sel = value; return ret; -} + } /* Do reference counting. The value 'op' decides what to do. * if it is +1 then the count is incremented. If op is 0 count is @@ -99,114 +99,134 @@ int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it) */ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) -{ + { const ASN1_AUX *aux; int *lck, ret; - if(it->itype != ASN1_ITYPE_SEQUENCE) return 0; + if ((it->itype != ASN1_ITYPE_SEQUENCE) + && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) + return 0; aux = it->funcs; - if(!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) return 0; + if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) + return 0; lck = offset2ptr(*pval, aux->ref_offset); - if(op == 0) { + if (op == 0) + { *lck = 1; return 1; - } + } ret = CRYPTO_add(lck, op, aux->ref_lock); #ifdef REF_PRINT fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck); #endif #ifdef REF_CHECK - if(ret < 0) + if (ret < 0) fprintf(stderr, "%s, bad reference count\n", it->sname); #endif return ret; -} + } static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { const ASN1_AUX *aux; - if(!pval || !*pval) return NULL; + if (!pval || !*pval) + return NULL; aux = it->funcs; - if(!aux || !(aux->flags & ASN1_AFLG_ENCODING)) return NULL; + if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) + return NULL; return offset2ptr(*pval, aux->enc_offset); -} + } void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); - if(enc) { + if (enc) + { enc->enc = NULL; enc->len = 0; enc->modified = 1; + } } -} void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ + { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); - if(enc) { - if(enc->enc) OPENSSL_free(enc->enc); + if (enc) + { + if (enc->enc) + OPENSSL_free(enc->enc); enc->enc = NULL; enc->len = 0; enc->modified = 1; + } } -} -int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it) -{ +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it) + { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); - if(!enc) return 1; + if (!enc) + return 1; - if(enc->enc) OPENSSL_free(enc->enc); + if (enc->enc) + OPENSSL_free(enc->enc); enc->enc = OPENSSL_malloc(inlen); - if(!enc->enc) return 0; + if (!enc->enc) + return 0; memcpy(enc->enc, in, inlen); enc->len = inlen; enc->modified = 0; return 1; -} + } -int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it) -{ +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it) + { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); - if(!enc || enc->modified) return 0; - if(out) { + if (!enc || enc->modified) + return 0; + if (out) + { memcpy(*out, enc->enc, enc->len); *out += enc->len; - } - if(len) *len = enc->len; + } + if (len) + *len = enc->len; return 1; -} + } /* Given an ASN1_TEMPLATE get a pointer to a field */ ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ + { ASN1_VALUE **pvaltmp; - if(tt->flags & ASN1_TFLG_COMBINE) return pval; + if (tt->flags & ASN1_TFLG_COMBINE) + return pval; pvaltmp = offset2ptr(*pval, tt->offset); /* NOTE for BOOLEAN types the field is just a plain * int so we can't return int **, so settle for * (int *). */ return pvaltmp; -} + } /* Handle ANY DEFINED BY template, find the selector, look up * the relevant ASN1_TEMPLATE in the table and return it. */ -const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr) -{ +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr) + { const ASN1_ADB *adb; const ASN1_ADB_TABLE *atbl; long selector; ASN1_VALUE **sfld; int i; - if(!(tt->flags & ASN1_TFLG_ADB_MASK)) return tt; + if (!(tt->flags & ASN1_TFLG_ADB_MASK)) + return tt; /* Else ANY DEFINED BY ... get the table */ adb = ASN1_ADB_ptr(tt->item); @@ -215,16 +235,18 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int sfld = offset2ptr(*pval, adb->offset); /* Check if NULL */ - if(!sfld) { - if(!adb->null_tt) goto err; + if (!sfld) + { + if (!adb->null_tt) + goto err; return adb->null_tt; - } + } /* Convert type to a long: * NB: don't check for NID_undef here because it * might be a legitimate value in the table */ - if(tt->flags & ASN1_TFLG_ADB_OID) + if (tt->flags & ASN1_TFLG_ADB_OID) selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); else selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); @@ -237,17 +259,21 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int * linear search. */ - for(atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) - if(atbl->value == selector) return &atbl->tt; + for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) + if (atbl->value == selector) + return &atbl->tt; /* FIXME: need to search application table too */ /* No match, return default type */ - if(!adb->default_tt) goto err; + if (!adb->default_tt) + goto err; return adb->default_tt; err: /* FIXME: should log the value or OID of unsupported type */ - if(nullerr) ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + if (nullerr) + ASN1err(ASN1_F_ASN1_DO_ADB, + ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); return NULL; -} + } diff --git a/src/lib/libcrypto/asn1/x_algor.c b/src/lib/libcrypto/asn1/x_algor.c index 00b9ea54a1..33533aba86 100644 --- a/src/lib/libcrypto/asn1/x_algor.c +++ b/src/lib/libcrypto/asn1/x_algor.c @@ -66,8 +66,65 @@ ASN1_SEQUENCE(X509_ALGOR) = { ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) } ASN1_SEQUENCE_END(X509_ALGOR) +ASN1_ITEM_TEMPLATE(X509_ALGORS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) +ASN1_ITEM_TEMPLATE_END(X509_ALGORS) + IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) IMPLEMENT_STACK_OF(X509_ALGOR) IMPLEMENT_ASN1_SET_OF(X509_ALGOR) + +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) + { + if (!alg) + return 0; + if (ptype != V_ASN1_UNDEF) + { + if (alg->parameter == NULL) + alg->parameter = ASN1_TYPE_new(); + if (alg->parameter == NULL) + return 0; + } + if (alg) + { + if (alg->algorithm) + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = aobj; + } + if (ptype == 0) + return 1; + if (ptype == V_ASN1_UNDEF) + { + if (alg->parameter) + { + ASN1_TYPE_free(alg->parameter); + alg->parameter = NULL; + } + } + else + ASN1_TYPE_set(alg->parameter, ptype, pval); + return 1; + } + +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor) + { + if (paobj) + *paobj = algor->algorithm; + if (pptype) + { + if (algor->parameter == NULL) + { + *pptype = V_ASN1_UNDEF; + return; + } + else + *pptype = algor->parameter->type; + if (ppval) + *ppval = algor->parameter->value.ptr; + } + } + diff --git a/src/lib/libcrypto/asn1/x_bignum.c b/src/lib/libcrypto/asn1/x_bignum.c index 848c7a0877..869c05d931 100644 --- a/src/lib/libcrypto/asn1/x_bignum.c +++ b/src/lib/libcrypto/asn1/x_bignum.c @@ -59,6 +59,7 @@ #include #include "cryptlib.h" #include +#include /* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a * BIGNUM directly. Currently it ignores the sign which isn't a problem since all @@ -72,7 +73,7 @@ static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); -static int bn_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); static ASN1_PRIMITIVE_FUNCS bignum_pf = { NULL, 0, @@ -122,7 +123,8 @@ static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN return pad + BN_num_bytes(bn); } -static int bn_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) { BIGNUM *bn; if(!*pval) bn_new(pval, it); diff --git a/src/lib/libcrypto/asn1/x_crl.c b/src/lib/libcrypto/asn1/x_crl.c index b99f8fc522..70d56a67f2 100644 --- a/src/lib/libcrypto/asn1/x_crl.c +++ b/src/lib/libcrypto/asn1/x_crl.c @@ -84,7 +84,7 @@ static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) * would affect the output of X509_CRL_print(). */ case ASN1_OP_D2I_POST: - sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp); + (void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp); break; } return 1; diff --git a/src/lib/libcrypto/asn1/x_exten.c b/src/lib/libcrypto/asn1/x_exten.c index 702421b6c8..1732e66712 100644 --- a/src/lib/libcrypto/asn1/x_exten.c +++ b/src/lib/libcrypto/asn1/x_exten.c @@ -67,5 +67,10 @@ ASN1_SEQUENCE(X509_EXTENSION) = { ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) } ASN1_SEQUENCE_END(X509_EXTENSION) +ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) +ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) + IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) diff --git a/src/lib/libcrypto/asn1/x_long.c b/src/lib/libcrypto/asn1/x_long.c index c5f25956cb..0db233cb95 100644 --- a/src/lib/libcrypto/asn1/x_long.c +++ b/src/lib/libcrypto/asn1/x_long.c @@ -59,6 +59,7 @@ #include #include "cryptlib.h" #include +#include /* Custom primitive type for long handling. This converts between an ASN1_INTEGER * and a long directly. @@ -69,7 +70,7 @@ static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); -static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); static ASN1_PRIMITIVE_FUNCS long_pf = { NULL, 0, @@ -136,13 +137,14 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const A return clen + pad; } -static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) { int neg, i; long ltmp; unsigned long utmp = 0; char *cp = (char *)pval; - if(len > sizeof(long)) { + if(len > (int)sizeof(long)) { ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); return 0; } diff --git a/src/lib/libcrypto/asn1/x_name.c b/src/lib/libcrypto/asn1/x_name.c index 31f3377b64..04380abc3f 100644 --- a/src/lib/libcrypto/asn1/x_name.c +++ b/src/lib/libcrypto/asn1/x_name.c @@ -61,7 +61,7 @@ #include #include -static int x509_name_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it, +static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); @@ -123,7 +123,7 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) return 1; memerr: - ASN1err(ASN1_F_X509_NAME_NEW, ERR_R_MALLOC_FAILURE); + ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); if (ret) { if (ret->entries) @@ -156,48 +156,48 @@ static void sk_internal_free(void *a) sk_free(a); } -static int x509_name_ex_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it, +static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) { - unsigned char *p = *in, *q; - STACK *intname = NULL, **intname_pp = &intname; + const unsigned char *p = *in, *q; + union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; + union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; int i, j, ret; - X509_NAME *nm = NULL, **nm_pp = &nm; STACK_OF(X509_NAME_ENTRY) *entries; X509_NAME_ENTRY *entry; q = p; /* Get internal representation of Name */ - ret = ASN1_item_ex_d2i((ASN1_VALUE **)intname_pp, + ret = ASN1_item_ex_d2i(&intname.a, &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), tag, aclass, opt, ctx); if(ret <= 0) return ret; if(*val) x509_name_ex_free(val, NULL); - if(!x509_name_ex_new((ASN1_VALUE **)nm_pp, NULL)) goto err; + if(!x509_name_ex_new(&nm.a, NULL)) goto err; /* We've decoded it: now cache encoding */ - if(!BUF_MEM_grow(nm->bytes, p - q)) goto err; - memcpy(nm->bytes->data, q, p - q); + if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err; + memcpy(nm.x->bytes->data, q, p - q); /* Convert internal representation to X509_NAME structure */ - for(i = 0; i < sk_num(intname); i++) { - entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname, i); + for(i = 0; i < sk_num(intname.s); i++) { + entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i); for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { entry = sk_X509_NAME_ENTRY_value(entries, j); entry->set = i; - if(!sk_X509_NAME_ENTRY_push(nm->entries, entry)) + if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) goto err; } sk_X509_NAME_ENTRY_free(entries); } - sk_free(intname); - nm->modified = 0; - *val = (ASN1_VALUE *)nm; + sk_free(intname.s); + nm.x->modified = 0; + *val = nm.a; *in = p; return ret; err: - ASN1err(ASN1_F_D2I_X509_NAME, ERR_R_NESTED_ASN1_ERROR); + ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); return 0; } @@ -219,36 +219,36 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT static int x509_name_encode(X509_NAME *a) { - STACK *intname = NULL, **intname_pp = &intname; + union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; int len; unsigned char *p; STACK_OF(X509_NAME_ENTRY) *entries = NULL; X509_NAME_ENTRY *entry; int i, set = -1; - intname = sk_new_null(); - if(!intname) goto memerr; + intname.s = sk_new_null(); + if(!intname.s) goto memerr; for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { entry = sk_X509_NAME_ENTRY_value(a->entries, i); if(entry->set != set) { entries = sk_X509_NAME_ENTRY_new_null(); if(!entries) goto memerr; - if(!sk_push(intname, (char *)entries)) goto memerr; + if(!sk_push(intname.s, (char *)entries)) goto memerr; set = entry->set; } if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; } - len = ASN1_item_ex_i2d((ASN1_VALUE **)intname_pp, NULL, + len = ASN1_item_ex_i2d(&intname.a, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); if (!BUF_MEM_grow(a->bytes,len)) goto memerr; p=(unsigned char *)a->bytes->data; - ASN1_item_ex_i2d((ASN1_VALUE **)intname_pp, + ASN1_item_ex_i2d(&intname.a, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - sk_pop_free(intname, sk_internal_free); + sk_pop_free(intname.s, sk_internal_free); a->modified = 0; return len; memerr: - sk_pop_free(intname, sk_internal_free); - ASN1err(ASN1_F_D2I_X509_NAME, ERR_R_MALLOC_FAILURE); + sk_pop_free(intname.s, sk_internal_free); + ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); return -1; } diff --git a/src/lib/libcrypto/asn1/x_pkey.c b/src/lib/libcrypto/asn1/x_pkey.c index f1c6221ac3..8453618426 100644 --- a/src/lib/libcrypto/asn1/x_pkey.c +++ b/src/lib/libcrypto/asn1/x_pkey.c @@ -69,15 +69,15 @@ int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp) return(0); } -X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, unsigned char **pp, long length) +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length) { int i; M_ASN1_D2I_vars(a,X509_PKEY *,X509_PKEY_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get(ret->enc_algor,d2i_X509_ALGOR); - M_ASN1_D2I_get(ret->enc_pkey,d2i_ASN1_OCTET_STRING); + M_ASN1_D2I_get_x(X509_ALGOR,ret->enc_algor,d2i_X509_ALGOR); + M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->enc_pkey,d2i_ASN1_OCTET_STRING); ret->cipher.cipher=EVP_get_cipherbyname( OBJ_nid2ln(OBJ_obj2nid(ret->enc_algor->algorithm))); diff --git a/src/lib/libcrypto/asn1/x_pubkey.c b/src/lib/libcrypto/asn1/x_pubkey.c index 7d6d71af88..91c2756116 100644 --- a/src/lib/libcrypto/asn1/x_pubkey.c +++ b/src/lib/libcrypto/asn1/x_pubkey.c @@ -60,16 +60,23 @@ #include "cryptlib.h" #include #include +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif /* Minor tweak to operation: free up EVP_PKEY */ static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - if(operation == ASN1_OP_FREE_POST) { + { + if (operation == ASN1_OP_FREE_POST) + { X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; EVP_PKEY_free(pubkey->pkey); - } + } return 1; -} + } ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), @@ -111,13 +118,12 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) a->parameter->type=V_ASN1_NULL; } } - else #ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) + else if (pkey->type == EVP_PKEY_DSA) { unsigned char *pp; DSA *dsa; - + dsa=pkey->pkey.dsa; dsa->write_params=0; ASN1_TYPE_free(a->parameter); @@ -151,8 +157,64 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) } OPENSSL_free(p); } - else #endif +#ifndef OPENSSL_NO_EC + else if (pkey->type == EVP_PKEY_EC) + { + int nid=0; + unsigned char *pp; + EC_KEY *ec_key; + const EC_GROUP *group; + + ec_key = pkey->pkey.ec; + ASN1_TYPE_free(a->parameter); + + if ((a->parameter = ASN1_TYPE_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); + goto err; + } + + group = EC_KEY_get0_group(ec_key); + if (EC_GROUP_get_asn1_flag(group) + && (nid = EC_GROUP_get_curve_name(group))) + { + /* just set the OID */ + a->parameter->type = V_ASN1_OBJECT; + a->parameter->value.object = OBJ_nid2obj(nid); + } + else /* explicit parameters */ + { + if ((i = i2d_ECParameters(ec_key, NULL)) == 0) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); + goto err; + } + if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE); + goto err; + } + pp = p; + if (!i2d_ECParameters(ec_key, &pp)) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); + OPENSSL_free(p); + goto err; + } + a->parameter->type = V_ASN1_SEQUENCE; + if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); + OPENSSL_free(p); + goto err; + } + ASN1_STRING_set(a->parameter->value.sequence, p, i); + OPENSSL_free(p); + } + } +#endif + else if (1) { X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); goto err; @@ -171,7 +233,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } - /* Set number of unused bits to zero */ + /* Set number of unused bits to zero */ pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; @@ -198,8 +260,8 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) EVP_PKEY *ret=NULL; long j; int type; - unsigned char *p; -#ifndef OPENSSL_NO_DSA + const unsigned char *p; +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) const unsigned char *cp; X509_ALGOR *a; #endif @@ -207,40 +269,106 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) if (key == NULL) goto err; if (key->pkey != NULL) - { - CRYPTO_add(&key->pkey->references,1,CRYPTO_LOCK_EVP_PKEY); - return(key->pkey); - } + { + CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + return(key->pkey); + } if (key->public_key == NULL) goto err; type=OBJ_obj2nid(key->algor->algorithm); - p=key->public_key->data; - j=key->public_key->length; - if ((ret=d2i_PublicKey(type,NULL,&p,(long)j)) == NULL) + if ((ret = EVP_PKEY_new()) == NULL) { - X509err(X509_F_X509_PUBKEY_GET,X509_R_ERR_ASN1_LIB); + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } - ret->save_parameters=0; + ret->type = EVP_PKEY_type(type); -#ifndef OPENSSL_NO_DSA + /* the parameters must be extracted before the public key (ECDSA!) */ + +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) a=key->algor; - if (ret->type == EVP_PKEY_DSA) +#endif + + if (0) + ; +#ifndef OPENSSL_NO_DSA + else if (ret->type == EVP_PKEY_DSA) { if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { + if ((ret->pkey.dsa = DSA_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); + goto err; + } ret->pkey.dsa->write_params=0; cp=p=a->parameter->value.sequence->data; j=a->parameter->value.sequence->length; - if (!d2i_DSAparams(&ret->pkey.dsa,&cp,(long)j)) + if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j)) goto err; } ret->save_parameters=1; } #endif - key->pkey=ret; - CRYPTO_add(&ret->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifndef OPENSSL_NO_EC + else if (ret->type == EVP_PKEY_EC) + { + if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) + { + /* type == V_ASN1_SEQUENCE => we have explicit parameters + * (e.g. parameters in the X9_62_EC_PARAMETERS-structure ) + */ + if ((ret->pkey.ec= EC_KEY_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_GET, + ERR_R_MALLOC_FAILURE); + goto err; + } + cp = p = a->parameter->value.sequence->data; + j = a->parameter->value.sequence->length; + if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j)) + { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB); + goto err; + } + } + else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT)) + { + /* type == V_ASN1_OBJECT => the parameters are given + * by an asn1 OID + */ + EC_KEY *ec_key; + EC_GROUP *group; + + if (ret->pkey.ec == NULL) + ret->pkey.ec = EC_KEY_new(); + ec_key = ret->pkey.ec; + if (ec_key == NULL) + goto err; + group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); + if (group == NULL) + goto err; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(ec_key, group) == 0) + goto err; + EC_GROUP_free(group); + } + /* the case implicitlyCA is currently not implemented */ + ret->save_parameters = 1; + } +#endif + + p=key->public_key->data; + j=key->public_key->length; + if (!d2i_PublicKey(type, &ret, &p, (long)j)) + { + X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); + goto err; + } + + key->pkey = ret; + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); return(ret); err: if (ret != NULL) @@ -252,9 +380,9 @@ err: * and encode or decode as X509_PUBKEY */ -EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp, +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) -{ + { X509_PUBKEY *xpk; EVP_PKEY *pktmp; xpk = d2i_X509_PUBKEY(NULL, pp, length); @@ -262,15 +390,16 @@ EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp, pktmp = X509_PUBKEY_get(xpk); X509_PUBKEY_free(xpk); if(!pktmp) return NULL; - if(a) { + if(a) + { EVP_PKEY_free(*a); *a = pktmp; - } + } return pktmp; -} + } int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) -{ + { X509_PUBKEY *xpk=NULL; int ret; if(!a) return 0; @@ -278,83 +407,125 @@ int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) ret = i2d_X509_PUBKEY(xpk, pp); X509_PUBKEY_free(xpk); return ret; -} + } /* The following are equivalents but which return RSA and DSA * keys */ #ifndef OPENSSL_NO_RSA -RSA *d2i_RSA_PUBKEY(RSA **a, unsigned char **pp, +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) -{ + { EVP_PKEY *pkey; RSA *key; - unsigned char *q; + const unsigned char *q; q = *pp; pkey = d2i_PUBKEY(NULL, &q, length); - if(!pkey) return NULL; + if (!pkey) return NULL; key = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); - if(!key) return NULL; + if (!key) return NULL; *pp = q; - if(a) { + if (a) + { RSA_free(*a); *a = key; - } + } return key; -} + } int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) -{ + { EVP_PKEY *pktmp; int ret; - if(!a) return 0; + if (!a) return 0; pktmp = EVP_PKEY_new(); - if(!pktmp) { + if (!pktmp) + { ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); return 0; - } + } EVP_PKEY_set1_RSA(pktmp, a); ret = i2d_PUBKEY(pktmp, pp); EVP_PKEY_free(pktmp); return ret; -} + } #endif #ifndef OPENSSL_NO_DSA -DSA *d2i_DSA_PUBKEY(DSA **a, unsigned char **pp, +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) -{ + { EVP_PKEY *pkey; DSA *key; - unsigned char *q; + const unsigned char *q; q = *pp; pkey = d2i_PUBKEY(NULL, &q, length); - if(!pkey) return NULL; + if (!pkey) return NULL; key = EVP_PKEY_get1_DSA(pkey); EVP_PKEY_free(pkey); - if(!key) return NULL; + if (!key) return NULL; *pp = q; - if(a) { + if (a) + { DSA_free(*a); *a = key; - } + } return key; -} + } int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) -{ + { EVP_PKEY *pktmp; int ret; if(!a) return 0; pktmp = EVP_PKEY_new(); - if(!pktmp) { + if(!pktmp) + { ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); return 0; - } + } EVP_PKEY_set1_DSA(pktmp, a); ret = i2d_PUBKEY(pktmp, pp); EVP_PKEY_free(pktmp); return ret; -} + } +#endif + +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) + { + EVP_PKEY *pkey; + EC_KEY *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) return(NULL); + key = EVP_PKEY_get1_EC_KEY(pkey); + EVP_PKEY_free(pkey); + if (!key) return(NULL); + *pp = q; + if (a) + { + EC_KEY_free(*a); + *a = key; + } + return(key); + } + +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) + { + EVP_PKEY *pktmp; + int ret; + if (!a) return(0); + if ((pktmp = EVP_PKEY_new()) == NULL) + { + ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); + return(0); + } + EVP_PKEY_set1_EC_KEY(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return(ret); + } #endif diff --git a/src/lib/libcrypto/asn1/x_req.c b/src/lib/libcrypto/asn1/x_req.c index b3f18ebc12..59ca8ce329 100644 --- a/src/lib/libcrypto/asn1/x_req.c +++ b/src/lib/libcrypto/asn1/x_req.c @@ -102,7 +102,7 @@ ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) -ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_INFO) = { +ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = { ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) diff --git a/src/lib/libcrypto/asn1/x_x509.c b/src/lib/libcrypto/asn1/x_x509.c index b50167ce43..e118696625 100644 --- a/src/lib/libcrypto/asn1/x_x509.c +++ b/src/lib/libcrypto/asn1/x_x509.c @@ -79,6 +79,8 @@ ASN1_SEQUENCE(X509_CINF) = { IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) /* X509 top level structure needs a bit of customisation */ +extern void policy_cache_free(X509_POLICY_CACHE *cache); + static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) { X509 *ret = (X509 *)*pval; @@ -92,6 +94,10 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) ret->ex_pathlen = -1; ret->skid = NULL; ret->akid = NULL; +#ifndef OPENSSL_NO_RFC3779 + ret->rfc3779_addr = NULL; + ret->rfc3779_asid = NULL; +#endif ret->aux = NULL; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); break; @@ -106,6 +112,11 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) X509_CERT_AUX_free(ret->aux); ASN1_OCTET_STRING_free(ret->skid); AUTHORITY_KEYID_free(ret->akid); + policy_cache_free(ret->policy_cache); +#ifndef OPENSSL_NO_RFC3779 + sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); + ASIdentifiers_free(ret->rfc3779_asid); +#endif if (ret->name != NULL) OPENSSL_free(ret->name); break; @@ -125,11 +136,13 @@ ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { IMPLEMENT_ASN1_FUNCTIONS(X509) IMPLEMENT_ASN1_DUP_FUNCTION(X509) -static ASN1_METHOD meth={ - (int (*)()) i2d_X509, - (char *(*)())d2i_X509, - (char *(*)())X509_new, - (void (*)()) X509_free}; +static ASN1_METHOD meth= + { + (I2D_OF(void)) i2d_X509, + (D2I_OF(void)) d2i_X509, + (void *(*)(void))X509_new, + (void (*)(void *)) X509_free + }; ASN1_METHOD *X509_asn1_meth(void) { @@ -161,9 +174,9 @@ void *X509_get_ex_data(X509 *r, int idx) * */ -X509 *d2i_X509_AUX(X509 **a, unsigned char **pp, long length) +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) { - unsigned char *q; + const unsigned char *q; X509 *ret; /* Save start position */ q = *pp; diff --git a/src/lib/libcrypto/asn1/x_x509a.c b/src/lib/libcrypto/asn1/x_x509a.c index f244768b7e..13db5fd03f 100644 --- a/src/lib/libcrypto/asn1/x_x509a.c +++ b/src/lib/libcrypto/asn1/x_x509a.c @@ -91,6 +91,14 @@ static X509_CERT_AUX *aux_get(X509 *x) int X509_alias_set1(X509 *x, unsigned char *name, int len) { X509_CERT_AUX *aux; + if (!name) + { + if (!x || !x->aux || !x->aux->alias) + return 1; + ASN1_UTF8STRING_free(x->aux->alias); + x->aux->alias = NULL; + return 1; + } if(!(aux = aux_get(x))) return 0; if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0; return ASN1_STRING_set(aux->alias, name, len); @@ -99,6 +107,14 @@ int X509_alias_set1(X509 *x, unsigned char *name, int len) int X509_keyid_set1(X509 *x, unsigned char *id, int len) { X509_CERT_AUX *aux; + if (!id) + { + if (!x || !x->aux || !x->aux->keyid) + return 1; + ASN1_OCTET_STRING_free(x->aux->keyid); + x->aux->keyid = NULL; + return 1; + } if(!(aux = aux_get(x))) return 0; if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0; return ASN1_STRING_set(aux->keyid, id, len); @@ -111,6 +127,13 @@ unsigned char *X509_alias_get0(X509 *x, int *len) return x->aux->alias->data; } +unsigned char *X509_keyid_get0(X509 *x, int *len) +{ + if(!x->aux || !x->aux->keyid) return NULL; + if(len) *len = x->aux->keyid->length; + return x->aux->keyid->data; +} + int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) { X509_CERT_AUX *aux; @@ -149,3 +172,9 @@ void X509_reject_clear(X509 *x) } } +ASN1_SEQUENCE(X509_CERT_PAIR) = { + ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0), + ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1) +} ASN1_SEQUENCE_END(X509_CERT_PAIR) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR) -- cgit v1.2.3-55-g6feb