Skip to content

Commit 74399cf

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 74399cf

File tree

1 file changed

+98
-82
lines changed

1 file changed

+98
-82
lines changed

src/internal.c

Lines changed: 98 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -38575,32 +38575,110 @@ 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+
}
38590+
}
38591+
else
38592+
#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
3858838611
}
3858938612
else
3859038613
#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
}
38637+
38638+
SetDigest(ssl, ssl->options.peerHashAlgo);
38639+
}
38640+
else {
38641+
/* make sure a default is defined */
38642+
#if !defined(NO_SHA)
38643+
SetDigest(ssl, sha_mac);
38644+
#elif !defined(NO_SHA256)
38645+
SetDigest(ssl, sha256_mac);
38646+
#elif defined(WOLFSSL_SM3)
38647+
SetDigest(ssl, sm3_mac);
38648+
#elif defined(WOLFSSL_SHA384)
38649+
SetDigest(ssl, sha384_mac);
38650+
#elif defined(WOLFSSL_SHA512)
38651+
SetDigest(ssl, sha512_mac);
38652+
#else
38653+
#error No digest enabled for ECC sig verify
38654+
#endif
38655+
38656+
#ifndef NO_RSA
38657+
if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0)
38658+
ssl->options.peerSigAlgo = rsa_sa_algo;
38659+
#endif
38660+
#ifdef HAVE_ECC
38661+
else if (ssl->peerEccDsaKeyPresent) {
38662+
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
38663+
if (ssl->peerEccDsaKey->dp->id == ECC_SM2P256V1) {
38664+
ssl->options.peerSigAlgo = sm2_sa_algo;
38665+
}
38666+
else
38667+
#endif
38668+
{
38669+
ssl->options.peerSigAlgo = ecc_dsa_sa_algo;
38670+
}
38671+
}
38672+
#endif
38673+
#if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
38674+
else if (ssl->peerEd25519KeyPresent)
38675+
ssl->options.peerSigAlgo = ed25519_sa_algo;
38676+
#endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
38677+
#if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
38678+
else if (ssl->peerEd448KeyPresent)
38679+
ssl->options.peerSigAlgo = ed448_sa_algo;
38680+
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
3859438681
}
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 */
3860438682

3860538683
if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
3860638684
ERROR_OUT(BUFFER_ERROR, exit_dcv);
@@ -38614,60 +38692,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3861438692
ERROR_OUT(BUFFER_ERROR, exit_dcv);
3861538693
}
3861638694

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 */
38623-
#if !defined(NO_SHA)
38624-
SetDigest(ssl, sha_mac);
38625-
#elif !defined(NO_SHA256)
38626-
SetDigest(ssl, sha256_mac);
38627-
#elif defined(WOLFSSL_SM3)
38628-
SetDigest(ssl, sm3_mac);
38629-
#elif defined(WOLFSSL_SHA384)
38630-
SetDigest(ssl, sha384_mac);
38631-
#elif defined(WOLFSSL_SHA512)
38632-
SetDigest(ssl, sha512_mac);
38633-
#else
38634-
#error No digest enabled for ECC sig verify
38635-
#endif
38636-
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");
38644-
}
38645-
38646-
SetDigest(ssl, ssl->options.peerHashAlgo);
38647-
}
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");
38657-
}
38658-
}
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-
}
38668-
}
38669-
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
38670-
3867138695
/* Advance state and proceed */
3867238696
ssl->options.asyncState = TLS_ASYNC_DO;
3867338697
} /* case TLS_ASYNC_BUILD */
@@ -38803,8 +38827,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3880338827
if (IsAtLeastTLSv1_2(ssl)) {
3880438828
#ifdef WC_RSA_PSS
3880538829
if (ssl->options.peerSigAlgo == rsa_pss_sa_algo) {
38806-
SetDigest(ssl, ssl->options.peerHashAlgo);
38807-
3880838830
#ifdef HAVE_SELFTEST
3880938831
ret = wc_RsaPSS_CheckPadding(
3881038832
ssl->buffers.digest.buffer,
@@ -38837,12 +38859,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3883738859
}
3883838860
#endif
3883938861

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);
3884638862

3884738863
args->sigSz = wc_EncodeSignature(encodedSig,
3884838864
ssl->buffers.digest.buffer,

0 commit comments

Comments
 (0)