X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fa_gentm.c;h=2f72d4877cd374b76768985570c62d81bbec5757;hp=185d16960038772b84e1ef1a9c6bd16880664ccb;hb=359b0c9fb8ccb5f492cc918f7e4c6319e15af16b;hpb=bc36ee6227517edae802bcb0da68d4f04fe1fb5e diff --git a/crypto/asn1/a_gentm.c b/crypto/asn1/a_gentm.c index 185d169600..2f72d4877c 100644 --- a/crypto/asn1/a_gentm.c +++ b/crypto/asn1/a_gentm.c @@ -61,6 +61,7 @@ #include #include #include "cryptlib.h" +#include "o_time.h" #include #if 0 @@ -114,10 +115,10 @@ err: #endif -int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) { - static int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0}; - static int max[9]={99, 99,12,31,23,59,59,12,59}; + static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0}; + static const int max[9]={99, 99,12,31,23,59,59,12,59}; char *a; int n,i,l,o; @@ -145,6 +146,19 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) if ((n < min[i]) || (n > max[i])) goto err; } + /* Optional fractional seconds: decimal point followed by one + * or more digits. + */ + if (a[o] == '.') + { + if (++o > l) goto err; + i = o; + while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) + o++; + /* Must have at least one digit after decimal point */ + if (i == o) goto err; + } + if (a[o] == 'Z') o++; else if ((a[o] == '+') || (a[o] == '-')) @@ -162,12 +176,17 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) o++; } } + else + { + /* Missing time zone information. */ + goto err; + } return(o == l); 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; @@ -178,8 +197,9 @@ int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, char *str) { if (s != NULL) { - ASN1_STRING_set((ASN1_STRING *)s, - (unsigned char *)str,t.length); + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str,t.length)) + return 0; s->type=V_ASN1_GENERALIZEDTIME; } return(1); @@ -190,36 +210,50 @@ int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, char *str) ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t) + { + return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); + } + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, long offset_sec) { char *p; struct tm *ts; -#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) struct tm data; -#endif + size_t len = 20; if (s == NULL) s=M_ASN1_GENERALIZEDTIME_new(); if (s == NULL) return(NULL); -#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) - gmtime_r(&t,&data); /* should return &data, but doesn't on some systems, so we don't even look at the return value */ - ts=&data; -#else - ts=gmtime(&t); -#endif + ts=OPENSSL_gmtime(&t, &data); + if (ts == NULL) + return(NULL); + + if (offset_day || offset_sec) + { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + p=(char *)s->data; - if ((p == NULL) || (s->length < 16)) + if ((p == NULL) || ((size_t)s->length < len)) { - p=OPENSSL_malloc(20); - if (p == NULL) return(NULL); + p=OPENSSL_malloc(len); + if (p == NULL) + { + ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, + ERR_R_MALLOC_FAILURE); + return(NULL); + } if (s->data != NULL) OPENSSL_free(s->data); s->data=(unsigned char *)p; } - sprintf(p,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900, - ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec); + BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900, + ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec); s->length=strlen(p); s->type=V_ASN1_GENERALIZEDTIME; #ifdef CHARSET_EBCDIC_not