diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index db1e0e1ec..2d13c95b5 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -1537,7 +1537,7 @@ static INLINE int DateLessThan(const struct tm* a, const struct tm* b) /* like atoi but only use first byte */ /* Make sure before and after dates are valid */ -static int ValidateDate(const byte* date, byte format, int dateType) +int ValidateDate(const byte* date, byte format, int dateType) { time_t ltime; struct tm certTime; @@ -4491,15 +4491,16 @@ static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx) /* Get raw Date only, no processing, 0 on success */ -static int GetBasicDate(const byte* source, word32* idx, byte* date, int maxIdx) +static int GetBasicDate(const byte* source, word32* idx, byte* date, + byte* format, int maxIdx) { int length; - byte b = source[*idx]; CYASSL_ENTER("GetBasicDate"); + *format = source[*idx]; *idx += 1; - if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) + if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME) return ASN_TIME_E; if (GetLength(source, idx, &length, maxIdx) < 0) @@ -4654,12 +4655,17 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz) if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0) return ASN_PARSE_E; - if (GetBasicDate(buff, &idx, dcrl->lastDate, sz) < 0) + if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) return ASN_PARSE_E; - if (GetBasicDate(buff, &idx, dcrl->nextDate, sz) < 0) + if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0) return ASN_PARSE_E; + if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) { + CYASSL_MSG("CRL after date is no longer valid"); + return ASN_AFTER_DATE_E; + } + if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) { if (GetSequence(buff, &idx, &len, sz) < 0) return ASN_PARSE_E; diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index eaf06a794..07379f654 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -295,6 +295,7 @@ CYASSL_LOCAL void FreeSigners(Signer*, void*); CYASSL_LOCAL int ToTraditional(byte* buffer, word32 length); CYASSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*, int); +CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); #ifdef HAVE_ECC /* ASN sig helpers */ @@ -410,6 +411,8 @@ struct DecodedCRL { byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */ byte lastDate[MAX_DATE_SIZE]; /* last date updated */ byte nextDate[MAX_DATE_SIZE]; /* next update date */ + byte lastDateFormat; /* format of last date */ + byte nextDateFormat; /* format of next date */ RevokedCert* certs; /* revoked cert list */ int totalCerts; /* number on list */ }; diff --git a/cyassl/internal.h b/cyassl/internal.h index 5f704a76a..4a37329e8 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -633,6 +633,8 @@ struct CRL_Entry { byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */ byte lastDate[MAX_DATE_SIZE]; /* last date updated */ byte nextDate[MAX_DATE_SIZE]; /* next update date */ + byte lastDateFormat; /* last date format */ + byte nextDateFormat; /* next date format */ RevokedCert* certs; /* revoked cert list */ int totalCerts; /* number on list */ }; diff --git a/src/crl.c b/src/crl.c index 8bf88c59e..46e53a3f0 100644 --- a/src/crl.c +++ b/src/crl.c @@ -61,6 +61,8 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl) XMEMCPY(crle->crlHash, dcrl->crlHash, MD5_DIGEST_SIZE); XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE); XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE); + crle->lastDateFormat = dcrl->lastDateFormat; + crle->nextDateFormat = dcrl->nextDateFormat; crle->certs = dcrl->certs; /* take ownsership */ dcrl->certs = NULL; @@ -119,27 +121,34 @@ void FreeCRL(CYASSL_CRL* crl) /* Is the cert ok with CRL, return 0 on success */ int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert) { - CRL_Entry* crle; - int foundEntry = 0; - int revoked = 0; - int ret = 0; + CRL_Entry* crle; + int foundEntry = 0; + int revoked = 0; + int ret = 0; - CYASSL_ENTER("CheckCertCRL"); + CYASSL_ENTER("CheckCertCRL"); - if (LockMutex(&crl->crlLock) != 0) { - CYASSL_MSG("LockMutex failed"); - return BAD_MUTEX_ERROR; - } + if (LockMutex(&crl->crlLock) != 0) { + CYASSL_MSG("LockMutex failed"); + return BAD_MUTEX_ERROR; + } - crle = crl->crlList; + crle = crl->crlList; while (crle) { if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) { CYASSL_MSG("Found CRL Entry on list"); - foundEntry = 1; - break; + CYASSL_MSG("Checking next date validity"); + + if (!ValidateDate(crle->nextDate, crle->nextDateFormat, AFTER)) { + CYASSL_MSG("CRL next date is no longer valid"); + ret = ASN_AFTER_DATE_E; + } + else + foundEntry = 1; + break; } - crle = crle->next; + crle = crle->next; } if (foundEntry) { @@ -505,7 +514,7 @@ int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor) CYASSL_MSG("opendir path crl load failed"); return BAD_PATH_ERROR; } - while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) { + while ( (entry = readdir(dir)) != NULL) { if (entry->d_type & DT_REG) { char name[MAX_FILENAME_SZ]; @@ -529,7 +538,10 @@ int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor) XSTRNCAT(name, "/", 1); XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2); - ret = ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl); + if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl) + != SSL_SUCCESS) { + CYASSL_MSG("CRL file load failed, continuing"); + } } }