Skip to content

Commit babc5d3

Browse files
committed
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).
1 parent 3ec882c commit babc5d3

File tree

1 file changed

+97
-74
lines changed

1 file changed

+97
-74
lines changed

src/internal.c

Lines changed: 97 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -38575,51 +38575,70 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3857538575
DecodeSigAlg(&input[args->idx], &ssl->options.peerHashAlgo,
3857638576
&ssl->options.peerSigAlgo);
3857738577
args->idx += 2;
38578-
}
38579-
#ifndef NO_RSA
38580-
else if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0)
38581-
ssl->options.peerSigAlgo = rsa_sa_algo;
38582-
#endif
38583-
#ifdef HAVE_ECC
38584-
else if (ssl->peerEccDsaKeyPresent) {
38585-
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
38586-
if (ssl->peerEccDsaKey->dp->id == ECC_SM2P256V1) {
38587-
ssl->options.peerSigAlgo = sm2_sa_algo;
38578+
38579+
#ifndef NO_RSA
38580+
if (ssl->peerRsaKeyPresent) {
38581+
if (ssl->options.peerSigAlgo != rsa_sa_algo
38582+
#ifdef WC_RSA_PSS
38583+
&& ssl->options.peerSigAlgo != rsa_pss_sa_algo
38584+
#endif
38585+
) {
38586+
WOLFSSL_MSG("Oops, peer sent RSA key but not in "
38587+
"verify");
38588+
ERROR_OUT(INVALID_PARAMETER, exit_dcv);
38589+
}
3858838590
}
3858938591
else
3859038592
#endif
38593+
#ifdef HAVE_ECC
38594+
if (ssl->peerEccDsaKeyPresent) {
38595+
if (ssl->options.peerSigAlgo != ecc_dsa_sa_algo
38596+
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
38597+
&& ssl->options.peerSigAlgo != sm2_sa_algo
38598+
#endif
38599+
) {
38600+
WOLFSSL_MSG("Oops, peer sent ECC key but not in "
38601+
"verify");
38602+
ERROR_OUT(INVALID_PARAMETER, exit_dcv);
38603+
}
38604+
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
38605+
if (ssl->options.peerSigAlgo == sm2_sa_algo &&
38606+
ssl->options.peerHashAlgo != sm3_mac) {
38607+
WOLFSSL_MSG("SM2 with SM3 only");
38608+
ERROR_OUT(INVALID_PARAMETER, exit_dcv);
38609+
}
38610+
#endif
38611+
}
38612+
else
38613+
#endif
38614+
#if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
38615+
if (ssl->peerEd25519KeyPresent) {
38616+
if (ssl->options.peerSigAlgo != ed25519_sa_algo) {
38617+
WOLFSSL_MSG("Oops, peer sent Ed25519 key but not "
38618+
"in verify");
38619+
ERROR_OUT(INVALID_PARAMETER, exit_dcv);
38620+
}
38621+
}
38622+
else
38623+
#endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
38624+
#if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
38625+
if (ssl->peerEd448KeyPresent) {
38626+
if (ssl->options.peerSigAlgo != ed448_sa_algo) {
38627+
WOLFSSL_MSG("Oops, peer sent Ed448 key but not in "
38628+
"verify");
38629+
ERROR_OUT(INVALID_PARAMETER, exit_dcv);
38630+
}
38631+
}
38632+
else
38633+
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
3859138634
{
38592-
ssl->options.peerSigAlgo = ecc_dsa_sa_algo;
38635+
ERROR_OUT(INVALID_PARAMETER, exit_dcv);
3859338636
}
38594-
}
38595-
#endif
38596-
#if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
38597-
else if (ssl->peerEd25519KeyPresent)
38598-
ssl->options.peerSigAlgo = ed25519_sa_algo;
38599-
#endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
38600-
#if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
38601-
else if (ssl->peerEd448KeyPresent)
38602-
ssl->options.peerSigAlgo = ed448_sa_algo;
38603-
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
3860438637

38605-
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
38606-
ERROR_OUT(BUFFER_ERROR, exit_dcv);
38638+
SetDigest(ssl, ssl->options.peerHashAlgo);
3860738639
}
38608-
38609-
ato16(input + args->idx, &args->sz);
38610-
args->idx += OPAQUE16_LEN;
38611-
38612-
if ((args->idx - args->begin) + args->sz > size ||
38613-
args->sz > ENCRYPT_LEN) {
38614-
ERROR_OUT(BUFFER_ERROR, exit_dcv);
38615-
}
38616-
38617-
#ifdef HAVE_ECC
38618-
if (ssl->peerEccDsaKeyPresent) {
38619-
38620-
WOLFSSL_MSG("Doing ECC peer cert verify");
38621-
38622-
/* make sure a default is defined */
38640+
else {
38641+
/* make sure a default is defined */
3862338642
#if !defined(NO_SHA)
3862438643
SetDigest(ssl, sha_mac);
3862538644
#elif !defined(NO_SHA256)
@@ -38634,39 +38653,51 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3863438653
#error No digest enabled for ECC sig verify
3863538654
#endif
3863638655

38637-
if (IsAtLeastTLSv1_2(ssl)) {
38638-
if (ssl->options.peerSigAlgo != ecc_dsa_sa_algo
38639-
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
38640-
&& ssl->options.peerSigAlgo != sm2_sa_algo
38641-
#endif
38642-
) {
38643-
WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
38656+
#ifndef NO_RSA
38657+
if (ssl->peerRsaKeyPresent)
38658+
ssl->options.peerSigAlgo = rsa_sa_algo;
38659+
else
38660+
#endif
38661+
#ifdef HAVE_ECC
38662+
if (ssl->peerEccDsaKeyPresent) {
38663+
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
38664+
if (ssl->peerEccDsaKey->dp->id == ECC_SM2P256V1) {
38665+
ssl->options.peerSigAlgo = sm2_sa_algo;
38666+
}
38667+
else
38668+
#endif
38669+
{
38670+
ssl->options.peerSigAlgo = ecc_dsa_sa_algo;
3864438671
}
38645-
38646-
SetDigest(ssl, ssl->options.peerHashAlgo);
3864738672
}
38648-
}
38649-
#endif /* HAVE_ECC */
38650-
#if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
38651-
if (ssl->peerEd25519KeyPresent) {
38652-
WOLFSSL_MSG("Doing ED25519 peer cert verify");
38653-
if (IsAtLeastTLSv1_2(ssl) &&
38654-
ssl->options.peerSigAlgo != ed25519_sa_algo) {
38655-
WOLFSSL_MSG(
38656-
"Oops, peer sent ED25519 key but not in verify");
38673+
else
38674+
#endif
38675+
#if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
38676+
if (ssl->peerEd25519KeyPresent)
38677+
ssl->options.peerSigAlgo = ed25519_sa_algo;
38678+
else
38679+
#endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
38680+
#if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
38681+
if (ssl->peerEd448KeyPresent)
38682+
ssl->options.peerSigAlgo = ed448_sa_algo;
38683+
else
38684+
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
38685+
{
38686+
ERROR_OUT(NO_PEER_KEY, exit_dcv);
3865738687
}
3865838688
}
38659-
#endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
38660-
#if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
38661-
if (ssl->peerEd448KeyPresent) {
38662-
WOLFSSL_MSG("Doing ED448 peer cert verify");
38663-
if (IsAtLeastTLSv1_2(ssl) &&
38664-
ssl->options.peerSigAlgo != ed448_sa_algo) {
38665-
WOLFSSL_MSG(
38666-
"Oops, peer sent ED448 key but not in verify");
38667-
}
38689+
38690+
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
38691+
ERROR_OUT(BUFFER_ERROR, exit_dcv);
38692+
}
38693+
38694+
ato16(input + args->idx, &args->sz);
38695+
args->idx += OPAQUE16_LEN;
38696+
38697+
if ((args->idx - args->begin) + args->sz > size ||
38698+
args->sz > ENCRYPT_LEN) {
38699+
ERROR_OUT(BUFFER_ERROR, exit_dcv);
3866838700
}
38669-
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
3867038701

3867138702
/* Advance state and proceed */
3867238703
ssl->options.asyncState = TLS_ASYNC_DO;
@@ -38803,8 +38834,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3880338834
if (IsAtLeastTLSv1_2(ssl)) {
3880438835
#ifdef WC_RSA_PSS
3880538836
if (ssl->options.peerSigAlgo == rsa_pss_sa_algo) {
38806-
SetDigest(ssl, ssl->options.peerHashAlgo);
38807-
3880838837
#ifdef HAVE_SELFTEST
3880938838
ret = wc_RsaPSS_CheckPadding(
3881038839
ssl->buffers.digest.buffer,
@@ -38837,12 +38866,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3883738866
}
3883838867
#endif
3883938868

38840-
if (ssl->options.peerSigAlgo != rsa_sa_algo) {
38841-
WOLFSSL_MSG("Oops, peer sent RSA key but not "
38842-
"in verify");
38843-
}
38844-
38845-
SetDigest(ssl, ssl->options.peerHashAlgo);
3884638869

3884738870
args->sigSz = wc_EncodeSignature(encodedSig,
3884838871
ssl->buffers.digest.buffer,

0 commit comments

Comments
 (0)