From 4e657debfca5fbb469244d53cb14550857c5793d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 19 Dec 2012 10:18:11 -0800 Subject: [PATCH 1/5] added the ability to disable OCSP nonces --- ctaocrypt/src/asn.c | 49 +++++++++++++++++++++++------------------- cyassl/ctaocrypt/asn.h | 4 +++- cyassl/internal.h | 1 + cyassl/ssl.h | 1 + src/ocsp.c | 3 ++- src/ssl.c | 1 + 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 56b420298..f0961cd5d 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4635,7 +4635,6 @@ int EncodeOcspRequest(OcspRequest* req) byte snArray[MAX_SN_SZ]; byte extArray[MAX_OCSP_EXT_SZ]; byte* output = req->dest; - RNG rng; word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; int i; @@ -4653,14 +4652,17 @@ int EncodeOcspRequest(OcspRequest* req) req->serialSz = req->cert->serialSz; snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); - if (InitRng(&rng) != 0) { - CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); - extSz = 0; - } else { - req->nonceSz = MAX_OCSP_NONCE_SZ; - RNG_GenerateBlock(&rng, req->nonce, req->nonceSz); - extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, - req->nonce, req->nonceSz); + if (req->useNonce) { + RNG rng; + if (InitRng(&rng) != 0) { + CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); + extSz = 0; + } else { + req->nonceSz = MAX_OCSP_NONCE_SZ; + RNG_GenerateBlock(&rng, req->nonce, req->nonceSz); + extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, + req->nonce, req->nonceSz); + } } totalSz = algoSz + issuerSz + issuerKeySz + snSz; @@ -4692,12 +4694,13 @@ int EncodeOcspRequest(OcspRequest* req) } -void InitOcspRequest(OcspRequest* req, DecodedCert* cert, +void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, byte* dest, word32 destSz) { CYASSL_ENTER("InitOcspRequest"); req->cert = cert; + req->useNonce = useNonce; req->nonceSz = 0; req->issuerHash = NULL; req->issuerKeyHash = NULL; @@ -4725,18 +4728,20 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) return 1; } - cmp = req->nonceSz - resp->nonceSz; - if (cmp != 0) - { - CYASSL_MSG("\tnonceSz mismatch"); - return cmp; - } - - cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz); - if (cmp != 0) - { - CYASSL_MSG("\tnonce mismatch"); - return cmp; + if (req->useNonce) { + cmp = req->nonceSz - resp->nonceSz; + if (cmp != 0) + { + CYASSL_MSG("\tnonceSz mismatch"); + return cmp; + } + + cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz); + if (cmp != 0) + { + CYASSL_MSG("\tnonce mismatch"); + return cmp; + } } cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE); diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index eab0dd2e3..cc3d8a4f0 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -417,6 +417,7 @@ struct OcspResponse { struct OcspRequest { DecodedCert* cert; + byte useNonce; byte nonce[MAX_OCSP_NONCE_SZ]; int nonceSz; @@ -433,7 +434,8 @@ struct OcspRequest { CYASSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32); CYASSL_LOCAL int OcspResponseDecode(OcspResponse*); -CYASSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*, byte*, word32); +CYASSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*, + byte, byte*, word32); CYASSL_LOCAL int EncodeOcspRequest(OcspRequest*); CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*); diff --git a/cyassl/internal.h b/cyassl/internal.h index 0b989e112..1bce715ef 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -775,6 +775,7 @@ struct OCSP_Entry { struct CYASSL_OCSP { byte enabled; byte useOverrideUrl; + byte useNonce; char overrideName[80]; char overridePath[80]; int overridePort; diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 2bbbfa054..0035e1341 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -885,6 +885,7 @@ CYASSL_API int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX*, const char*); #define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */ #define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL * in certificate */ +#define CYASSL_OCSP_NO_NONCE 0x0004 /* Disables the request nonce. */ #ifdef __cplusplus diff --git a/src/ocsp.c b/src/ocsp.c index 343b98c5b..805353341 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -64,6 +64,7 @@ int CyaSSL_OCSP_Init(CYASSL_OCSP* ocsp) { if (ocsp != NULL) { XMEMSET(ocsp, 0, sizeof(*ocsp)); + ocsp->useNonce = 1; return 0; } @@ -501,7 +502,7 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) } } - InitOcspRequest(&ocspRequest, cert, ocspReqBuf, ocspReqSz); + InitOcspRequest(&ocspRequest, cert, ocsp->useNonce, ocspReqBuf, ocspReqSz); ocspReqSz = EncodeOcspRequest(&ocspRequest); result = http_ocsp_transaction(ocsp, cert, ocspReqBuf, ocspReqSz, &ocspRespBuf); diff --git a/src/ssl.c b/src/ssl.c index 1baa80dab..ef110da2a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8220,6 +8220,7 @@ long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX* ctx, long options) if (ctx != NULL) { ctx->ocsp.enabled = (options & CYASSL_OCSP_ENABLE) != 0; ctx->ocsp.useOverrideUrl = (options & CYASSL_OCSP_URL_OVERRIDE) != 0; + ctx->ocsp.useNonce = (options & CYASSL_OCSP_NO_NONCE) == 0; return 1; } return 0; From 26cf98c878797888014ec81a41e647bbdb1aa2f5 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 19 Dec 2012 11:28:33 -0800 Subject: [PATCH 2/5] removed check against producedAt date in ocsp, check not required --- ctaocrypt/src/asn.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index f0961cd5d..1c928cf0b 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4374,8 +4374,6 @@ static int DecodeResponseData(byte* source, if (GetBasicDate(source, &idx, resp->producedDate, &resp->producedDateFormat, size) < 0) return ASN_PARSE_E; - if (!ValidateDate(resp->producedDate, resp->producedDateFormat, BEFORE)) - return ASN_BEFORE_DATE_E; if (DecodeSingleResponse(source, &idx, resp, size) < 0) return ASN_PARSE_E; From 51787db76b754fa802d1c19809ec7cfb528273f0 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 19 Dec 2012 18:09:05 -0800 Subject: [PATCH 3/5] changed ocsp lookup to use dynamic mem for request rather than stack --- src/ocsp.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/ocsp.c b/src/ocsp.c index 805353341..c012f27e5 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -455,7 +455,7 @@ static int xstat2err(int stat) int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) { - byte ocspReqBuf[SCRATCH_BUFFER_SIZE]; + byte* ocspReqBuf = NULL; int ocspReqSz = SCRATCH_BUFFER_SIZE; byte* ocspRespBuf = NULL; OcspRequest ocspRequest; @@ -502,30 +502,37 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) } } + ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER); + if (ocspReqBuf == NULL) { + CYASSL_MSG("\talloc OCSP request buffer failed"); + return MEMORY_ERROR; + } InitOcspRequest(&ocspRequest, cert, ocsp->useNonce, ocspReqBuf, ocspReqSz); ocspReqSz = EncodeOcspRequest(&ocspRequest); result = http_ocsp_transaction(ocsp, cert, ocspReqBuf, ocspReqSz, &ocspRespBuf); - if (result < 0) return result; - /* If the transaction failed, return that result. */ - - InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result); - OcspResponseDecode(&ocspResponse); - - if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) { - CYASSL_MSG("OCSP Responder failure"); - result = OCSP_LOOKUP_FAIL; - } else { - if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) - { - result = xstat2err(ocspResponse.status->status); - } - else - { - CYASSL_MSG("OCSP Response incorrect for Request"); + if (result >= 0) { + InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result); + OcspResponseDecode(&ocspResponse); + + if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) { + CYASSL_MSG("OCSP Responder failure"); result = OCSP_LOOKUP_FAIL; + } else { + if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0) + { + result = xstat2err(ocspResponse.status->status); + } + else + { + CYASSL_MSG("OCSP Response incorrect for Request"); + result = OCSP_LOOKUP_FAIL; + } } } + if (ocspReqBuf != NULL) { + XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); + } if (ocspRespBuf != NULL) { XFREE(ocspRespBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); } From 5164c152162a041ca051a81da8a27c9f8a50e71d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 20 Dec 2012 15:29:15 -0800 Subject: [PATCH 4/5] fixed missed initialization when not using ocsp nonces --- ctaocrypt/src/asn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 1c928cf0b..785e49e50 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4650,11 +4650,11 @@ int EncodeOcspRequest(OcspRequest* req) req->serialSz = req->cert->serialSz; snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); + extSz = 0; if (req->useNonce) { RNG rng; if (InitRng(&rng) != 0) { CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); - extSz = 0; } else { req->nonceSz = MAX_OCSP_NONCE_SZ; RNG_GenerateBlock(&rng, req->nonce, req->nonceSz); From afbc34f0e03bea0ae83c792b7c35a541876b9a97 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 20 Dec 2012 15:56:57 -0800 Subject: [PATCH 5/5] changed polarity on ocsp thisDate check to allow very timely responses --- ctaocrypt/src/asn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 785e49e50..c30263be2 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4240,7 +4240,8 @@ static int DecodeSingleResponse(byte* source, if (GetBasicDate(source, &idx, cs->thisDate, &cs->thisDateFormat, size) < 0) return ASN_PARSE_E; - if (!ValidateDate(cs->thisDate, cs->thisDateFormat, BEFORE)) + /* Check thisDate <= now, or treat thisDate > now as a failure */ + if (ValidateDate(cs->thisDate, cs->thisDateFormat, AFTER)) return ASN_BEFORE_DATE_E; /* The following items are optional. Only check for them if there is more