From 284ef5f35710b9fbff82abc20cced66d2dcff7c1 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 26 Jul 2000 01:18:37 +0000 Subject: [PATCH] Make NEG_PUBKEY_BUG on by default. ASN1_TIME fixes. New function c2i_ASN1_OBJECT(). --- CHANGES | 17 +++++++++++++ crypto/asn1/a_object.c | 41 ++++++++++++++++++++++---------- crypto/asn1/asn1.h | 5 ++++ crypto/asn1/d2i_dsap.c | 2 +- crypto/asn1/d2i_r_pu.c | 2 +- crypto/asn1/d2i_s_pu.c | 2 +- crypto/x509/x509.h | 18 +++++++------- crypto/x509/x509_set.c | 16 ++++++------- crypto/x509/x509_vfy.c | 54 +++++++++++++++++++++++++++++------------- 9 files changed, 108 insertions(+), 49 deletions(-) diff --git a/CHANGES b/CHANGES index 16b9c6bb7a..e739139cd9 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,23 @@ Changes between 0.9.5a and 0.9.6 [xx XXX 2000] + *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME. + Also change the functions X509_cmp_current_time() and + X509_gmtime_adj() work with an ASN1_TIME structure, + this will enable certificates using GeneralizedTime in validity + dates to be checked. + [Steve Henson] + + *) Make the NEG_PUBKEY_BUG code (which tolerates invalid + negative public key encodings) on by default, + NO_NEG_PUBKEY_BUG can be set to disable it. + [Steve Henson] + + *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT + content octets. An i2c_ASN1_OBJECT is unnecessary because + the encoding can be trivially obtained from the structure. + [Steve Henson] + *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock), not read locks (CRYPTO_r_[un]lock). [Bodo Moeller] diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index 7e1300021e..3873b98902 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -190,24 +190,13 @@ int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, long length) - { - ASN1_OBJECT *ret=NULL; +{ unsigned char *p; long len; int tag,xclass; int inf,i; - - /* only the ASN1_OBJECTs from the 'table' will have values - * for ->sn or ->ln */ - if ((a == NULL) || ((*a) == NULL) || - !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) - { - if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); - } - else ret=(*a); - + ASN1_OBJECT *ret = NULL; p= *pp; - inf=ASN1_get_object(&p,&len,&tag,&xclass,length); if (inf & 0x80) { @@ -220,6 +209,32 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, i=ASN1_R_EXPECTING_AN_OBJECT; goto err; } + ret = c2i_ASN1_OBJECT(a, &p, len); + if(ret) *pp = p; + return ret; +err: + ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_OBJECT_free(ret); + return(NULL); +} +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, + long len) + { + ASN1_OBJECT *ret=NULL; + unsigned char *p; + int i; + + /* only the ASN1_OBJECTs from the 'table' will have values + * for ->sn or ->ln */ + if ((a == NULL) || ((*a) == NULL) || + !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) + { + if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); + } + else ret=(*a); + + p= *pp; if ((ret->data == NULL) || (ret->length < len)) { if (ret->data != NULL) OPENSSL_free(ret->data); diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index fcce0f6925..79df50a85b 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -237,6 +237,7 @@ DECLARE_STACK_OF(ASN1_STRING_TABLE) #define ASN1_BMPSTRING ASN1_STRING #define ASN1_VISIBLESTRING ASN1_STRING #define ASN1_UTF8STRING ASN1_STRING +#define ASN1_BOOLEAN int #else typedef struct asn1_string_st ASN1_INTEGER; typedef struct asn1_string_st ASN1_ENUMERATED; @@ -253,6 +254,7 @@ typedef struct asn1_string_st ASN1_TIME; typedef struct asn1_string_st ASN1_GENERALIZEDTIME; typedef struct asn1_string_st ASN1_VISIBLESTRING; typedef struct asn1_string_st ASN1_UTF8STRING; +typedef int ASN1_BOOLEAN; #endif typedef int ASN1_NULL; @@ -265,6 +267,7 @@ typedef struct asn1_type_st int type; union { char *ptr; + ASN1_BOOLEAN boolean; ASN1_STRING * asn1_string; ASN1_OBJECT * object; ASN1_INTEGER * integer; @@ -506,6 +509,8 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, 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, + long length); ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,unsigned char **pp, long length); diff --git a/crypto/asn1/d2i_dsap.c b/crypto/asn1/d2i_dsap.c index 6d1c297133..9d4dea6145 100644 --- a/crypto/asn1/d2i_dsap.c +++ b/crypto/asn1/d2i_dsap.c @@ -64,7 +64,7 @@ #include #include -#ifdef NEG_PUBKEY_BUG +#ifndef NO_NEG_PUBKEY_BUG #define d2i_ASN1_INTEGER d2i_ASN1_UINTEGER #endif diff --git a/crypto/asn1/d2i_r_pu.c b/crypto/asn1/d2i_r_pu.c index d1289f160e..9e5d41cf53 100644 --- a/crypto/asn1/d2i_r_pu.c +++ b/crypto/asn1/d2i_r_pu.c @@ -64,7 +64,7 @@ #include #include -#ifdef NEG_PUBKEY_BUG +#ifndef NO_NEG_PUBKEY_BUG #define d2i_ASN1_INTEGER d2i_ASN1_UINTEGER #endif diff --git a/crypto/asn1/d2i_s_pu.c b/crypto/asn1/d2i_s_pu.c index e0adaa0393..0b7d2fafcc 100644 --- a/crypto/asn1/d2i_s_pu.c +++ b/crypto/asn1/d2i_s_pu.c @@ -66,7 +66,7 @@ #include #include -#ifdef NEG_PUBKEY_BUG +#ifndef NO_NEG_PUBKEY_BUG #define d2i_ASN1_INTEGER d2i_ASN1_UINTEGER #endif diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index bbf9a10ad5..7955e5c2c1 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -138,8 +138,8 @@ DECLARE_ASN1_SET_OF(X509_ALGOR) typedef struct X509_val_st { - ASN1_UTCTIME *notBefore; - ASN1_UTCTIME *notAfter; + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; } X509_VAL; typedef struct X509_pubkey_st @@ -323,7 +323,7 @@ DECLARE_STACK_OF(X509_TRUST) typedef struct X509_revoked_st { ASN1_INTEGER *serialNumber; - ASN1_UTCTIME *revocationDate; + ASN1_TIME *revocationDate; STACK_OF(X509_EXTENSION) /* optional */ *extensions; int sequence; /* load sequence */ } X509_REVOKED; @@ -336,8 +336,8 @@ typedef struct X509_crl_info_st ASN1_INTEGER *version; X509_ALGOR *sig_alg; X509_NAME *issuer; - ASN1_UTCTIME *lastUpdate; - ASN1_UTCTIME *nextUpdate; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; STACK_OF(X509_REVOKED) *revoked; STACK_OF(X509_EXTENSION) /* [0] */ *extensions; } X509_CRL_INFO; @@ -737,8 +737,8 @@ RSA *RSAPrivateKey_dup(RSA *rsa); #endif /* !SSLEAY_MACROS */ -int X509_cmp_current_time(ASN1_UTCTIME *s); -ASN1_UTCTIME * X509_gmtime_adj(ASN1_UTCTIME *s, long adj); +int X509_cmp_current_time(ASN1_TIME *s); +ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); const char * X509_get_default_cert_area(void ); const char * X509_get_default_cert_dir(void ); @@ -920,8 +920,8 @@ int X509_set_issuer_name(X509 *x, X509_NAME *name); X509_NAME * X509_get_issuer_name(X509 *a); int X509_set_subject_name(X509 *x, X509_NAME *name); X509_NAME * X509_get_subject_name(X509 *a); -int X509_set_notBefore(X509 *x, ASN1_UTCTIME *tm); -int X509_set_notAfter(X509 *x, ASN1_UTCTIME *tm); +int X509_set_notBefore(X509 *x, ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, ASN1_TIME *tm); int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); EVP_PKEY * X509_get_pubkey(X509 *x); int X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */); diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c index add842d17a..aaf61ca062 100644 --- a/crypto/x509/x509_set.c +++ b/crypto/x509/x509_set.c @@ -104,36 +104,36 @@ int X509_set_subject_name(X509 *x, X509_NAME *name) return(X509_NAME_set(&x->cert_info->subject,name)); } -int X509_set_notBefore(X509 *x, ASN1_UTCTIME *tm) +int X509_set_notBefore(X509 *x, ASN1_TIME *tm) { - ASN1_UTCTIME *in; + ASN1_TIME *in; if ((x == NULL) || (x->cert_info->validity == NULL)) return(0); in=x->cert_info->validity->notBefore; if (in != tm) { - in=M_ASN1_UTCTIME_dup(tm); + in=M_ASN1_TIME_dup(tm); if (in != NULL) { - M_ASN1_UTCTIME_free(x->cert_info->validity->notBefore); + M_ASN1_TIME_free(x->cert_info->validity->notBefore); x->cert_info->validity->notBefore=in; } } return(in != NULL); } -int X509_set_notAfter(X509 *x, ASN1_UTCTIME *tm) +int X509_set_notAfter(X509 *x, ASN1_TIME *tm) { - ASN1_UTCTIME *in; + ASN1_TIME *in; if ((x == NULL) || (x->cert_info->validity == NULL)) return(0); in=x->cert_info->validity->notAfter; if (in != tm) { - in=M_ASN1_UTCTIME_dup(tm); + in=M_ASN1_TIME_dup(tm); if (in != NULL) { - M_ASN1_UTCTIME_free(x->cert_info->validity->notAfter); + M_ASN1_TIME_free(x->cert_info->validity->notAfter); x->cert_info->validity->notAfter=in; } } diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index e9311d5ea8..0d5273d51a 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -502,10 +502,10 @@ end: return(ok); } -int X509_cmp_current_time(ASN1_UTCTIME *ctm) +int X509_cmp_current_time(ASN1_TIME *ctm) { char *str; - ASN1_UTCTIME atm; + ASN1_TIME atm; time_t offset; char buff1[24],buff2[24],*p; int i,j; @@ -513,14 +513,32 @@ int X509_cmp_current_time(ASN1_UTCTIME *ctm) p=buff1; i=ctm->length; str=(char *)ctm->data; - if ((i < 11) || (i > 17)) return(0); - memcpy(p,str,10); - p+=10; - str+=10; + if(ctm->type == V_ASN1_UTCTIME) { + if ((i < 11) || (i > 17)) return(0); + memcpy(p,str,10); + p+=10; + str+=10; + } else { + if(i < 13) return 0; + memcpy(p,str,12); + p+=12; + str+=12; + } if ((*str == 'Z') || (*str == '-') || (*str == '+')) { *(p++)='0'; *(p++)='0'; } - else { *(p++)= *(str++); *(p++)= *(str++); } + else + { + *(p++)= *(str++); + *(p++)= *(str++); + /* Skip any fractional seconds... */ + if(*str == '.') + { + str++; + while((*str >= '0') && (*str <= '9')) str++; + } + + } *(p++)='Z'; *(p++)='\0'; @@ -535,19 +553,22 @@ int X509_cmp_current_time(ASN1_UTCTIME *ctm) if (*str == '-') offset= -offset; } - atm.type=V_ASN1_UTCTIME; + atm.type=ctm->type; atm.length=sizeof(buff2); atm.data=(unsigned char *)buff2; X509_gmtime_adj(&atm,-offset*60); - i=(buff1[0]-'0')*10+(buff1[1]-'0'); - if (i < 50) i+=100; /* cf. RFC 2459 */ - j=(buff2[0]-'0')*10+(buff2[1]-'0'); - if (j < 50) j+=100; + if(ctm->type == V_ASN1_UTCTIME) + { + i=(buff1[0]-'0')*10+(buff1[1]-'0'); + if (i < 50) i+=100; /* cf. RFC 2459 */ + j=(buff2[0]-'0')*10+(buff2[1]-'0'); + if (j < 50) j+=100; - if (i < j) return (-1); - if (i > j) return (1); + if (i < j) return (-1); + if (i > j) return (1); + } i=strcmp(buff1,buff2); if (i == 0) /* wait a second then return younger :-) */ return(-1); @@ -555,13 +576,14 @@ int X509_cmp_current_time(ASN1_UTCTIME *ctm) return(i); } -ASN1_UTCTIME *X509_gmtime_adj(ASN1_UTCTIME *s, long adj) +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) { time_t t; time(&t); t+=adj; - return(ASN1_UTCTIME_set(s,t)); + if(s->type == V_ASN1_UTCTIME) return(ASN1_UTCTIME_set(s,t)); + return ASN1_GENERALIZEDTIME_set(s, t); } int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) -- 2.25.1