From 6120f03173820333f41fd7e56a1cb109d7548cfe Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 1 Jun 2012 11:57:03 -0700 Subject: [PATCH] ocsp response date checking --- ctaocrypt/src/asn.c | 13 +++++++------ cyassl/ctaocrypt/asn.h | 5 +++-- src/ocsp.c | 44 +++++++++++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 546ca4f70..d12a47a86 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4232,6 +4232,8 @@ static int DecodeSingleResponse(byte* source, if (GetBasicDate(source, &index, cs->thisDate, &cs->thisDateFormat, size) < 0) return ASN_PARSE_E; + if (!ValidateDate(cs->thisDate, cs->thisDateFormat, BEFORE)) + return ASN_BEFORE_DATE_E; /* The following items are optional. Only check for them if there is more * unprocessed data in the singleResponse wrapper. */ @@ -4361,11 +4363,11 @@ static int DecodeResponseData(byte* source, return ASN_PARSE_E; /* save pointer to the producedAt time */ - if (source[idx++] != ASN_GENERALIZED_TIME) + if (GetBasicDate(source, &idx, resp->producedDate, + &resp->producedDateFormat, size) < 0) return ASN_PARSE_E; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - resp->producedAt = source + idx; + if (!ValidateDate(resp->producedDate, resp->producedDateFormat, BEFORE)) + return ASN_BEFORE_DATE_E; idx += length; if (DecodeSingleResponse(source, &idx, resp, size) < 0) @@ -4481,8 +4483,7 @@ void InitOcspResponse(OcspResponse* resp, CertStatus* status, resp->responseStatus = -1; resp->response = NULL; resp->responseSz = 0; - resp->producedAt = NULL; - resp->producedAtFormat = 0; + resp->producedDateFormat = 0; resp->issuerHash = NULL; resp->issuerKeyHash = NULL; resp->sig = NULL; diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 7db5f7d1f..0e574a418 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -378,8 +378,9 @@ struct OcspResponse { byte* response; /* Pointer to beginning of OCSP Response */ word32 responseSz; /* length of the OCSP Response */ - byte* producedAt; /* Time at which this response was signed */ - byte producedAtFormat;/* format of the producedAt date */ + byte producedDate[MAX_DATE_SIZE]; + /* Date at which this response was signed */ + byte producedDateFormat; /* format of the producedDate */ byte* issuerHash; byte* issuerKeyHash; diff --git a/src/ocsp.c b/src/ocsp.c index 464d67eac..3b3dea968 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -361,6 +361,7 @@ static CertStatus* find_cert_status(OCSP_Entry* ocspe, DecodedCert* cert) XMEMCPY(stat->serial, cert->serial, cert->serialSz); stat->serialSz = cert->serialSz; stat->status = -1; + stat->nextDate[0] = 0; ocspe->totalStatus++; stat->next = ocspe->status; @@ -427,6 +428,22 @@ static int http_ocsp_transaction(CYASSL_OCSP* ocsp, DecodedCert* cert, } +static int xstat2err(int stat) +{ + switch (stat) { + case CERT_GOOD: + return 0; + break; + case CERT_REVOKED: + return OCSP_CERT_REVOKED; + break; + default: + return OCSP_CERT_UNKNOWN; + break; + } +} + + int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) { byte ocspReqBuf[SCRATCH_BUFFER_SIZE]; @@ -460,6 +477,21 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) if (certStatus->status != -1) { + if (!ValidateDate(certStatus->thisDate, + certStatus->thisDateFormat, BEFORE) || + (certStatus->nextDate[0] == 0) || + !ValidateDate(certStatus->nextDate, + certStatus->nextDateFormat, AFTER)) + { + CYASSL_MSG("\tinvalid status date, looking up cert"); + certStatus->status = -1; + } + else + { + CYASSL_MSG("\tusing cached status"); + result = xstat2err(certStatus->status); + return result; + } } InitOcspRequest(&ocspRequest, cert, ocspReqBuf, ocspReqSz); @@ -478,17 +510,7 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) } else { if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) { - switch (ocspResponse.status[0].status) { - case CERT_GOOD: - result = 0; - break; - case CERT_REVOKED: - result = OCSP_CERT_REVOKED; - break; - default: - result = OCSP_CERT_UNKNOWN; - break; - } + result = xstat2err(ocspResponse.status->status); } else {