From 58bd6a8d9431f16b3745cae4d4dd504a8c170eb0 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 6 Nov 2025 11:35:26 +1000 Subject: [PATCH 1/2] TLS 1.2 CertificateVerify: validate sig alg matches peer key Don't proceed with parsing CertificateVerify message in TLS 1.2 if the signature algorithm doesn't match the peer's key (key from client certificate). --- src/internal.c | 177 ++++++++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 77 deletions(-) diff --git a/src/internal.c b/src/internal.c index 88caf2d736..40508bbe76 100644 --- a/src/internal.c +++ b/src/internal.c @@ -38575,51 +38575,70 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, DecodeSigAlg(&input[args->idx], &ssl->options.peerHashAlgo, &ssl->options.peerSigAlgo); args->idx += 2; - } - #ifndef NO_RSA - else if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) - ssl->options.peerSigAlgo = rsa_sa_algo; - #endif - #ifdef HAVE_ECC - else if (ssl->peerEccDsaKeyPresent) { - #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) - if (ssl->peerEccDsaKey->dp->id == ECC_SM2P256V1) { - ssl->options.peerSigAlgo = sm2_sa_algo; + + #ifndef NO_RSA + if (ssl->peerRsaKeyPresent) { + if (ssl->options.peerSigAlgo != rsa_sa_algo + #ifdef WC_RSA_PSS + && ssl->options.peerSigAlgo != rsa_pss_sa_algo + #endif + ) { + WOLFSSL_MSG("Oops, peer sent RSA key but not in " + "verify"); + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } } else #endif - { - ssl->options.peerSigAlgo = ecc_dsa_sa_algo; + #ifdef HAVE_ECC + if (ssl->peerEccDsaKeyPresent) { + if (ssl->options.peerSigAlgo != ecc_dsa_sa_algo + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + && ssl->options.peerSigAlgo != sm2_sa_algo + #endif + ) { + WOLFSSL_MSG("Oops, peer sent ECC key but not in " + "verify"); + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->options.peerSigAlgo == sm2_sa_algo && + ssl->options.peerHashAlgo != sm3_mac) { + WOLFSSL_MSG("SM2 with SM3 only"); + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } + #endif } + else + #endif + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) + if (ssl->peerEd25519KeyPresent) { + if (ssl->options.peerSigAlgo != ed25519_sa_algo) { + WOLFSSL_MSG("Oops, peer sent Ed25519 key but not " + "in verify"); + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } + } + else + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + if (ssl->peerEd448KeyPresent) { + if (ssl->options.peerSigAlgo != ed448_sa_algo) { + WOLFSSL_MSG("Oops, peer sent Ed448 key but not in " + "verify"); + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } + } + else + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ + { + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } + + SetDigest(ssl, ssl->options.peerHashAlgo); } - #endif - #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) - else if (ssl->peerEd25519KeyPresent) - ssl->options.peerSigAlgo = ed25519_sa_algo; - #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ - #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) - else if (ssl->peerEd448KeyPresent) - ssl->options.peerSigAlgo = ed448_sa_algo; - #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ - - if ((args->idx - args->begin) + OPAQUE16_LEN > size) { - ERROR_OUT(BUFFER_ERROR, exit_dcv); - } - - ato16(input + args->idx, &args->sz); - args->idx += OPAQUE16_LEN; - - if ((args->idx - args->begin) + args->sz > size || - args->sz > ENCRYPT_LEN) { - ERROR_OUT(BUFFER_ERROR, exit_dcv); - } - - #ifdef HAVE_ECC - if (ssl->peerEccDsaKeyPresent) { - - WOLFSSL_MSG("Doing ECC peer cert verify"); - - /* make sure a default is defined */ + else { + /* make sure a default is defined */ #if !defined(NO_SHA) SetDigest(ssl, sha_mac); #elif !defined(NO_SHA256) @@ -38634,39 +38653,51 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #error No digest enabled for ECC sig verify #endif - if (IsAtLeastTLSv1_2(ssl)) { - if (ssl->options.peerSigAlgo != ecc_dsa_sa_algo - #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) - && ssl->options.peerSigAlgo != sm2_sa_algo - #endif - ) { - WOLFSSL_MSG("Oops, peer sent ECC key but not in verify"); + #ifndef NO_RSA + if (ssl->peerRsaKeyPresent) + ssl->options.peerSigAlgo = rsa_sa_algo; + else + #endif + #ifdef HAVE_ECC + if (ssl->peerEccDsaKeyPresent) { + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + if (ssl->peerEccDsaKey->dp->id == ECC_SM2P256V1) { + ssl->options.peerSigAlgo = sm2_sa_algo; } + else + #endif + { + ssl->options.peerSigAlgo = ecc_dsa_sa_algo; + } + } + else + #endif + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) + if (ssl->peerEd25519KeyPresent) + ssl->options.peerSigAlgo = ed25519_sa_algo; + else + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + if (ssl->peerEd448KeyPresent) + ssl->options.peerSigAlgo = ed448_sa_algo; + else + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ + { + ERROR_OUT(NO_PEER_KEY, exit_dcv); + } + } - SetDigest(ssl, ssl->options.peerHashAlgo); - } + if ((args->idx - args->begin) + OPAQUE16_LEN > size) { + ERROR_OUT(BUFFER_ERROR, exit_dcv); } - #endif /* HAVE_ECC */ - #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) - if (ssl->peerEd25519KeyPresent) { - WOLFSSL_MSG("Doing ED25519 peer cert verify"); - if (IsAtLeastTLSv1_2(ssl) && - ssl->options.peerSigAlgo != ed25519_sa_algo) { - WOLFSSL_MSG( - "Oops, peer sent ED25519 key but not in verify"); - } + + ato16(input + args->idx, &args->sz); + args->idx += OPAQUE16_LEN; + + if ((args->idx - args->begin) + args->sz > size || + args->sz > ENCRYPT_LEN) { + ERROR_OUT(BUFFER_ERROR, exit_dcv); } - #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ - #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) - if (ssl->peerEd448KeyPresent) { - WOLFSSL_MSG("Doing ED448 peer cert verify"); - if (IsAtLeastTLSv1_2(ssl) && - ssl->options.peerSigAlgo != ed448_sa_algo) { - WOLFSSL_MSG( - "Oops, peer sent ED448 key but not in verify"); - } - } - #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -38803,8 +38834,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (IsAtLeastTLSv1_2(ssl)) { #ifdef WC_RSA_PSS if (ssl->options.peerSigAlgo == rsa_pss_sa_algo) { - SetDigest(ssl, ssl->options.peerHashAlgo); - #ifdef HAVE_SELFTEST ret = wc_RsaPSS_CheckPadding( ssl->buffers.digest.buffer, @@ -38837,12 +38866,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif - if (ssl->options.peerSigAlgo != rsa_sa_algo) { - WOLFSSL_MSG("Oops, peer sent RSA key but not " - "in verify"); - } - - SetDigest(ssl, ssl->options.peerHashAlgo); args->sigSz = wc_EncodeSignature(encodedSig, ssl->buffers.digest.buffer, From f54ca0d481fae9bfa86011ff37d2911c824be073 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 7 Nov 2025 12:29:08 +1000 Subject: [PATCH 2/2] TLS 1.2 CertificateVerify: req sig alg to have been in CR The signature algorithm specified in CertificateVerify must have been in the CertificateRequest. Add check. The cipher suite test cases, when client auth and RSA are built-in and use the default client certificate and use the *-ECDSA-* cipher suites, no longer work. The client certificate must be ECC when the cipher suite has ECDSA. Don't run them for that build. --- src/internal.c | 19 ++- tests/api/test_tls.c | 321 ++++++++++++++++++++++++++++++++++++++++++ tests/api/test_tls.h | 6 +- tests/suites.c | 87 +++++++++--- tests/test-fails.conf | 17 +++ 5 files changed, 420 insertions(+), 30 deletions(-) diff --git a/src/internal.c b/src/internal.c index 40508bbe76..963fa4403c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -37338,11 +37338,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(outSuites->suites, &suites, sizeof(suites)); #ifdef WOLFSSL_DEBUG_TLS { - int ii; + word16 ii; WOLFSSL_MSG("Refined Ciphers:"); - for (ii = 0 ; ii < suites->suiteSz; ii += 2) { - WOLFSSL_MSG(GetCipherNameInternal(suites->suites[ii+0], - suites->suites[ii+1])); + for (ii = 0 ; ii < outSuites->suiteSz; ii += 2) { + WOLFSSL_MSG(GetCipherNameInternal(outSuites->suites[ii+0], + outSuites->suites[ii+1])); } } #endif @@ -38568,10 +38568,19 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case TLS_ASYNC_BUILD: { if (IsAtLeastTLSv1_2(ssl)) { - if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > size) { + if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > + size) { ERROR_OUT(BUFFER_ERROR, exit_dcv); } + /* Check if hashSigAlgo in CertificateVerify is supported + * in our ssl->suites or ssl->ctx->suites. */ + if (!SupportedHashSigAlgo(ssl, &input[args->idx])) { + WOLFSSL_MSG("Signature algorithm was not in " + "CertificateRequest"); + ERROR_OUT(INVALID_PARAMETER, exit_dcv); + } + DecodeSigAlg(&input[args->idx], &ssl->options.peerHashAlgo, &ssl->options.peerSigAlgo); args->idx += 2; diff --git a/tests/api/test_tls.c b/tests/api/test_tls.c index 11a8748544..91cf524599 100644 --- a/tests/api/test_tls.c +++ b/tests/api/test_tls.c @@ -345,3 +345,324 @@ int test_tls_certreq_order(void) return EXPECT_RESULT(); } +#if !defined(WOLFSSL_NO_TLS12) && !defined(NO_RSA) && defined(HAVE_ECC) && \ + !defined(NO_WOLFSSL_SERVER) +/* Called when writing. */ +static int CsSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) +{ + (void)ssl; + (void)buf; + (void)ctx; + + return sz; +} +/* Called when reading. */ +static int CsRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) +{ + WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx; + int len = (int)msg->length; + + (void)ssl; + (void)sz; + + /* Pass back as much of message as will fit in buffer. */ + if (len > sz) + len = sz; + XMEMCPY(buf, msg->buffer, len); + /* Move over returned data. */ + msg->buffer += len; + msg->length -= len; + + /* Amount actually copied. */ + return len; +} +#endif + +int test_tls12_bad_cv_sig_alg(void) +{ + EXPECT_DECLS; +#if !defined(WOLFSSL_NO_TLS12) && !defined(NO_RSA) && defined(HAVE_ECC) && \ + !defined(NO_WOLFSSL_SERVER) + byte clientMsgs[] = { + /* Client Hello */ + 0x16, 0x03, 0x03, 0x00, 0xe7, + 0x01, 0x00, 0x00, 0xe3, 0x03, 0x03, 0x65, 0x27, + 0x41, 0xdf, 0xd9, 0x17, 0xdb, 0x02, 0x5c, 0x2e, + 0xf8, 0x4b, 0x77, 0x86, 0x5a, 0x20, 0x57, 0x7f, + 0xc0, 0xe7, 0xef, 0x8f, 0x56, 0xef, 0xfa, 0x71, + 0x36, 0xec, 0x55, 0x1d, 0x4e, 0xa2, 0x00, 0x00, + 0x64, 0xc0, 0x2c, 0xc0, 0x2b, 0xc0, 0x30, 0xc0, + 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0x00, 0xab, 0x00, + 0x34, 0x00, 0xa7, 0x00, 0xaa, 0xcc, 0xa9, 0xcc, + 0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, + 0x28, 0xc0, 0x24, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, + 0x07, 0xc0, 0x14, 0xc0, 0x13, 0xc0, 0x11, 0xc0, + 0xac, 0xc0, 0xae, 0xc0, 0xaf, 0x00, 0x6b, 0x00, + 0x67, 0x00, 0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, + 0x13, 0xcc, 0x15, 0xc0, 0x06, 0x00, 0xb3, 0x00, + 0xb2, 0xc0, 0xa6, 0xc0, 0xa7, 0xcc, 0xab, 0xcc, + 0xac, 0xcc, 0xad, 0xc0, 0x37, 0xd0, 0x01, 0x00, + 0xb5, 0xc0, 0x3a, 0x00, 0xb4, 0x00, 0x45, 0x00, + 0x88, 0x00, 0xbe, 0x00, 0xc4, 0x01, 0x00, 0x00, + 0x56, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x1e, 0x06, + 0x03, 0x05, 0x03, 0x04, 0x03, 0x08, 0x07, 0x08, + 0x08, 0x08, 0x06, 0x08, 0x0b, 0x08, 0x05, 0x08, + 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01, 0x05, + 0x01, 0x04, 0x01, 0x03, 0x01, 0x00, 0x0b, 0x00, + 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x1c, 0x00, + 0x1a, 0x00, 0x19, 0x00, 0x1c, 0x00, 0x18, 0x00, + 0x1b, 0x00, 0x1e, 0x00, 0x17, 0x00, 0x16, 0x00, + 0x1a, 0x00, 0x1d, 0x00, 0x15, 0x00, 0x14, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + /* Certificate */ + 0x16, 0x03, 0x03, 0x05, 0x2b, + 0x0b, 0x00, 0x05, 0x27, 0x00, 0x05, 0x24, 0x00, + 0x05, 0x21, 0x30, 0x82, 0x05, 0x1d, 0x30, 0x82, + 0x04, 0x05, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x14, 0x4f, 0x0d, 0x8c, 0xc5, 0xfa, 0xee, 0xa2, + 0x9b, 0xb7, 0x35, 0x9e, 0xe9, 0x4a, 0x17, 0x99, + 0xf0, 0xcc, 0x23, 0xf2, 0xec, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x9e, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x4d, + 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, 0x6e, + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x0c, 0x77, 0x6f, 0x6c, 0x66, 0x53, + 0x53, 0x4c, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x31, + 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x10, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, + 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2d, 0x32, 0x30, + 0x34, 0x38, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77, + 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, + 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, + 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, + 0x0d, 0x32, 0x34, 0x31, 0x32, 0x31, 0x38, 0x32, + 0x31, 0x32, 0x35, 0x32, 0x39, 0x5a, 0x17, 0x0d, + 0x32, 0x37, 0x30, 0x39, 0x31, 0x34, 0x32, 0x31, + 0x32, 0x35, 0x32, 0x39, 0x5a, 0x30, 0x81, 0x9e, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, + 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, + 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0c, 0x77, 0x6f, 0x6c, 0x66, + 0x53, 0x53, 0x4c, 0x5f, 0x32, 0x30, 0x34, 0x38, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x10, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2d, 0x32, + 0x30, 0x34, 0x38, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, + 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, + 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, + 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, + 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, + 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc3, + 0x03, 0xd1, 0x2b, 0xfe, 0x39, 0xa4, 0x32, 0x45, + 0x3b, 0x53, 0xc8, 0x84, 0x2b, 0x2a, 0x7c, 0x74, + 0x9a, 0xbd, 0xaa, 0x2a, 0x52, 0x07, 0x47, 0xd6, + 0xa6, 0x36, 0xb2, 0x07, 0x32, 0x8e, 0xd0, 0xba, + 0x69, 0x7b, 0xc6, 0xc3, 0x44, 0x9e, 0xd4, 0x81, + 0x48, 0xfd, 0x2d, 0x68, 0xa2, 0x8b, 0x67, 0xbb, + 0xa1, 0x75, 0xc8, 0x36, 0x2c, 0x4a, 0xd2, 0x1b, + 0xf7, 0x8b, 0xba, 0xcf, 0x0d, 0xf9, 0xef, 0xec, + 0xf1, 0x81, 0x1e, 0x7b, 0x9b, 0x03, 0x47, 0x9a, + 0xbf, 0x65, 0xcc, 0x7f, 0x65, 0x24, 0x69, 0xa6, + 0xe8, 0x14, 0x89, 0x5b, 0xe4, 0x34, 0xf7, 0xc5, + 0xb0, 0x14, 0x93, 0xf5, 0x67, 0x7b, 0x3a, 0x7a, + 0x78, 0xe1, 0x01, 0x56, 0x56, 0x91, 0xa6, 0x13, + 0x42, 0x8d, 0xd2, 0x3c, 0x40, 0x9c, 0x4c, 0xef, + 0xd1, 0x86, 0xdf, 0x37, 0x51, 0x1b, 0x0c, 0xa1, + 0x3b, 0xf5, 0xf1, 0xa3, 0x4a, 0x35, 0xe4, 0xe1, + 0xce, 0x96, 0xdf, 0x1b, 0x7e, 0xbf, 0x4e, 0x97, + 0xd0, 0x10, 0xe8, 0xa8, 0x08, 0x30, 0x81, 0xaf, + 0x20, 0x0b, 0x43, 0x14, 0xc5, 0x74, 0x67, 0xb4, + 0x32, 0x82, 0x6f, 0x8d, 0x86, 0xc2, 0x88, 0x40, + 0x99, 0x36, 0x83, 0xba, 0x1e, 0x40, 0x72, 0x22, + 0x17, 0xd7, 0x52, 0x65, 0x24, 0x73, 0xb0, 0xce, + 0xef, 0x19, 0xcd, 0xae, 0xff, 0x78, 0x6c, 0x7b, + 0xc0, 0x12, 0x03, 0xd4, 0x4e, 0x72, 0x0d, 0x50, + 0x6d, 0x3b, 0xa3, 0x3b, 0xa3, 0x99, 0x5e, 0x9d, + 0xc8, 0xd9, 0x0c, 0x85, 0xb3, 0xd9, 0x8a, 0xd9, + 0x54, 0x26, 0xdb, 0x6d, 0xfa, 0xac, 0xbb, 0xff, + 0x25, 0x4c, 0xc4, 0xd1, 0x79, 0xf4, 0x71, 0xd3, + 0x86, 0x40, 0x18, 0x13, 0xb0, 0x63, 0xb5, 0x72, + 0x4e, 0x30, 0xc4, 0x97, 0x84, 0x86, 0x2d, 0x56, + 0x2f, 0xd7, 0x15, 0xf7, 0x7f, 0xc0, 0xae, 0xf5, + 0xfc, 0x5b, 0xe5, 0xfb, 0xa1, 0xba, 0xd3, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4f, + 0x30, 0x82, 0x01, 0x4b, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x33, + 0xd8, 0x45, 0x66, 0xd7, 0x68, 0x87, 0x18, 0x7e, + 0x54, 0x0d, 0x70, 0x27, 0x91, 0xc7, 0x26, 0xd7, + 0x85, 0x65, 0xc0, 0x30, 0x81, 0xde, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x81, 0xd6, 0x30, 0x81, + 0xd3, 0x80, 0x14, 0x33, 0xd8, 0x45, 0x66, 0xd7, + 0x68, 0x87, 0x18, 0x7e, 0x54, 0x0d, 0x70, 0x27, + 0x91, 0xc7, 0x26, 0xd7, 0x85, 0x65, 0xc0, 0xa1, + 0x81, 0xa4, 0xa4, 0x81, 0xa1, 0x30, 0x81, 0x9e, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, + 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, + 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0c, 0x77, 0x6f, 0x6c, 0x66, + 0x53, 0x53, 0x4c, 0x5f, 0x32, 0x30, 0x34, 0x38, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x10, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2d, 0x32, + 0x30, 0x34, 0x38, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, + 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, + 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, + 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, + 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, + 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x14, + 0x4f, 0x0d, 0x8c, 0xc5, 0xfa, 0xee, 0xa2, 0x9b, + 0xb7, 0x35, 0x9e, 0xe9, 0x4a, 0x17, 0x99, 0xf0, + 0xcc, 0x23, 0xf2, 0xec, 0x30, 0x0c, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xff, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x15, 0x30, 0x13, 0x82, 0x0b, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, + 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x46, 0xab, 0xe4, 0x6d, 0xae, + 0x49, 0x5b, 0x6a, 0x0b, 0xa9, 0x87, 0xe1, 0x95, + 0x32, 0xa6, 0xd7, 0xae, 0xde, 0x28, 0xdc, 0xc7, + 0x99, 0x68, 0xe2, 0x5f, 0xc9, 0x5a, 0x4c, 0x64, + 0xb8, 0xf5, 0x28, 0x42, 0x5a, 0xe8, 0x5c, 0x59, + 0x32, 0xfe, 0xd0, 0x1f, 0x0b, 0x55, 0x89, 0xdb, + 0x67, 0xe7, 0x78, 0xf3, 0x70, 0xcf, 0x18, 0x51, + 0x57, 0x8b, 0xf3, 0x2b, 0xa4, 0x66, 0x0b, 0xf6, + 0x03, 0x6e, 0x11, 0xac, 0x83, 0x52, 0x16, 0x7e, + 0xa2, 0x7c, 0x36, 0x77, 0xf6, 0xbb, 0x13, 0x19, + 0x40, 0x2c, 0xb8, 0x8c, 0xca, 0xd6, 0x7e, 0x79, + 0x7d, 0xf4, 0x14, 0x8d, 0xb5, 0xa4, 0x09, 0xf6, + 0x2d, 0x4c, 0xe7, 0xf9, 0xb8, 0x25, 0x41, 0x15, + 0x78, 0xf4, 0xca, 0x80, 0x41, 0xea, 0x3a, 0x05, + 0x08, 0xf6, 0xb5, 0x5b, 0xa1, 0x3b, 0x5b, 0x48, + 0xa8, 0x4b, 0x8c, 0x19, 0x8d, 0x6c, 0x87, 0x31, + 0x76, 0x74, 0x02, 0x16, 0x8b, 0xdd, 0x7f, 0xd1, + 0x11, 0x62, 0x27, 0x42, 0x39, 0xe0, 0x9a, 0x63, + 0x26, 0x31, 0x19, 0xce, 0x3d, 0x41, 0xd5, 0x24, + 0x47, 0x32, 0x0f, 0x76, 0xd6, 0x41, 0x37, 0x44, + 0xad, 0x73, 0xf1, 0xb8, 0xec, 0x2b, 0x6e, 0x9c, + 0x4f, 0x84, 0xc4, 0x4e, 0xd7, 0x92, 0x10, 0x7e, + 0x23, 0x32, 0xa0, 0x75, 0x6a, 0xe7, 0xfe, 0x55, + 0x95, 0x9f, 0x0a, 0xad, 0xdf, 0xf9, 0x2a, 0xa2, + 0x1a, 0x59, 0xd5, 0x82, 0x63, 0xd6, 0x5d, 0x7d, + 0x79, 0xf4, 0xa7, 0x2d, 0xdc, 0x8c, 0x04, 0xcd, + 0x98, 0xb0, 0x42, 0x0e, 0x84, 0xfa, 0x86, 0x50, + 0x10, 0x61, 0xac, 0x73, 0xcd, 0x79, 0x45, 0x30, + 0xe8, 0x42, 0xa1, 0x6a, 0xf6, 0x77, 0x55, 0xec, + 0x07, 0xdb, 0x52, 0x29, 0xca, 0x7a, 0xc8, 0xa2, + 0xda, 0xe9, 0xf5, 0x98, 0x33, 0x6a, 0xe8, 0xbc, + 0x89, 0xed, 0x01, 0xe2, 0xfe, 0x44, 0x86, 0x86, + 0x80, 0x39, 0xec, + /* ClientKeyExchange */ + 0x16, 0x03, 0x03, 0x00, 0x46, + 0x10, 0x00, 0x00, 0x42, 0x41, 0x04, 0xc5, 0xb9, + 0x0f, 0xbc, 0x84, 0xe6, 0x0c, 0x02, 0xa6, 0x8d, + 0x34, 0xa6, 0x3e, 0x1e, 0xb7, 0x88, 0xb8, 0x68, + 0x29, 0x2b, 0x85, 0x67, 0xe2, 0x62, 0x4d, 0xd9, + 0xa4, 0x38, 0xb3, 0xec, 0x33, 0xa1, 0xe5, 0xe1, + 0xae, 0xe9, 0x07, 0xd1, 0xea, 0x1b, 0xec, 0xa6, + 0xaf, 0x1f, 0x80, 0x87, 0x7c, 0x53, 0x80, 0x04, + 0xee, 0x20, 0xeb, 0x64, 0x0d, 0xa0, 0xf7, 0x62, + 0xb1, 0xcc, 0x73, 0x97, 0xf5, 0x80, + /* CertificateVerify */ + 0x16, 0x03, 0x03, 0x01, 0x08, + /* 0x04 - sha256, changed to 0x02 - sha1 */ + 0x0f, 0x00, 0x01, 0x04, 0x08, 0x02, 0x01, 0x00, + 0x8b, 0x09, 0xa4, 0x58, 0x8d, 0x68, 0xd9, 0xc9, + 0xef, 0xe9, 0xa5, 0x98, 0x7f, 0xa3, 0xa9, 0x7b, + 0x56, 0xf7, 0xaa, 0x5f, 0x8f, 0x47, 0x7f, 0xd0, + 0x7b, 0xcf, 0x4f, 0x84, 0xe1, 0xa9, 0x0e, 0xa8, + 0x83, 0x19, 0xd8, 0xb3, 0x97, 0x23, 0x98, 0xc5, + 0x2b, 0x56, 0x82, 0x66, 0x94, 0xcc, 0xd7, 0x23, + 0xe6, 0x6e, 0x60, 0x83, 0x78, 0xfb, 0xaf, 0x8e, + 0x8b, 0xae, 0x1f, 0x3c, 0x34, 0x96, 0x3b, 0xd5, + 0x8d, 0x1e, 0xaf, 0x98, 0x1d, 0x27, 0x86, 0x97, + 0x42, 0xd4, 0xfc, 0x62, 0xbc, 0x43, 0x94, 0x98, + 0x19, 0x26, 0x87, 0xb0, 0x8c, 0xb5, 0x22, 0xa7, + 0x6a, 0x5e, 0x56, 0x73, 0x0a, 0x75, 0xc9, 0xb9, + 0x0e, 0xf7, 0x49, 0x4f, 0xa2, 0x0f, 0xfb, 0xdf, + 0x3e, 0xe4, 0xc8, 0x31, 0x26, 0xc5, 0x5c, 0x83, + 0x9f, 0x13, 0xcb, 0x4c, 0xdc, 0x21, 0xe6, 0x24, + 0x2d, 0xd3, 0xe8, 0x18, 0x04, 0xaf, 0x5c, 0x42, + 0x03, 0xa3, 0x0a, 0xb5, 0xfc, 0xb9, 0xbc, 0x8e, + 0xd3, 0xe0, 0x78, 0xdc, 0xef, 0xb9, 0x91, 0x9f, + 0x5b, 0xdc, 0xe3, 0x84, 0xd2, 0xca, 0x32, 0x33, + 0x00, 0x7c, 0x13, 0xd3, 0x2d, 0x85, 0x65, 0x00, + 0xc0, 0xb0, 0xde, 0x85, 0x37, 0x38, 0x18, 0xd2, + 0x81, 0xd4, 0x35, 0xeb, 0xf1, 0xfb, 0x9f, 0x6c, + 0x96, 0x95, 0xf5, 0xaa, 0xfd, 0x22, 0xca, 0x20, + 0xfd, 0x3b, 0xa9, 0xa7, 0xb6, 0x5a, 0x26, 0x02, + 0xb6, 0x0e, 0xdd, 0xaa, 0x0f, 0xa8, 0x96, 0x18, + 0xaa, 0xb1, 0x79, 0x9c, 0x17, 0xb0, 0x7e, 0xa7, + 0x4f, 0xc0, 0x98, 0x27, 0xbe, 0xac, 0x00, 0xda, + 0x3b, 0x2e, 0xd4, 0x11, 0x41, 0x54, 0x34, 0x53, + 0x5f, 0xc5, 0xcd, 0x72, 0xd7, 0x36, 0x04, 0xe1, + 0x7f, 0xcf, 0x1e, 0x01, 0x97, 0xec, 0xeb, 0xad, + 0x1c, 0xc6, 0x7f, 0x2d, 0x8c, 0x68, 0x29, 0xd1, + 0x93, 0x47, 0x59, 0xc0, 0xe2, 0x4a, 0x36, 0x6c + }; + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + WOLFSSL_BUFFER_INFO msg; + + /* Set up wolfSSL context. */ + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())); + ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, + CERT_FILETYPE)); + ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, + CERT_FILETYPE)); + if (EXPECT_SUCCESS()) { + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL); + } + /* Read from 'msg'. */ + wolfSSL_SetIORecv(ctx, CsRecv); + /* No where to send to - dummy sender. */ + wolfSSL_SetIOSend(ctx, CsSend); + + ExpectNotNull(ssl = wolfSSL_new(ctx)); + msg.buffer = clientMsgs; + msg.length = (unsigned int)sizeof(clientMsgs); + if (EXPECT_SUCCESS()) { + wolfSSL_SetIOReadCtx(ssl, &msg); + } + /* Read all message include CertificateVerify with invalid signature + * algorithm. */ + ExpectIntEQ(wolfSSL_accept(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)); + /* Expect an invalid parameter error. */ + ExpectIntEQ(wolfSSL_get_error(ssl, WOLFSSL_FATAL_ERROR), -425); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif + return EXPECT_RESULT(); +} + diff --git a/tests/api/test_tls.h b/tests/api/test_tls.h index ea2c2c680e..b964503bac 100644 --- a/tests/api/test_tls.h +++ b/tests/api/test_tls.h @@ -28,6 +28,7 @@ int test_tls13_unexpected_ccs(void); int test_tls12_curve_intersection(void); int test_tls13_curve_intersection(void); int test_tls_certreq_order(void); +int test_tls12_bad_cv_sig_alg(void); #define TEST_TLS_DECLS \ TEST_DECL_GROUP("tls", test_utils_memio_move_message), \ @@ -35,6 +36,7 @@ int test_tls_certreq_order(void); TEST_DECL_GROUP("tls", test_tls13_unexpected_ccs), \ TEST_DECL_GROUP("tls", test_tls12_curve_intersection), \ TEST_DECL_GROUP("tls", test_tls13_curve_intersection), \ - TEST_DECL_GROUP("tls", test_tls_certreq_order) + TEST_DECL_GROUP("tls", test_tls_certreq_order), \ + TEST_DECL_GROUP("tls", test_tls12_bad_cv_sig_alg) -#endif /* TESTS_API_TEST_TLS_EMS_H */ +#endif /* TESTS_API_TEST_TLS_H */ diff --git a/tests/suites.c b/tests/suites.c index 8f51494269..60a727ea02 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -358,6 +358,20 @@ static int IsNoClientCert(const char* line) } #endif +#if (defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ + !defined(NO_RSA) && !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH) +static int IsEcdsaCipherSuiteDefRsaCert(const char* line) +{ + int found; + + found = (strstr(line, "-ECDSA-") != NULL); + found &= (strstr(line, "-c ") == NULL); + found &= (strstr(line, "-x") == NULL); + + return found; +} +#endif + static int execute_test_case(int svr_argc, char** svr_argv, int cli_argc, char** cli_argv, int addNoVerify, int addNonBlocking, @@ -529,6 +543,56 @@ static int execute_test_case(int svr_argc, char** svr_argv, svrTestShouldFail = 1; } + + commandLine[0] = '\0'; + added = 0; + for (i = 0; i < cliArgs.argc; i++) { + added += XSTRLEN(cli_argv[i]) + 2; + if (added >= MAX_COMMAND_SZ) { + printf("client command line too long\n"); + break; + } + XSTRLCAT(commandLine, cli_argv[i], sizeof commandLine); + XSTRLCAT(commandLine, flagSep, sizeof commandLine); + } + if (!IsValidCA(commandLine)) { + #ifdef DEBUG_SUITE_TESTS + printf("certificate %s not supported in build\n", commandLine); + #endif + return NOT_BUILT_IN; + } +#ifdef WOLFSSL_NO_CLIENT_AUTH + if (reqClientCert && IsNoClientCert(commandLine)) { + #ifdef DEBUG_SUITE_TESTS + printf("client auth on line %s not supported in build\n", + commandLine); + #endif + return NOT_BUILT_IN; + } +#else + if (!IsValidCert(commandLine)) { + #ifdef DEBUG_SUITE_TESTS + printf("certificate %s not supported in build\n", commandLine); + #endif + return NOT_BUILT_IN; + } +#endif +#ifdef NO_CERTS + if (IsNoClientCert(commandLine)) { + #ifdef DEBUG_SUITE_TESTS + printf("certificate %s not supported in build\n", commandLine); + #endif + return NOT_BUILT_IN; + } +#endif +#if (defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ + !defined(NO_RSA) && !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH) + if (IsEcdsaCipherSuiteDefRsaCert(commandLine)) { + return NOT_BUILT_IN; + } +#endif + + InitTcpReady(&ready); #if defined(WOLFSSL_SRTP) && defined(WOLFSSL_COND) @@ -596,29 +660,6 @@ static int execute_test_case(int svr_argc, char** svr_argv, XSTRLCAT(commandLine, cli_argv[i], sizeof commandLine); XSTRLCAT(commandLine, flagSep, sizeof commandLine); } - if (!IsValidCA(commandLine)) { - #ifdef DEBUG_SUITE_TESTS - printf("certificate %s not supported in build\n", commandLine); - #endif - return NOT_BUILT_IN; - } -#ifdef WOLFSSL_NO_CLIENT_AUTH - if (reqClientCert && IsNoClientCert(commandLine)) { - #ifdef DEBUG_SUITE_TESTS - printf("client auth on line %s not supported in build\n", - commandLine); - #endif - return NOT_BUILT_IN; - } -#endif -#ifdef NO_CERTS - if (IsNoClientCert(commandLine)) { - #ifdef DEBUG_SUITE_TESTS - printf("certificate %s not supported in build\n", commandLine); - #endif - return NOT_BUILT_IN; - } -#endif printf("trying client command line[%d]: %s\n", tests, commandLine); tests++; diff --git a/tests/test-fails.conf b/tests/test-fails.conf index 40afb54e0f..66edd321b2 100644 --- a/tests/test-fails.conf +++ b/tests/test-fails.conf @@ -176,6 +176,23 @@ -l ECDHE-ECDSA-AES128-GCM-SHA256 -H verifyFail +# Client is using RSA certificate with ECDSA cipher suite. Server will fail. +# server +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem +-A ./certs/client-cert.pem +-H exitWithRet + +# client +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/client-cert.pem +-k ./certs/client-key.pem +-A ./certs/ca-ecc-cert.pem +-H exitWithRet + # server send alert on no mutual authentication -v 3 -F