From 570befb63f7be43e9545df7b9273d320c29a7ae0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 Apr 2017 10:35:26 -0700 Subject: [PATCH] Fixes for using async. Combine duplicate `DoCertificate` and `DoTls13Certificate` code into `ProcessPeerCerts`. Cleanup of the XMALLOC/XFREE to use ssl->heap. --- src/internal.c | 151 ++++++--- src/tls.c | 23 +- src/tls13.c | 826 +++------------------------------------------ wolfssl/internal.h | 3 +- 4 files changed, 182 insertions(+), 821 deletions(-) diff --git a/src/internal.c b/src/internal.c index 589330def..1cc38d532 100755 --- a/src/internal.c +++ b/src/internal.c @@ -6803,8 +6803,11 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) #endif /* KEEP_PEER_CERT || SESSION_CERTS */ -typedef struct DoCertArgs { +typedef struct ProcPeerCertArgs { buffer* certs; +#ifdef WOLFSSL_TLS13 + buffer* exts; /* extentions */ +#endif DecodedCert* dCert; char* domain; word32 idx; @@ -6813,14 +6816,17 @@ typedef struct DoCertArgs { int count; int dCertInit; int certIdx; +#ifdef WOLFSSL_TLS13 + byte ctxSz; +#endif #ifdef WOLFSSL_TRUST_PEER_CERT byte haveTrustPeer; /* was cert verified by loaded trusted peer cert */ #endif -} DoCertArgs; +} ProcPeerCertArgs; -static void FreeDoCertArgs(WOLFSSL* ssl, void* pArgs) +static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) { - DoCertArgs* args = (DoCertArgs*)pArgs; + ProcPeerCertArgs* args = (ProcPeerCertArgs*)pArgs; (void)ssl; @@ -6832,6 +6838,12 @@ static void FreeDoCertArgs(WOLFSSL* ssl, void* pArgs) XFREE(args->certs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); args->certs = NULL; } +#ifdef WOLFSSL_TLS13 + if (args->exts) { + XFREE(args->exts, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + args->exts = NULL; + } +#endif if (args->dCert) { if (args->dCertInit) { FreeDecodedCert(args->dCert); @@ -6842,30 +6854,29 @@ static void FreeDoCertArgs(WOLFSSL* ssl, void* pArgs) } } -static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, - word32 size) +int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz) { int ret = 0, lastErr = 0; #ifdef WOLFSSL_ASYNC_CRYPT - DoCertArgs* args = (DoCertArgs*)ssl->async.args; + ProcPeerCertArgs* args = (ProcPeerCertArgs*)ssl->async.args; typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1]; (void)sizeof(args_test); #else - DoCertArgs args[1]; + ProcPeerCertArgs args[1]; #endif #ifdef WOLFSSL_TRUST_PEER_CERT byte haveTrustPeer = 0; /* was cert verified by loaded trusted peer cert */ #endif - WOLFSSL_ENTER("DoCertificate"); + WOLFSSL_ENTER("ProcessPeerCerts"); #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState); if (ret != WC_NOT_PENDING_E) { /* Check for error */ if (ret < 0) - goto exit_dc; + goto exit_ppc; } else #endif @@ -6873,15 +6884,15 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* Reset state */ ret = 0; ssl->options.asyncState = TLS_ASYNC_BEGIN; - XMEMSET(args, 0, sizeof(DoCertArgs)); + XMEMSET(args, 0, sizeof(ProcPeerCertArgs)); args->idx = *inOutIdx; args->begin = *inOutIdx; #ifdef WOLFSSL_ASYNC_CRYPT - ssl->async.freeArgs = FreeDoCertArgs; + ssl->async.freeArgs = FreeProcPeerCertArgs; #endif } - switch(ssl->options.asyncState) + switch (ssl->options.asyncState) { case TLS_ASYNC_BEGIN: { @@ -6894,27 +6905,65 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, AddLateName("Certificate", &ssl->timeoutInfo); #endif + #ifdef WOLFSSL_TLS13 + if (ssl->options.tls1_3) { + byte ctxSz; + + /* Certificate Request Context */ + if ((args->idx - args->begin) + OPAQUE8_LEN > totalSz) + return BUFFER_ERROR; + ctxSz = *(input + args->idx); + args->idx++; + if ((args->idx - args->begin) + ctxSz > totalSz) + return BUFFER_ERROR; + #ifndef NO_WOLFSSL_CLIENT + /* Must be empty when received from server. */ + if (ssl->options.side == WOLFSSL_CLIENT_END) { + if (ctxSz != 0) { + return INVALID_CERT_CTX_E; + } + } + #endif + #ifndef NO_WOLFSSL_SERVER + /* Must contain value sent in request when received from client. */ + if (ssl->options.side == WOLFSSL_SERVER_END) { + if (ssl->clientCertCtx.length != ctxSz || + XMEMCMP(ssl->clientCertCtx.buffer, + input + args->idx, ctxSz) != 0) { + return INVALID_CERT_CTX_E; + } + } + #endif + args->idx += ctxSz; + + /* allocate buffer for cert extensions */ + args->exts = (buffer*)XMALLOC(sizeof(buffer) * MAX_CHAIN_DEPTH, + ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (args->exts == NULL) { + ERROR_OUT(MEMORY_E, exit_ppc); + } + } + #endif + /* allocate buffer for certs */ args->certs = (buffer*)XMALLOC(sizeof(buffer) * MAX_CHAIN_DEPTH, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (args->certs == NULL) { - ERROR_OUT(MEMORY_E, exit_dc); + ERROR_OUT(MEMORY_E, exit_ppc); } XMEMSET(args->certs, 0, sizeof(buffer) * MAX_CHAIN_DEPTH); - if ((args->idx - args->begin) + OPAQUE24_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dc); + /* Certificate List */ + if ((args->idx - args->begin) + OPAQUE24_LEN > totalSz) { + ERROR_OUT(BUFFER_ERROR, exit_ppc); } - c24to32(input + args->idx, &listSz); args->idx += OPAQUE24_LEN; - if (listSz > MAX_RECORD_SIZE) { - ERROR_OUT(BUFFER_ERROR, exit_dc); + ERROR_OUT(BUFFER_ERROR, exit_ppc); } - - if ((args->idx - args->begin) + listSz != size) { - ERROR_OUT(BUFFER_ERROR, exit_dc); + if ((args->idx - args->begin) + listSz != totalSz) { + ERROR_OUT(BUFFER_ERROR, exit_ppc); } WOLFSSL_MSG("Loading peer's cert chain"); @@ -6927,18 +6976,18 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef OPENSSL_EXTRA ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; #endif - ERROR_OUT(MAX_CHAIN_ERROR, exit_dc); + ERROR_OUT(MAX_CHAIN_ERROR, exit_ppc); } - if ((args->idx - args->begin) + OPAQUE24_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dc); + if ((args->idx - args->begin) + OPAQUE24_LEN > totalSz) { + ERROR_OUT(BUFFER_ERROR, exit_ppc); } c24to32(input + args->idx, &certSz); args->idx += OPAQUE24_LEN; - if ((args->idx - args->begin) + certSz > size) { - ERROR_OUT(BUFFER_ERROR, exit_dc); + if ((args->idx - args->begin) + certSz > totalSz) { + ERROR_OUT(BUFFER_ERROR, exit_ppc); } args->certs[args->totalCerts].length = certSz; @@ -6962,6 +7011,25 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->idx += certSz; listSz -= certSz + CERT_HEADER_SZ; + #ifdef WOLFSSL_TLS13 + /* Extensions */ + if (ssl->options.tls1_3) { + word16 extSz; + + if ((args->idx - args->begin) + OPAQUE16_LEN > totalSz) + return BUFFER_ERROR; + ato16(input + args->idx, &extSz); + args->idx += OPAQUE16_LEN; + if ((args->idx - args->begin) + extSz > totalSz) + return BUFFER_ERROR; + /* Store extension data info for later processing. */ + args->exts[args->totalCerts].length = extSz; + args->exts[args->totalCerts].buffer = input + args->idx; + args->idx += extSz; + listSz -= extSz + OPAQUE16_LEN; + } + #endif + args->totalCerts++; WOLFSSL_MSG("\tPut another cert into chain"); } /* while (listSz) */ @@ -6973,7 +7041,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (args->dCert == NULL) { - ERROR_OUT(MEMORY_E, exit_dc); + ERROR_OUT(MEMORY_E, exit_ppc); } /* Advance state and proceed */ @@ -7007,7 +7075,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WC_ASYNC_FLAG_CALL_AGAIN); } #endif - goto exit_dc; + goto exit_ppc; } #ifndef NO_SKID @@ -7123,7 +7191,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = AllocDer(&add, args->certs[args->certIdx].length, CA_TYPE, ssl->heap); if (ret < 0) - goto exit_dc; + goto exit_ppc; WOLFSSL_MSG("Adding CA from chain"); @@ -7197,7 +7265,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* Check for error */ if (ret != 0) { - goto exit_dc; + goto exit_ppc; } /* Advance state and proceed */ @@ -7394,7 +7462,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef OPENSSL_EXTRA ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; #endif - goto exit_dc; + goto exit_ppc; } ssl->options.havePeerCert = 1; @@ -7402,7 +7470,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* Check for error */ if (ret != 0) { - goto exit_dc; + goto exit_ppc; } /* Advance state and proceed */ @@ -7415,7 +7483,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->domain = (char*)XMALLOC(ASN_NAME_MAX, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (args->domain == NULL) { - ERROR_OUT(MEMORY_E, exit_dc); + ERROR_OUT(MEMORY_E, exit_ppc); } /* store for callback use */ @@ -7586,7 +7654,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* Check for error */ if (ret != 0) { - goto exit_dc; + goto exit_ppc; } /* Advance state and proceed */ @@ -7600,7 +7668,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, sizeof(WOLFSSL_X509_STORE_CTX), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (store == NULL) { - ERROR_OUT(MEMORY_E, exit_dc); + ERROR_OUT(MEMORY_E, exit_ppc); } #else WOLFSSL_X509_STORE_CTX store[1]; @@ -7734,9 +7802,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } /* switch(ssl->options.asyncState) */ -exit_dc: +exit_ppc: - WOLFSSL_LEAVE("DoCertificate", ret); + WOLFSSL_LEAVE("ProcessPeerCerts", ret); #ifdef WOLFSSL_ASYNC_CRYPT /* Handle WC_PENDING_E */ @@ -7748,12 +7816,17 @@ exit_dc: } #endif /* WOLFSSL_ASYNC_CRYPT */ - FreeDoCertArgs(ssl, args); + FreeProcPeerCertArgs(ssl, args); FreeKeyExchange(ssl); return ret; } +static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, + word32 size) +{ + return ProcessPeerCerts(ssl, input, inOutIdx, size); +} static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size) diff --git a/src/tls.c b/src/tls.c index ab6d8236c..9c6d39dcb 100755 --- a/src/tls.c +++ b/src/tls.c @@ -4606,6 +4606,12 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) if (ret != 0) goto end; ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId); +#ifdef WOLFSSL_ASYNC_CRYPT + /* TODO: Make this function non-blocking */ + if (ret == WC_PENDING_E) { + ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE); + } +#endif if (ret != 0) goto end; @@ -4868,6 +4874,7 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) #ifndef NO_ECC int ret; int curveId; + ecc_key* keyShareKey = (ecc_key*)keyShareEntry->key; if (ssl->peerEccKey != NULL) wc_ecc_free(ssl->peerEccKey); @@ -4932,7 +4939,18 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) } ssl->arrays->preMasterSz = ENCRYPT_LEN; - return EccSharedSecret(ssl, keyShareEntry->key, ssl->peerEccKey, + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &keyShareKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + #endif + if (ret >= 0) + ret = wc_ecc_shared_secret(keyShareKey, ssl->peerEccKey, + ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); + } while (ret == WC_PENDING_E); + +#if 0 + /* TODO: Switch to support async here and use: */ + ret = EccSharedSecret(ssl, keyShareEntry->key, ssl->peerEccKey, keyShareEntry->ke, &keyShareEntry->keLen, ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, ssl->options.side, @@ -4942,6 +4960,9 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) NULL #endif ); +#endif + + return ret; #else return PEER_KEY_ERROR; #endif diff --git a/src/tls13.c b/src/tls13.c index 2c3209399..f88de1225 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -803,7 +803,7 @@ static int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side) int deriveServer = 0; #ifdef WOLFSSL_SMALL_STACK - key_data = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER); + key_data = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (key_data == NULL) return MEMORY_E; #endif @@ -904,8 +904,8 @@ static int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side) end: #ifdef WOLFSSL_SMALL_STACK - XFREE(serverData, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(key_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serverData, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key_data, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; @@ -3012,7 +3012,7 @@ static int CheckRSASignature(WOLFSSL* ssl, int hashAlgo, byte* decSig, word32 sigSz; #ifdef WOLFSSL_SMALL_STACK - encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (encodedSig == NULL) { ret = MEMORY_E; @@ -3031,7 +3031,7 @@ static int CheckRSASignature(WOLFSSL* ssl, int hashAlgo, byte* decSig, #ifdef WOLFSSL_SMALL_STACK end: if (encodedSig != NULL) - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; @@ -3303,7 +3303,7 @@ typedef struct Scv13Args { int sendSz; word16 length; - byte sigData[MAX_SIG_DATA_SZ]; + byte* sigData; word16 sigDataSz; } Scv13Args; @@ -3319,6 +3319,10 @@ static void FreeScv13Args(WOLFSSL* ssl, void* pArgs) args->verifySig = NULL; } #endif + if (args->sigData) { + XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + args->sigData = NULL; + } if (args->input) { XFREE(args->input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); args->input = NULL; @@ -3406,14 +3410,20 @@ int SendTls13CertificateVerify(WOLFSSL* ssl) EncodeSigAlg(ssl->suites->hashAlgo, ssl->hsType, args->verify); /* Create the data to be signed. */ + args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (args->sigData == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + CreateSigData(ssl, args->sigData, &args->sigDataSz, 0); #ifndef NO_RSA if (ssl->hsType == DYNAMIC_TYPE_RSA) { /* build encoded signature buffer */ sig->length = MAX_ENCODED_SIG_SZ; - sig->buffer = (byte*)XMALLOC(sig->length, - ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); if (sig->buffer == NULL) return MEMORY_E; @@ -3493,7 +3503,7 @@ int SendTls13CertificateVerify(WOLFSSL* ssl) if (ssl->hsType == DYNAMIC_TYPE_RSA) { if (args->verifySig == NULL) { args->verifySig = (byte*)XMALLOC(args->sigLen, ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); + DYNAMIC_TYPE_TMP_BUFFER); if (args->verifySig == NULL) { ERROR_OUT(MEMORY_E, exit_scv); } @@ -3579,655 +3589,6 @@ exit_scv: return ret; } -int ProcessPeerCerts(WOLFSSL* ssl, buffer *certs, buffer *exts, int totalCerts) -{ - int ret = 0; - int anyError = 0; - int count; -#ifdef WOLFSSL_SMALL_STACK - char* domain = NULL; - DecodedCert* dCert = NULL; - WOLFSSL_X509_STORE_CTX* store = NULL; -#else - char domain[ASN_NAME_MAX]; - DecodedCert dCert[1]; - WOLFSSL_X509_STORE_CTX store[1]; -#endif - -#ifdef WOLFSSL_TRUST_PEER_CERT - byte haveTrustPeer = 0; /* was cert verified by loaded trusted peer cert */ -#endif - - /* TODO: [TLS13] Handle certificate extensions */ - (void)exts; - - count = totalCerts; - -#ifdef WOLFSSL_SMALL_STACK - dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (dCert == NULL) - return MEMORY_E; -#endif - -#ifdef WOLFSSL_TRUST_PEER_CERT - /* if using trusted peer certs check before verify chain and CA test */ - if (count > 0) { - TrustedPeerCert* tp = NULL; - - InitDecodedCert(dCert, certs[0].buffer, certs[0].length, ssl->heap); - ret = ParseCertRelative(dCert, CERT_TYPE, 0, ssl->ctx->cm); - #ifndef NO_SKID - if (dCert->extAuthKeyIdSet) { - tp = GetTrustedPeer(ssl->ctx->cm, dCert->extSubjKeyId, - WC_MATCH_SKID); - } - else { /* if the cert has no SKID try to match by name */ - tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash, - WC_MATCH_NAME); - } - #else /* NO_SKID */ - tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash, - WC_MATCH_NAME); - #endif /* NO SKID */ - WOLFSSL_MSG("Checking for trusted peer cert"); - - if (tp == NULL) { - /* no trusted peer cert */ - WOLFSSL_MSG("No matching trusted peer cert. Checking CAs"); - FreeDecodedCert(dCert); - } else if (MatchTrustedPeer(tp, dCert)){ - WOLFSSL_MSG("Found matching trusted peer cert"); - haveTrustPeer = 1; - } else { - WOLFSSL_MSG("Trusted peer cert did not match!"); - FreeDecodedCert(dCert); - } - } - if (!haveTrustPeer) { /* do not verify chain if trusted peer cert found */ -#endif /* WOLFSSL_TRUST_PEER_CERT */ - - /* verify up to peer's first */ - while (count > 1) { - buffer myCert = certs[count - 1]; - byte* subjectHash; - - InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap); - ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone, - ssl->ctx->cm); - #ifndef NO_SKID - subjectHash = dCert->extSubjKeyId; - #else - subjectHash = dCert->subjectHash; - #endif - - /* Check key sizes for certs. Is redundent check since ProcessBuffer - also performs this check. */ - if (!ssl->options.verifyNone) { - switch (dCert->keyOID) { - #ifndef NO_RSA - case RSAk: - if (ssl->options.minRsaKeySz < 0 || - dCert->pubKeySize < (word16)ssl->options.minRsaKeySz) { - WOLFSSL_MSG("RSA key size in cert chain error"); - ret = RSA_KEY_SIZE_E; - } - break; - #endif /* !NO_RSA */ - #ifdef HAVE_ECC - case ECDSAk: - if (ssl->options.minEccKeySz < 0 || - dCert->pubKeySize < (word16)ssl->options.minEccKeySz) { - WOLFSSL_MSG("ECC key size in cert chain error"); - ret = ECC_KEY_SIZE_E; - } - break; - #endif /* HAVE_ECC */ - - default: - WOLFSSL_MSG("Key size not checked"); - break; /* key not being checked for size if not in switch */ - } - } - - if (ret == 0 && dCert->isCA == 0) { - WOLFSSL_MSG("Chain cert is not a CA, not adding as one"); - } - else if (ret == 0 && ssl->options.verifyNone) { - WOLFSSL_MSG("Chain cert not verified by option, not adding as CA"); - } - else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) { - DerBuffer* add = NULL; - ret = AllocDer(&add, myCert.length, CA_TYPE, ssl->heap); - if (ret < 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } - - WOLFSSL_MSG("Adding CA from chain"); - - XMEMCPY(add->buffer, myCert.buffer, myCert.length); - - /* already verified above */ - ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA, 0); - if (ret == 1) ret = 0; /* SSL_SUCCESS for external */ - } - else if (ret != 0) { - WOLFSSL_MSG("Failed to verify CA from chain"); - #ifdef OPENSSL_EXTRA - ssl->peerVerifyRet = X509_V_ERR_INVALID_CA; - #endif - } - else { - WOLFSSL_MSG("Verified CA from chain and already had it"); - } - -#if defined(HAVE_OCSP) || defined(HAVE_CRL) - if (ret == 0) { - int doCrlLookup = 1; - -#ifdef HAVE_OCSP - #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - if (ssl->status_request_v2) - ret = TLSX_CSR2_InitRequests(ssl->extensions, dCert, 0, - ssl->heap); - else /* skips OCSP and force CRL check */ - #endif - if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) { - WOLFSSL_MSG("Doing Non Leaf OCSP check"); - ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL); - doCrlLookup = (ret == OCSP_CERT_UNKNOWN); - if (ret != 0) { - doCrlLookup = 0; - WOLFSSL_MSG("\tOCSP Lookup not ok"); - } - } -#endif /* HAVE_OCSP */ - -#ifdef HAVE_CRL - if (ret == 0 && doCrlLookup && ssl->ctx->cm->crlEnabled - && ssl->ctx->cm->crlCheckAll) { - WOLFSSL_MSG("Doing Non Leaf CRL check"); - ret = CheckCertCRL(ssl->ctx->cm->crl, dCert); - - if (ret != 0) { - WOLFSSL_MSG("\tCRL check not ok"); - } - } -#else - (void)doCrlLookup; -#endif /* HAVE_CRL */ - } -#endif /* HAVE_OCSP || HAVE_CRL */ - - if (ret != 0 && anyError == 0) - anyError = ret; /* save error from last time */ - - FreeDecodedCert(dCert); - count--; - } - -#ifdef WOLFSSL_TRUST_PEER_CERT - } /* end of if (haveTrustPeer) -- a check for if already verified */ -#endif - - /* peer's, may not have one if blank client cert sent by TLSv1.2 */ - if (count) { - buffer myCert = certs[0]; - int fatal = 0; - - WOLFSSL_MSG("Verifying Peer's cert"); - -#ifdef WOLFSSL_TRUST_PEER_CERT - if (!haveTrustPeer) { /* do not parse again if previously verified */ -#endif - InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap); - ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone, - ssl->ctx->cm); -#ifdef WOLFSSL_TRUST_PEER_CERT - } -#endif - - if (ret == 0) { - WOLFSSL_MSG("Verified Peer's cert"); - #ifdef OPENSSL_EXTRA - ssl->peerVerifyRet = X509_V_OK; - #endif - fatal = 0; - } - else if (ret == ASN_PARSE_E) { - WOLFSSL_MSG("Got Peer cert ASN PARSE ERROR, fatal"); - fatal = 1; - } - else { - WOLFSSL_MSG("Failed to verify Peer's cert"); - #ifdef OPENSSL_EXTRA - ssl->peerVerifyRet = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; - #endif - if (ssl->verifyCallback) { - WOLFSSL_MSG("\tCallback override available, will continue"); - fatal = 0; - } - else { - WOLFSSL_MSG("\tNo callback override available, fatal"); - fatal = 1; - } - } - -#ifdef HAVE_SECURE_RENEGOTIATION - if (fatal == 0 && ssl->secure_renegotiation - && ssl->secure_renegotiation->enabled) { - - if (IsEncryptionOn(ssl, 0)) { - /* compare against previous time */ - if (XMEMCMP(dCert->subjectHash, - ssl->secure_renegotiation->subject_hash, - SHA_DIGEST_SIZE) != 0) { - WOLFSSL_MSG("Peer sent different cert during scr, fatal"); - fatal = 1; - ret = SCR_DIFFERENT_CERT_E; - } - } - - /* cache peer's hash */ - if (fatal == 0) { - XMEMCPY(ssl->secure_renegotiation->subject_hash, - dCert->subjectHash, SHA_DIGEST_SIZE); - } - } -#endif - -#if defined(HAVE_OCSP) || defined(HAVE_CRL) - if (fatal == 0) { - int doLookup = 1; - - if (ssl->options.side == WOLFSSL_CLIENT_END) { -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST - if (ssl->status_request) { - fatal = TLSX_CSR_InitRequest(ssl->extensions, dCert, - ssl->heap); - doLookup = 0; - } -#endif -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - if (ssl->status_request_v2) { - fatal = TLSX_CSR2_InitRequests(ssl->extensions, dCert, 1, - ssl->heap); - doLookup = 0; - } -#endif - } - -#ifdef HAVE_OCSP - if (doLookup && ssl->ctx->cm->ocspEnabled) { - WOLFSSL_MSG("Doing Leaf OCSP check"); - ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL); - doLookup = (ret == OCSP_CERT_UNKNOWN); - if (ret != 0) { - WOLFSSL_MSG("\tOCSP Lookup not ok"); - fatal = 0; - #ifdef OPENSSL_EXTRA - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; - #endif - } - } -#endif /* HAVE_OCSP */ - -#ifdef HAVE_CRL - if (doLookup && ssl->ctx->cm->crlEnabled) { - WOLFSSL_MSG("Doing Leaf CRL check"); - ret = CheckCertCRL(ssl->ctx->cm->crl, dCert); - if (ret != 0) { - WOLFSSL_MSG("\tCRL check not ok"); - fatal = 0; - #ifdef OPENSSL_EXTRA - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; - #endif - } - } -#endif /* HAVE_CRL */ - (void)doLookup; - } -#endif /* HAVE_OCSP || HAVE_CRL */ - -#ifdef KEEP_PEER_CERT - { - /* set X509 format for peer cert even if fatal */ - int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert); - if (copyRet == MEMORY_E) - fatal = 1; - } -#endif - -#ifndef IGNORE_KEY_EXTENSIONS - if (dCert->extKeyUsageSet) { - if ((ssl->specs.kea == rsa_kea) && - (ssl->options.side == WOLFSSL_CLIENT_END) && - (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) { - ret = KEYUSE_ENCIPHER_E; - } - if ((ssl->specs.sig_algo == rsa_sa_algo || - (ssl->specs.sig_algo == ecc_dsa_sa_algo && - !ssl->specs.static_ecdh)) && - (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) { - WOLFSSL_MSG("KeyUse Digital Sig not set"); - ret = KEYUSE_SIGNATURE_E; - } - } - - if (dCert->extExtKeyUsageSet) { - if (ssl->options.side == WOLFSSL_CLIENT_END) { - if ((dCert->extExtKeyUsage & - (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) { - WOLFSSL_MSG("ExtKeyUse Server Auth not set"); - ret = EXTKEYUSE_AUTH_E; - } - } - else { - if ((dCert->extExtKeyUsage & - (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) { - WOLFSSL_MSG("ExtKeyUse Client Auth not set"); - ret = EXTKEYUSE_AUTH_E; - } - } - } -#endif /* IGNORE_KEY_EXTENSIONS */ - - if (fatal) { - FreeDecodedCert(dCert); - #ifdef WOLFSSL_SMALL_STACK - XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - ssl->error = ret; - #ifdef OPENSSL_EXTRA - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; - #endif - return ret; - } - ssl->options.havePeerCert = 1; - -#ifdef WOLFSSL_SMALL_STACK - domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (domain == NULL) { - FreeDecodedCert(dCert); - XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - /* store for callback use */ - if (dCert->subjectCNLen < ASN_NAME_MAX) { - XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen); - domain[dCert->subjectCNLen] = '\0'; - } - else - domain[0] = '\0'; - - if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) { - if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen, - (char*)ssl->buffers.domainName.buffer) == 0) { - WOLFSSL_MSG("DomainName match on common name failed"); - if (CheckAltNames(dCert, - (char*)ssl->buffers.domainName.buffer) == 0 ) { - WOLFSSL_MSG("DomainName match on alt names failed too"); - ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */ - } - } - } - - /* decode peer key */ - switch (dCert->keyOID) { - #ifndef NO_RSA - case RSAk: - { - word32 idx = 0; - int keyRet = 0; - - if (ssl->peerRsaKey == NULL) { - ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), - ssl->heap, DYNAMIC_TYPE_RSA); - if (ssl->peerRsaKey == NULL) { - WOLFSSL_MSG("PeerRsaKey Memory error"); - keyRet = MEMORY_E; - } else { - keyRet = wc_InitRsaKey_ex(ssl->peerRsaKey, - ssl->heap, ssl->devId); - } - } else if (ssl->peerRsaKeyPresent) { - /* don't leak on reuse */ - wc_FreeRsaKey(ssl->peerRsaKey); - ssl->peerRsaKeyPresent = 0; - keyRet = wc_InitRsaKey_ex(ssl->peerRsaKey, ssl->heap, ssl->devId); - } - - if (keyRet != 0 || wc_RsaPublicKeyDecode(dCert->publicKey, - &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) { - ret = PEER_KEY_ERROR; - } - else { - ssl->peerRsaKeyPresent = 1; - #ifdef HAVE_PK_CALLBACKS - #ifndef NO_RSA - ssl->buffers.peerRsaKey.buffer = - (byte*)XMALLOC(dCert->pubKeySize, - ssl->heap, DYNAMIC_TYPE_RSA); - if (ssl->buffers.peerRsaKey.buffer == NULL) - ret = MEMORY_ERROR; - else { - XMEMCPY(ssl->buffers.peerRsaKey.buffer, - dCert->publicKey, dCert->pubKeySize); - ssl->buffers.peerRsaKey.length = - dCert->pubKeySize; - } - #endif /* NO_RSA */ - #endif /*HAVE_PK_CALLBACKS */ - } - - /* check size of peer RSA key */ - if (ret == 0 && ssl->peerRsaKeyPresent && - !ssl->options.verifyNone && - wc_RsaEncryptSize(ssl->peerRsaKey) - < ssl->options.minRsaKeySz) { - ret = RSA_KEY_SIZE_E; - WOLFSSL_MSG("Peer RSA key is too small"); - } - - } - break; - #endif /* NO_RSA */ - #ifdef HAVE_NTRU - case NTRUk: - { - if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) { - ret = PEER_KEY_ERROR; - } - else { - XMEMCPY(ssl->peerNtruKey, dCert->publicKey, - dCert->pubKeySize); - ssl->peerNtruKeyLen = (word16)dCert->pubKeySize; - ssl->peerNtruKeyPresent = 1; - } - } - break; - #endif /* HAVE_NTRU */ - #ifdef HAVE_ECC - case ECDSAk: - { - int curveId; - if (ssl->peerEccDsaKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->peerEccDsaKey == NULL) { - WOLFSSL_MSG("PeerEccDsaKey Memory error"); - return MEMORY_E; - } - wc_ecc_init_ex(ssl->peerEccDsaKey, ssl->heap, - ssl->devId); - } else if (ssl->peerEccDsaKeyPresent) { - /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccDsaKey); - ssl->peerEccDsaKeyPresent = 0; - wc_ecc_init_ex(ssl->peerEccDsaKey, ssl->heap, - ssl->devId); - } - - curveId = wc_ecc_get_oid(dCert->keyOID, NULL, NULL); - if (wc_ecc_import_x963_ex(dCert->publicKey, - dCert->pubKeySize, ssl->peerEccDsaKey, curveId) != 0) { - ret = PEER_KEY_ERROR; - } - else { - ssl->peerEccDsaKeyPresent = 1; - #ifdef HAVE_PK_CALLBACKS - #ifdef HAVE_ECC - ssl->buffers.peerEccDsaKey.buffer = - (byte*)XMALLOC(dCert->pubKeySize, - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->buffers.peerEccDsaKey.buffer == NULL) - ret = MEMORY_ERROR; - else { - XMEMCPY(ssl->buffers.peerEccDsaKey.buffer, - dCert->publicKey, dCert->pubKeySize); - ssl->buffers.peerEccDsaKey.length = - dCert->pubKeySize; - } - #endif /* HAVE_ECC */ - #endif /*HAVE_PK_CALLBACKS */ - } - - /* check size of peer ECC key */ - if (ret == 0 && ssl->peerEccDsaKeyPresent && - !ssl->options.verifyNone && - wc_ecc_size(ssl->peerEccDsaKey) - < ssl->options.minEccKeySz) { - ret = ECC_KEY_SIZE_E; - WOLFSSL_MSG("Peer ECC key is too small"); - } - - } - break; - #endif /* HAVE_ECC */ - default: - break; - } - - FreeDecodedCert(dCert); - } - -#ifdef WOLFSSL_SMALL_STACK - XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX), - NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (store == NULL) { - XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE_CTX)); - - if (anyError != 0 && ret == 0) - ret = anyError; - - if (ret != 0) { - if (!ssl->options.verifyNone) { - int why = bad_certificate; - - if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) - why = certificate_expired; - if (ssl->verifyCallback) { - int ok; - - store->error = ret; - store->error_depth = totalCerts; - store->discardSessionCerts = 0; - store->domain = domain; - store->userCtx = ssl->verifyCbCtx; - store->certs = certs; - store->totalCerts = totalCerts; -#ifdef KEEP_PEER_CERT - store->current_cert = &ssl->peerCert; -#else - store->current_cert = NULL; -#endif -#if defined(HAVE_EX_DATA) || defined(HAVE_FORTRESS) - store->ex_data = ssl; -#endif - ok = ssl->verifyCallback(0, store); - if (ok) { - WOLFSSL_MSG("Verify callback overriding error!"); - ret = 0; - } - #ifdef SESSION_CERTS - if (store->discardSessionCerts) { - WOLFSSL_MSG("Verify callback requested discard sess certs"); - ssl->session.chain.count = 0; - } - #endif - } - if (ret != 0) { - SendAlert(ssl, alert_fatal, why); /* try to send */ - ssl->options.isClosed = 1; - } - } - ssl->error = ret; - } -#ifdef WOLFSSL_ALWAYS_VERIFY_CB - else { - if (ssl->verifyCallback) { - int ok; - - store->error = ret; -#ifdef WOLFSSL_WPAS - store->error_depth = 0; -#else - store->error_depth = totalCerts; -#endif - store->discardSessionCerts = 0; - store->domain = domain; - store->userCtx = ssl->verifyCbCtx; - store->certs = certs; - store->totalCerts = totalCerts; -#ifdef KEEP_PEER_CERT - store->current_cert = &ssl->peerCert; -#endif - store->ex_data = ssl; - - ok = ssl->verifyCallback(1, store); - if (!ok) { - WOLFSSL_MSG("Verify callback overriding valid certificate!"); - ret = -1; - SendAlert(ssl, alert_fatal, bad_certificate); - ssl->options.isClosed = 1; - } - #ifdef SESSION_CERTS - if (store->discardSessionCerts) { - WOLFSSL_MSG("Verify callback requested discard sess certs"); - ssl->session.chain.count = 0; - } - #endif - } - } -#endif - - if (ssl->options.verifyNone && - (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) { - WOLFSSL_MSG("Ignoring CRL problem based on verify setting"); - ret = ssl->error = 0; - } - - if (ret == 0 && ssl->options.side == WOLFSSL_CLIENT_END) - ssl->options.serverState = SERVER_CERT_COMPLETE; - -#ifdef WOLFSSL_SMALL_STACK - XFREE(store, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} /* Parse and handle a TLS v1.3 Certificate message. * @@ -4241,117 +3602,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, buffer *certs, buffer *exts, int totalCerts) static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz) { - int ret; - word32 listSz; - word32 begin = *inOutIdx; - int totalCerts = 0; /* number of certs in certs buffer */ - buffer certs[MAX_CHAIN_DEPTH]; - buffer exts[MAX_CHAIN_DEPTH]; - byte ctxSz; - - #ifdef WOLFSSL_CALLBACKS - if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo); - if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo); - #endif - - /* Certificate Request Context */ - if ((*inOutIdx - begin) + OPAQUE8_LEN > totalSz) - return BUFFER_ERROR; - ctxSz = *(input + *inOutIdx); - (*inOutIdx)++; - if ((*inOutIdx - begin) + ctxSz > totalSz) - return BUFFER_ERROR; -#ifndef NO_WOLFSSL_CLIENT - /* Must be empty when received from server. */ - if (ssl->options.side == WOLFSSL_CLIENT_END) { - if (ctxSz != 0) { - return INVALID_CERT_CTX_E; - } - } -#endif -#ifndef NO_WOLFSSL_SERVER - /* Must contain value sent in request when received from client. */ - if (ssl->options.side == WOLFSSL_SERVER_END) { - if (ssl->clientCertCtx.length != ctxSz || - XMEMCMP(ssl->clientCertCtx.buffer, input + *inOutIdx, ctxSz) != 0) { - return INVALID_CERT_CTX_E; - } - } -#endif - *inOutIdx += ctxSz; - - /* Certificate List */ - if ((*inOutIdx - begin) + OPAQUE24_LEN > totalSz) - return BUFFER_ERROR; - c24to32(input + *inOutIdx, &listSz); - *inOutIdx += OPAQUE24_LEN; - if (listSz > MAX_RECORD_SIZE) - return BUFFER_E; - if ((*inOutIdx - begin) + listSz != totalSz) - return BUFFER_ERROR; - - WOLFSSL_MSG("Loading peer's cert chain"); - /* Put the indeces into the buffer of the certificates and extensions into - * list so they can be verified top down as they were sent bottom up. - */ - while (listSz) { - word32 certSz; - word16 extSz; - - if (totalCerts >= MAX_CHAIN_DEPTH) - return MAX_CHAIN_ERROR; - - /* Certificate Data */ - if ((*inOutIdx - begin) + OPAQUE24_LEN > totalSz) - return BUFFER_ERROR; - c24to32(input + *inOutIdx, &certSz); - *inOutIdx += OPAQUE24_LEN; - if ((*inOutIdx - begin) + certSz > totalSz) - return BUFFER_ERROR; - /* Store certificate data info for later processing. */ - certs[totalCerts].length = certSz; - certs[totalCerts].buffer = input + *inOutIdx; - -#ifdef SESSION_CERTS - if (ssl->session.chain.count < MAX_CHAIN_DEPTH && - certSz < MAX_X509_SIZE) { - ssl->session.chain.certs[ssl->session.chain.count].length = certSz; - XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer, - input + *inOutIdx, certSz); - ssl->session.chain.count++; - } else { - WOLFSSL_MSG("Couldn't store chain cert for session"); - } -#endif - - *inOutIdx += certSz; - listSz -= certSz + CERT_HEADER_SZ; - - /* Extensions */ - if ((*inOutIdx - begin) + OPAQUE16_LEN > totalSz) - return BUFFER_ERROR; - ato16(input + *inOutIdx, &extSz); - *inOutIdx += OPAQUE16_LEN; - if ((*inOutIdx - begin) + extSz > totalSz) - return BUFFER_ERROR; - /* Store extension data info for later processing. */ - exts[totalCerts].length = extSz; - exts[totalCerts].buffer = input + *inOutIdx; - *inOutIdx += extSz; - listSz -= extSz + OPAQUE16_LEN; - - totalCerts++; - WOLFSSL_MSG(" Put another cert into chain"); - } - - ret = ProcessPeerCerts(ssl, certs, exts, totalCerts); - if (ret != 0) - return ret; - - /* Always encrypted. */ - *inOutIdx += ssl->keys.padSz; - - return 0; + return ProcessPeerCerts(ssl, input, inOutIdx, totalSz); } #if !defined(NO_RSA) || defined(HAVE_ECC) @@ -4366,7 +3617,7 @@ typedef struct Dcv13Args { byte hashAlgo; byte sigAlgo; - byte sigData[MAX_SIG_DATA_SZ]; + byte* sigData; word16 sigDataSz; } Dcv13Args; @@ -4374,8 +3625,12 @@ static void FreeDcv13Args(WOLFSSL* ssl, void* pArgs) { Dcv13Args* args = (Dcv13Args*)pArgs; + if (args->sigData) { + XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + args->sigData = NULL; + } + (void)ssl; - (void)args; } /* Parse and handle a TLS v1.3 CertificateVerify message. @@ -4472,18 +3727,33 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, WOLFSSL_MSG("Oops, peer sent RSA key but not in verify"); } + sig->buffer = XMALLOC(args->sz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (sig->buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_dcv); + } + sig->length = args->sz; + XMEMCPY(sig->buffer, input + args->idx, args->sz); + + #ifdef HAVE_ECC + if (ssl->peerEccDsaKeyPresent) { + WOLFSSL_MSG("Doing ECC peer cert verify"); + + args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (args->sigData == NULL) { + ERROR_OUT(MEMORY_E, exit_dcv); + } + + CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); + } + #endif + /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; } /* case TLS_ASYNC_BUILD */ case TLS_ASYNC_DO: { - sig->buffer = XMALLOC(args->sz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sig->buffer == NULL) - ERROR_OUT(MEMORY_E, exit_dcv); - sig->length = args->sz; - XMEMCPY(sig->buffer, input + args->idx, args->sz); - #ifndef NO_RSA if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent) { WOLFSSL_MSG("Doing RSA peer cert verify"); @@ -4508,8 +3778,6 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, if (ssl->peerEccDsaKeyPresent) { WOLFSSL_MSG("Doing ECC peer cert verify"); - CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); - ret = EccVerify(ssl, input + args->idx, args->sz, args->sigData, args->sigDataSz, ssl->peerEccDsaKey, diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fcb4440b6..ae9c00b97 100755 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1359,8 +1359,7 @@ WOLFSSL_LOCAL void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz); WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); WOLFSSL_LOCAL void FreeKeyExchange(WOLFSSL* ssl); -WOLFSSL_LOCAL int ProcessPeerCerts(WOLFSSL* ssl, buffer *certs, buffer *exts, - int totalCerts); +WOLFSSL_LOCAL int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 size); WOLFSSL_LOCAL int MatchDomainName(const char* pattern, int len, const char* str); #ifndef NO_CERTS WOLFSSL_LOCAL int CheckAltNames(DecodedCert* dCert, char* domain);