From 4e657debfca5fbb469244d53cb14550857c5793d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 19 Dec 2012 10:18:11 -0800 Subject: [PATCH 01/11] 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 02/11] 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 03/11] 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 04/11] 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 05/11] 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 From 5bc976ee0f81e85a83ccd9962058d723527bcf02 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 26 Dec 2012 09:49:53 -0800 Subject: [PATCH 06/11] free ecc keys at the end of handshaking --- src/internal.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index b5b76e16d..bb8062b58 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1312,10 +1312,14 @@ void SSL_ResourceFree(CYASSL* ssl) FreeStreams(ssl); #endif #ifdef HAVE_ECC - ecc_free(&ssl->peerEccKey); - ecc_free(&ssl->peerEccDsaKey); - ecc_free(&ssl->eccTempKey); - ecc_free(&ssl->eccDsaKey); + if (ssl->peerEccKeyPresent) + ecc_free(&ssl->peerEccKey); + if (ssl->peerEccDsaKeyPresent) + ecc_free(&ssl->peerEccDsaKey); + if (ssl->eccTempKeyPresent) + ecc_free(&ssl->eccTempKey); + if (ssl->eccDsaKeyPresent) + ecc_free(&ssl->eccDsaKey); #endif } @@ -1358,6 +1362,25 @@ void FreeHandshakeResources(CYASSL* ssl) ssl->peerRsaKey = NULL; } #endif + +#ifdef HAVE_ECC + if (ssl->peerEccKeyPresent) { + ecc_free(&ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + } + if (ssl->peerEccDsaKeyPresent) { + ecc_free(&ssl->peerEccDsaKey); + ssl->peerEccDsaKeyPresent = 0; + } + if (ssl->eccTempKeyPresent) { + ecc_free(&ssl->eccTempKey); + ssl->eccTempKeyPresent = 0; + } + if (ssl->eccDsaKeyPresent) { + ecc_free(&ssl->eccDsaKey); + ssl->eccDsaKeyPresent = 0; + } +#endif } From cf114b92df02d42a041cc2464447ba3dcac26d0c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 26 Dec 2012 16:39:19 -0800 Subject: [PATCH 07/11] made the ecc keys in the CYASSL struct dynamic --- cyassl/ctaocrypt/types.h | 3 +- cyassl/internal.h | 8 +-- src/internal.c | 141 ++++++++++++++++++++++++++++----------- src/ssl.c | 2 +- 4 files changed, 109 insertions(+), 45 deletions(-) diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index 286280abb..083a87621 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -224,7 +224,8 @@ enum { DYNAMIC_TYPE_ARRAYS = 33, DYNAMIC_TYPE_DTLS_POOL = 34, DYNAMIC_TYPE_SOCKADDR = 35, - DYNAMIC_TYPE_LIBZ = 36 + DYNAMIC_TYPE_LIBZ = 36, + DYNAMIC_TYPE_ECC = 37 }; /* stack protection */ diff --git a/cyassl/internal.h b/cyassl/internal.h index fbdf4825e..2b70a3bd9 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1350,10 +1350,10 @@ struct CYASSL { byte peerNtruKeyPresent; #endif #ifdef HAVE_ECC - ecc_key peerEccKey; /* peer's ECDHE key */ - ecc_key peerEccDsaKey; /* peer's ECDSA key */ - ecc_key eccTempKey; /* private ECDHE key */ - ecc_key eccDsaKey; /* private ECDSA key */ + ecc_key* peerEccKey; /* peer's ECDHE key */ + ecc_key* peerEccDsaKey; /* peer's ECDSA key */ + ecc_key* eccTempKey; /* private ECDHE key */ + ecc_key* eccDsaKey; /* private ECDSA key */ word16 eccTempKeySz; /* in octets 20 - 66 */ byte peerEccKeyPresent; byte peerEccDsaKeyPresent; diff --git a/src/internal.c b/src/internal.c index bb8062b58..69518fd48 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1004,10 +1004,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->peerEccDsaKeyPresent = 0; ssl->eccDsaKeyPresent = 0; ssl->eccTempKeyPresent = 0; - ecc_init(&ssl->peerEccKey); - ecc_init(&ssl->peerEccDsaKey); - ecc_init(&ssl->eccDsaKey); - ecc_init(&ssl->eccTempKey); + ssl->peerEccKey = NULL; + ssl->peerEccDsaKey = NULL; + ssl->eccDsaKey = NULL; + ssl->eccTempKey = NULL; #endif ssl->timeout = ctx->timeout; @@ -1228,6 +1228,36 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) return NO_PRIVATE_KEY; } #endif +#ifdef HAVE_ECC + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + CYASSL_MSG("PeerEccKey Memory error"); + return MEMORY_E; + } + ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccDsaKey == NULL) { + CYASSL_MSG("PeerEccDsaKey Memory error"); + return MEMORY_E; + } + ssl->eccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->eccDsaKey == NULL) { + CYASSL_MSG("EccDsaKey Memory error"); + return MEMORY_E; + } + ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->eccTempKey == NULL) { + CYASSL_MSG("EccTempKey Memory error"); + return MEMORY_E; + } + ecc_init(ssl->peerEccKey); + ecc_init(ssl->peerEccDsaKey); + ecc_init(ssl->eccDsaKey); + ecc_init(ssl->eccTempKey); +#endif /* make sure server has DH parms, and add PSK if there, add NTRU too */ if (ssl->options.side == SERVER_END) @@ -1312,14 +1342,26 @@ void SSL_ResourceFree(CYASSL* ssl) FreeStreams(ssl); #endif #ifdef HAVE_ECC - if (ssl->peerEccKeyPresent) - ecc_free(&ssl->peerEccKey); - if (ssl->peerEccDsaKeyPresent) - ecc_free(&ssl->peerEccDsaKey); - if (ssl->eccTempKeyPresent) - ecc_free(&ssl->eccTempKey); - if (ssl->eccDsaKeyPresent) - ecc_free(&ssl->eccDsaKey); + if (ssl->peerEccKey) { + if (ssl->peerEccKeyPresent) + ecc_free(ssl->peerEccKey); + XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC); + } + if (ssl->peerEccDsaKey) { + if (ssl->peerEccDsaKeyPresent) + ecc_free(ssl->peerEccDsaKey); + XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC); + } + if (ssl->eccTempKey) { + if (ssl->eccTempKeyPresent) + ecc_free(ssl->eccTempKey); + XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC); + } + if (ssl->eccDsaKey) { + if (ssl->eccDsaKeyPresent) + ecc_free(ssl->eccDsaKey); + XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC); + } #endif } @@ -1364,21 +1406,41 @@ void FreeHandshakeResources(CYASSL* ssl) #endif #ifdef HAVE_ECC - if (ssl->peerEccKeyPresent) { - ecc_free(&ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; + if (ssl->peerEccKey) + { + if (ssl->peerEccKeyPresent) { + ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + } + XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC); + ssl->peerEccKey = NULL; } - if (ssl->peerEccDsaKeyPresent) { - ecc_free(&ssl->peerEccDsaKey); - ssl->peerEccDsaKeyPresent = 0; + if (ssl->peerEccDsaKey) + { + if (ssl->peerEccDsaKeyPresent) { + ecc_free(ssl->peerEccDsaKey); + ssl->peerEccDsaKeyPresent = 0; + } + XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC); + ssl->peerEccDsaKey = NULL; } - if (ssl->eccTempKeyPresent) { - ecc_free(&ssl->eccTempKey); - ssl->eccTempKeyPresent = 0; + if (ssl->eccTempKey) + { + if (ssl->eccTempKeyPresent) { + ecc_free(ssl->eccTempKey); + ssl->eccTempKeyPresent = 0; + } + XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC); + ssl->eccTempKey = NULL; } - if (ssl->eccDsaKeyPresent) { - ecc_free(&ssl->eccDsaKey); - ssl->eccDsaKeyPresent = 0; + if (ssl->eccDsaKey) + { + if (ssl->eccDsaKeyPresent) { + ecc_free(ssl->eccDsaKey); + ssl->eccDsaKeyPresent = 0; + } + XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC); + ssl->eccDsaKey = NULL; } #endif } @@ -2441,7 +2503,7 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx) case ECDSAk: { if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize, - &ssl->peerEccDsaKey) != 0) { + ssl->peerEccDsaKey) != 0) { ret = PEER_KEY_ERROR; } else @@ -5660,7 +5722,7 @@ int SetCipherList(Suites* s, const char* list) length = input[*inOutIdx]; *inOutIdx += 1; - if (ecc_import_x963(&input[*inOutIdx], length, &ssl->peerEccKey) != 0) + if (ecc_import_x963(&input[*inOutIdx], length, ssl->peerEccKey) != 0) return ECC_PEERKEY_ERROR; *inOutIdx += length; @@ -5754,7 +5816,7 @@ int SetCipherList(Suites* s, const char* list) return NO_PEER_KEY; ret = ecc_verify_hash(signature, sigLen, &hash[MD5_DIGEST_SIZE], - SHA_DIGEST_SIZE, &verify, &ssl->peerEccDsaKey); + SHA_DIGEST_SIZE, &verify, ssl->peerEccDsaKey); if (ret != 0 || verify == 0) return VERIFY_SIGN_ERROR; } @@ -5904,14 +5966,14 @@ int SetCipherList(Suites* s, const char* list) if (ssl->specs.static_ecdh) { /* TODO: EccDsa is really fixed Ecc change naming */ - if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey.dp) + if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey->dp) return NO_PEER_KEY; - peerKey = &ssl->peerEccDsaKey; + peerKey = ssl->peerEccDsaKey; } else { - if (!ssl->peerEccKeyPresent || !ssl->peerEccKey.dp) + if (!ssl->peerEccKeyPresent || !ssl->peerEccKey->dp) return NO_PEER_KEY; - peerKey = &ssl->peerEccKey; + peerKey = ssl->peerEccKey; } ecc_init(&myKey); @@ -6367,7 +6429,7 @@ int SetCipherList(Suites* s, const char* list) length = ENUM_LEN + CURVE_LEN + ENUM_LEN; /* pub key size */ CYASSL_MSG("Using ephemeral ECDH"); - if (ecc_export_x963(&ssl->eccTempKey, exportBuf, &expSz) != 0) + if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0) return ECC_EXPORT_ERROR; length += expSz; @@ -6437,7 +6499,7 @@ int SetCipherList(Suites* s, const char* list) /* key exchange data */ output[idx++] = named_curve; output[idx++] = 0x00; /* leading zero */ - output[idx++] = SetCurveId(ecc_size(&ssl->eccTempKey)); + output[idx++] = SetCurveId(ecc_size(ssl->eccTempKey)); output[idx++] = (byte)expSz; XMEMCPY(output + idx, exportBuf, expSz); idx += expSz; @@ -7570,7 +7632,7 @@ int SetCipherList(Suites* s, const char* list) CYASSL_MSG("Doing ECC peer cert verify"); err = ecc_verify_hash(sig, sz, ssl->certHashes.sha, SHA_DIGEST_SIZE, - &verify, &ssl->peerEccDsaKey); + &verify, ssl->peerEccDsaKey); if (err == 0 && verify == 1) ret = 0; /* verified */ @@ -7813,7 +7875,8 @@ int SetCipherList(Suites* s, const char* list) word32 bLength = input[*inOutIdx]; /* one byte length */ *inOutIdx += 1; - ret = ecc_import_x963(&input[*inOutIdx], bLength, &ssl->peerEccKey); + ret = ecc_import_x963(&input[*inOutIdx], + bLength, ssl->peerEccKey); if (ret != 0) return ECC_PEERKEY_ERROR; *inOutIdx += bLength; @@ -7826,14 +7889,14 @@ int SetCipherList(Suites* s, const char* list) ecc_init(&staticKey); ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i, - &staticKey, ssl->buffers.key.length); + &staticKey, ssl->buffers.key.length); if (ret == 0) - ret = ecc_shared_secret(&staticKey, &ssl->peerEccKey, - ssl->arrays->preMasterSecret, &size); + ret = ecc_shared_secret(&staticKey, ssl->peerEccKey, + ssl->arrays->preMasterSecret, &size); ecc_free(&staticKey); } else - ret = ecc_shared_secret(&ssl->eccTempKey, &ssl->peerEccKey, + ret = ecc_shared_secret(ssl->eccTempKey, ssl->peerEccKey, ssl->arrays->preMasterSecret, &size); if (ret != 0) return ECC_SHARED_ERROR; diff --git a/src/ssl.c b/src/ssl.c index ef110da2a..673fc72cb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2786,7 +2786,7 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) /* in case used set_accept_state after init */ if (ssl->eccTempKeyPresent == 0) { if (ecc_make_key(ssl->rng, ssl->eccTempKeySz, - &ssl->eccTempKey) != 0) { + ssl->eccTempKey) != 0) { ssl->error = ECC_MAKEKEY_ERROR; CYASSL_ERROR(ssl->error); return SSL_FATAL_ERROR; From baf9bef8a353ec4f53964f74ffc1dd97bc3200fc Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 26 Dec 2012 21:41:12 -0800 Subject: [PATCH 08/11] Revert "changed polarity on ocsp thisDate check to allow very timely responses" This reverts commit afbc34f0e03bea0ae83c792b7c35a541876b9a97. --- ctaocrypt/src/asn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index c30263be2..785e49e50 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4240,8 +4240,7 @@ static int DecodeSingleResponse(byte* source, if (GetBasicDate(source, &idx, cs->thisDate, &cs->thisDateFormat, size) < 0) return ASN_PARSE_E; - /* Check thisDate <= now, or treat thisDate > now as a failure */ - if (ValidateDate(cs->thisDate, cs->thisDateFormat, AFTER)) + 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 From 0cfa4235660d8930d75ce7efb0e657df2b72126b Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 27 Dec 2012 10:08:44 -0800 Subject: [PATCH 09/11] fixed mp_add_d overflow --- ctaocrypt/src/integer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ctaocrypt/src/integer.c b/ctaocrypt/src/integer.c index 388c4f0d5..000669db5 100644 --- a/ctaocrypt/src/integer.c +++ b/ctaocrypt/src/integer.c @@ -3792,8 +3792,10 @@ int mp_add_d (mp_int* a, mp_digit b, mp_int* c) *tmpc++ &= MP_MASK; } /* set final carry */ - ix++; - *tmpc++ = mu; + if (mu != 0 && ix < c->alloc) { + ix++; + *tmpc++ = mu; + } /* setup size */ c->used = a->used + 1; From 03f9cafa4b84662d79e5e4df63b4bba3d2c296ac Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 27 Dec 2012 11:18:29 -0800 Subject: [PATCH 10/11] ecc_verify_hash was leaking two mp_ints --- ctaocrypt/src/ecc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ctaocrypt/src/ecc.c b/ctaocrypt/src/ecc.c index 1976b3d12..ef35477f2 100644 --- a/ctaocrypt/src/ecc.c +++ b/ctaocrypt/src/ecc.c @@ -1266,17 +1266,17 @@ int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen, } /* allocate ints */ - if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2)) != MP_OKAY) { + if ((err = mp_init_multi(&v, &w, &u1, &u2, &p, &e)) != MP_OKAY) { return MEMORY_E; } - if ((err = mp_init_multi(&p, &e, &m, NULL, NULL, NULL)) != MP_OKAY) { - mp_clear(&r); - mp_clear(&s); + if ((err = mp_init(&m)) != MP_OKAY) { mp_clear(&v); mp_clear(&w); mp_clear(&u1); mp_clear(&u2); + mp_clear(&p); + mp_clear(&e); return MEMORY_E; } @@ -1286,6 +1286,12 @@ int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen, if (mQ == NULL || mG == NULL) err = MEMORY_E; + /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. + * If either of those don't allocate correctly, none of + * the rest of this function will execute, and everything + * gets cleaned up at the end. */ + XMEMSET(&r, 0, sizeof(r)); + XMEMSET(&s, 0, sizeof(s)); if (err == MP_OKAY) err = DecodeECC_DSA_Sig(sig, siglen, &r, &s); From 724297a127c3a7fab3eb7c9d132db0822facf397 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 27 Dec 2012 11:57:41 -0800 Subject: [PATCH 11/11] asn should use the validate date macro, not call the function directly. --- 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 785e49e50..6629f8e66 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4240,7 +4240,7 @@ 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)) + if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE)) return ASN_BEFORE_DATE_E; /* The following items are optional. Only check for them if there is more