Merge pull request #4948 from SparkiDev/tls12_pa_failsafe

TLS: add peer authentication failsafe for TLS 1.2 and below
pull/4957/head
David Garske 2022-03-15 09:42:56 -07:00 committed by GitHub
commit 9c29102c43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 167 additions and 17 deletions

View File

@ -4470,7 +4470,7 @@ then
fi fi
if test "$ENABLED_TLS13_EARLY_DATA" = "yes" if test "$ENABLED_TLS13_EARLY_DATA" = "yes"
then then
if test "x$ENABLED_TLS13" = "xno" if test "x$ENABLED_TLS13" = "xno" && test "X$ENABLED_ALL" = "xno"
then then
AC_MSG_ERROR([cannot enable earlydata without enabling tls13.]) AC_MSG_ERROR([cannot enable earlydata without enabling tls13.])
fi fi
@ -4478,7 +4478,10 @@ then
then then
AC_MSG_ERROR([cannot enable earlydata without enabling session tickets and/or PSK.]) AC_MSG_ERROR([cannot enable earlydata without enabling session tickets and/or PSK.])
fi fi
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_EARLY_DATA" if test "x$ENABLED_TLS13" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_EARLY_DATA"
fi
fi fi
if test "$ENABLED_TLSV12" = "no" && test "$ENABLED_TLS13" = "yes" && test "x$ENABLED_SESSION_TICKET" = "xno" if test "$ENABLED_TLSV12" = "no" && test "$ENABLED_TLS13" = "yes" && test "x$ENABLED_SESSION_TICKET" = "xno"

View File

@ -12766,7 +12766,23 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
goto exit_ppc; goto exit_ppc;
} }
/* Certificate validated and stored. */
ssl->options.havePeerCert = 1; ssl->options.havePeerCert = 1;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA)
if (ssl->options.side == WOLFSSL_CLIENT_END &&
ssl->specs.sig_algo == rsa_kea) {
/* CLIENT: No ServerKeyExchange message sent by server. */
ssl->options.peerAuthGood = 1;
}
#endif
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_ECC)
if (ssl->options.side == WOLFSSL_CLIENT_END &&
ssl->specs.static_ecdh) {
/* CLIENT: No ServerKeyExchange message sent by server. */
ssl->options.peerAuthGood = 1;
}
#endif
if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) { if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
#ifndef WOLFSSL_ALLOW_NO_CN_IN_SAN #ifndef WOLFSSL_ALLOW_NO_CN_IN_SAN
@ -14274,6 +14290,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if (ssl->options.resuming) { if (ssl->options.resuming) {
WOLFSSL_MSG("Not resuming as thought"); WOLFSSL_MSG("Not resuming as thought");
ssl->options.resuming = 0; ssl->options.resuming = 0;
/* CLIENT: No longer resuming, reset peer authentication state. */
ssl->options.peerAuthGood = 0;
} }
break; break;
@ -21915,9 +21933,10 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz)
ssl->suites->sigAlgo = ssl->buffers.keyType; ssl->suites->sigAlgo = ssl->buffers.keyType;
#endif #endif
} }
else else {
ssl->suites->sigAlgo = ssl->specs.sig_algo; ssl->suites->sigAlgo = ssl->specs.sig_algo;
if (ssl->suites->sigAlgo == 0) { }
if (ssl->suites->sigAlgo == anonymous_sa_algo) {
/* PSK ciphersuite - get digest to use from cipher suite */ /* PSK ciphersuite - get digest to use from cipher suite */
ssl->suites->hashAlgo = ssl->specs.mac_algorithm; ssl->suites->hashAlgo = ssl->specs.mac_algorithm;
return 0; return 0;
@ -23459,6 +23478,8 @@ exit_dpk:
if (!ssl->options.tls) if (!ssl->options.tls)
ret = DeriveKeys(ssl); ret = DeriveKeys(ssl);
#endif /* NO_OLD_TLS */ #endif /* NO_OLD_TLS */
/* SERVER: peer auth based on session secret. */
ssl->options.peerAuthGood = (ret == 0);
ssl->options.serverState = SERVER_HELLODONE_COMPLETE; ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
return ret; return ret;
@ -24812,6 +24833,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
(void**)&ssl->peerEccDsaKey); (void**)&ssl->peerEccDsaKey);
ssl->peerEccDsaKeyPresent = 0; ssl->peerEccDsaKeyPresent = 0;
} }
/* CLIENT: Data verified with cert's public key. */
ssl->options.peerAuthGood =
ssl->options.havePeerCert && (ret == 0);
break; break;
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
@ -24839,6 +24863,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
(void**)&ssl->peerEd25519Key); (void**)&ssl->peerEd25519Key);
ssl->peerEd25519KeyPresent = 0; ssl->peerEd25519KeyPresent = 0;
} }
/* CLIENT: Data verified with cert's public key. */
ssl->options.peerAuthGood =
ssl->options.havePeerCert && (ret == 0);
break; break;
} }
#endif /* HAVE_ED25519 */ #endif /* HAVE_ED25519 */
@ -24866,6 +24893,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
(void**)&ssl->peerEd448Key); (void**)&ssl->peerEd448Key);
ssl->peerEd448KeyPresent = 0; ssl->peerEd448KeyPresent = 0;
} }
/* CLIENT: Data verified with cert's public key. */
ssl->options.peerAuthGood =
ssl->options.havePeerCert && (ret == 0);
break; break;
} }
#endif /* HAVE_ED448 */ #endif /* HAVE_ED448 */
@ -24937,6 +24967,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
#endif #endif
if (ret != 0) if (ret != 0)
return ret; return ret;
/* CLIENT: Data verified with cert's public key. */
ssl->options.peerAuthGood =
ssl->options.havePeerCert;
break; break;
#endif #endif
case rsa_sa_algo: case rsa_sa_algo:
@ -24989,6 +25022,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
FINISHED_SZ) != 0) { FINISHED_SZ) != 0) {
ERROR_OUT(VERIFY_SIGN_ERROR, exit_dske); ERROR_OUT(VERIFY_SIGN_ERROR, exit_dske);
} }
/* CLIENT: Data verified with cert's public key. */
ssl->options.peerAuthGood =
ssl->options.havePeerCert;
break; break;
} }
#endif /* !NO_RSA */ #endif /* !NO_RSA */
@ -25526,6 +25562,8 @@ int SendClientKeyExchange(WOLFSSL* ssl)
} }
XMEMCPY(args->encSecret, ssl->arrays->client_identity, XMEMCPY(args->encSecret, ssl->arrays->client_identity,
args->encSz); args->encSz);
/* CLIENT: Pre-shared Key for peer authentication. */
ssl->options.peerAuthGood = 1;
/* make psk pre master secret */ /* make psk pre master secret */
/* length of key + length 0s + length of key + key */ /* length of key + length 0s + length of key + key */
@ -25562,6 +25600,8 @@ int SendClientKeyExchange(WOLFSSL* ssl)
if (esSz > MAX_PSK_ID_LEN) { if (esSz > MAX_PSK_ID_LEN) {
ERROR_OUT(CLIENT_ID_ERROR, exit_scke); ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
} }
/* CLIENT: Pre-shared Key for peer authentication. */
ssl->options.peerAuthGood = 1;
ssl->buffers.sig.length = ENCRYPT_LEN; ssl->buffers.sig.length = ENCRYPT_LEN;
ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN, ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN,
@ -25640,6 +25680,8 @@ int SendClientKeyExchange(WOLFSSL* ssl)
if (esSz > MAX_PSK_ID_LEN) { if (esSz > MAX_PSK_ID_LEN) {
ERROR_OUT(CLIENT_ID_ERROR, exit_scke); ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
} }
/* CLIENT: Pre-shared Key for peer authentication. */
ssl->options.peerAuthGood = 1;
/* place size and identity in output buffer sz:identity */ /* place size and identity in output buffer sz:identity */
c16toa((word16)esSz, args->output); c16toa((word16)esSz, args->output);
@ -29218,6 +29260,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (!ssl->options.tls) if (!ssl->options.tls)
ret = DeriveKeys(ssl); ret = DeriveKeys(ssl);
#endif #endif
/* SERVER: peer auth based on session secret. */
ssl->options.peerAuthGood = (ret == 0);
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
return ret; return ret;
@ -29341,10 +29385,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (!ssl->options.tls) if (!ssl->options.tls)
ret = DeriveKeys(ssl); ret = DeriveKeys(ssl);
#endif #endif
/* SERVER: peer auth based on session secret. */
ssl->options.peerAuthGood = (ret == 0);
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE; ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
} }
} }
return ret; return ret;
} }
@ -30203,6 +30250,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
NULL NULL
#endif #endif
); );
/* SERVER: Data verified with certificate's public key. */
ssl->options.peerAuthGood = ssl->options.havePeerCert &&
(ret == 0);
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
#if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)
@ -30219,6 +30269,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
NULL NULL
#endif #endif
); );
/* SERVER: Data verified with certificate's public key. */
ssl->options.peerAuthGood = ssl->options.havePeerCert &&
(ret == 0);
} }
#endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */
#if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)
@ -30235,6 +30288,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
NULL NULL
#endif #endif
); );
/* SERVER: Data verified with certificate's public key. */
ssl->options.peerAuthGood = ssl->options.havePeerCert &&
(ret == 0);
} }
#endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */
@ -30310,12 +30366,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (args->sendSz != args->sigSz || !args->output || if (args->sendSz != args->sigSz || !args->output ||
XMEMCMP(args->output, encodedSig, XMEMCMP(args->output, encodedSig,
min(args->sigSz, MAX_ENCODED_SIG_SZ)) != 0) { min(args->sigSz, MAX_ENCODED_SIG_SZ)) != 0) {
ret = VERIFY_CERT_ERROR; ret = VERIFY_CERT_ERROR;
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_SIGNATURE); XFREE(encodedSig, ssl->heap,
DYNAMIC_TYPE_SIGNATURE);
#endif #endif
} }
} }
@ -30326,8 +30383,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ret = VERIFY_CERT_ERROR; ret = VERIFY_CERT_ERROR;
} }
} }
if (ret == 0) {
/* SERVER: Data verified with cert's public key. */
ssl->options.peerAuthGood = ssl->options.havePeerCert &&
(ret == 0);
}
} }
#endif /* !NO_RSA */ #endif /* !NO_RSA */
if (ret != 0)
break;
/* Advance state and proceed */ /* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_FINALIZE; ssl->options.asyncState = TLS_ASYNC_FINALIZE;
@ -31820,6 +31884,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
#endif #endif
ERROR_OUT(PSK_KEY_ERROR, exit_dcke); ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
} }
/* SERVER: Pre-shared Key for peer authentication. */
ssl->options.peerAuthGood = 1;
/* make psk pre master secret */ /* make psk pre master secret */
/* length of key + length 0s + length of key + key */ /* length of key + length 0s + length of key + key */
@ -32659,6 +32725,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
#endif #endif
ERROR_OUT(PSK_KEY_ERROR, exit_dcke); ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
} }
/* SERVER: Pre-shared Key for peer authentication. */
ssl->options.peerAuthGood = 1;
c16toa((word16) ssl->arrays->psk_keySz, pms); c16toa((word16) ssl->arrays->psk_keySz, pms);
pms += OPAQUE16_LEN; pms += OPAQUE16_LEN;
@ -32695,6 +32763,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
ERROR_OUT(PSK_KEY_ERROR, exit_dcke); ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
} }
/* SERVER: Pre-shared Key for peer authentication. */
ssl->options.peerAuthGood = 1;
c16toa((word16) ssl->arrays->psk_keySz, pms); c16toa((word16) ssl->arrays->psk_keySz, pms);
pms += OPAQUE16_LEN; pms += OPAQUE16_LEN;

View File

@ -2064,6 +2064,11 @@ int SetCipherSpecs(WOLFSSL* ssl)
#endif #endif
#endif #endif
if (ssl->specs.sig_algo == anonymous_sa_algo) {
/* CLIENT/SERVER: No peer authentication to be performed. */
ssl->options.peerAuthGood = 1;
}
return 0; return 0;
} }

View File

@ -3168,6 +3168,8 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl)
ret = wolfSSL_UseSessionTicket(ssl); ret = wolfSSL_UseSessionTicket(ssl);
#endif #endif
} }
/* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
ssl->options.peerAuthGood = 0;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (ret == WOLFSSL_SUCCESS) if (ret == WOLFSSL_SUCCESS)
@ -14611,6 +14613,12 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS) #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
case FIRST_REPLY_SECOND : case FIRST_REPLY_SECOND :
/* CLIENT: Fail-safe for Server Authentication. */
if (!ssl->options.peerAuthGood) {
WOLFSSL_MSG("Server authentication did not happen");
return WOLFSSL_FATAL_ERROR;
}
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH) #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
if (ssl->options.sendVerify) { if (ssl->options.sendVerify) {
if ( (ssl->error = SendCertificateVerify(ssl)) != 0) { if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
@ -15007,6 +15015,10 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
} }
else {
/* SERVER: Peer auth good if not verifying client. */
ssl->options.peerAuthGood = 1;
}
} }
#endif #endif
ssl->options.acceptState = CERT_REQ_SENT; ssl->options.acceptState = CERT_REQ_SENT;
@ -15036,6 +15048,21 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
FALL_THROUGH; FALL_THROUGH;
case ACCEPT_SECOND_REPLY_DONE : case ACCEPT_SECOND_REPLY_DONE :
#ifndef NO_CERTS
/* SERVER: When not resuming and verifying peer but no certificate
* received and not failing when not received then peer auth good.
*/
if (!ssl->options.resuming && ssl->options.verifyPeer &&
!ssl->options.havePeerCert && !ssl->options.failNoCert) {
ssl->options.peerAuthGood = 1;
}
#endif /* !NO_CERTS */
#ifdef WOLFSSL_NO_CLIENT_AUTH
if (!ssl->options.resuming) {
ssl->options.peerAuthGood = 1;
}
#endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (ssl->options.createTicket && !ssl->options.noTicketTls12) { if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
if ( (ssl->error = SendTicket(ssl)) != 0) { if ( (ssl->error = SendTicket(ssl)) != 0) {
@ -15049,6 +15076,12 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
FALL_THROUGH; FALL_THROUGH;
case TICKET_SENT: case TICKET_SENT:
/* SERVER: Fail-safe for CLient Authentication. */
if (!ssl->options.peerAuthGood) {
WOLFSSL_MSG("Client authentication did not happen");
return WOLFSSL_FATAL_ERROR;
}
if ( (ssl->error = SendChangeCipher(ssl)) != 0) { if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error); WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;

View File

@ -5147,8 +5147,10 @@ static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input,
ret = DoClientTicket(ssl, input, length); ret = DoClientTicket(ssl, input, length);
if (ret == WOLFSSL_TICKET_RET_OK) { /* use ticket to resume */ if (ret == WOLFSSL_TICKET_RET_OK) { /* use ticket to resume */
WOLFSSL_MSG("Using existing client ticket"); WOLFSSL_MSG("Using existing client ticket");
ssl->options.useTicket = 1; ssl->options.useTicket = 1;
ssl->options.resuming = 1; ssl->options.resuming = 1;
/* SERVER: ticket is peer auth. */
ssl->options.peerAuthGood = 1;
} else if (ret == WOLFSSL_TICKET_RET_CREATE) { } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
WOLFSSL_MSG("Using existing client ticket, creating new one"); WOLFSSL_MSG("Using existing client ticket, creating new one");
ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap); ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
@ -5159,6 +5161,8 @@ static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input,
ssl->options.createTicket = 1; /* will send ticket msg */ ssl->options.createTicket = 1; /* will send ticket msg */
ssl->options.useTicket = 1; ssl->options.useTicket = 1;
ssl->options.resuming = 1; ssl->options.resuming = 1;
/* SERVER: ticket is peer auth. */
ssl->options.peerAuthGood = 1;
} }
} else if (ret == WOLFSSL_TICKET_RET_REJECT) { } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
WOLFSSL_MSG("Process client ticket rejected, not using"); WOLFSSL_MSG("Process client ticket rejected, not using");

View File

@ -2781,6 +2781,10 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) { ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) {
return ret; return ret;
} }
if (!clientHello) {
/* CLIENT: using secret in ticket for peer authentication. */
ssl->options.peerAuthGood = 1;
}
} }
#endif #endif
#ifndef NO_PSK #ifndef NO_PSK
@ -2903,6 +2907,11 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
psk->cipherSuite != suite[1])) { psk->cipherSuite != suite[1])) {
return PSK_KEY_ERROR; return PSK_KEY_ERROR;
} }
if (!clientHello) {
/* CLIENT: using PSK for peer authentication. */
ssl->options.peerAuthGood = 1;
}
} }
#endif #endif
@ -3629,7 +3638,6 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if ((ret = SetupPskKey(ssl, psk, 0)) != 0) if ((ret = SetupPskKey(ssl, psk, 0)) != 0)
return ret; return ret;
ssl->options.pskNegotiated = 1; ssl->options.pskNegotiated = 1;
ssl->options.peerAuthGood = 1;
} }
#endif #endif
@ -3961,6 +3969,8 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, byte* suite, int* err)
if ((ret == 0) && found) { if ((ret == 0) && found) {
/* PSK negotiation has succeeded */ /* PSK negotiation has succeeded */
ssl->options.isPSK = 1; ssl->options.isPSK = 1;
/* SERVER: using PSK for peer authentication. */
ssl->options.peerAuthGood = 1;
} }
} }
@ -4055,6 +4065,9 @@ static int DoPreSharedKeys(WOLFSSL* ssl, byte* suite, int* usingPSK, int* first)
} }
#endif #endif
/* SERVER: using secret in session ticket for peer auth. */
ssl->options.peerAuthGood = 1;
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
ssl->options.maxEarlyDataSz = ssl->session->maxEarlyDataSz; ssl->options.maxEarlyDataSz = ssl->session->maxEarlyDataSz;
#endif #endif
@ -4068,7 +4081,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, byte* suite, int* usingPSK, int* first)
/* Resumption PSK is resumption master secret. */ /* Resumption PSK is resumption master secret. */
ssl->arrays->psk_keySz = ssl->specs.hash_size; ssl->arrays->psk_keySz = ssl->specs.hash_size;
if ((ret = DeriveResumptionPSK(ssl, ssl->session->ticketNonce.data, if ((ret = DeriveResumptionPSK(ssl, ssl->session->ticketNonce.data,
ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) { ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) {
return ret; return ret;
} }
@ -4894,7 +4907,6 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->options.clientState = CLIENT_HELLO_COMPLETE; ssl->options.clientState = CLIENT_HELLO_COMPLETE;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ssl->options.pskNegotiated = (args->usingPSK != 0); ssl->options.pskNegotiated = (args->usingPSK != 0);
ssl->options.peerAuthGood = ssl->options.pskNegotiated;
#endif #endif
if (!args->usingPSK) { if (!args->usingPSK) {
@ -6744,6 +6756,9 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
); );
if (ret >= 0) { if (ret >= 0) {
/* CLIENT/SERVER: data verified with public key from
* certificate. */
ssl->options.peerAuthGood = 1;
FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey); FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey);
ssl->peerEccDsaKeyPresent = 0; ssl->peerEccDsaKeyPresent = 0;
} }
@ -6762,6 +6777,9 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
); );
if (ret >= 0) { if (ret >= 0) {
/* CLIENT/SERVER: data verified with public key from
* certificate. */
ssl->options.peerAuthGood = 1;
FreeKey(ssl, DYNAMIC_TYPE_ED25519, FreeKey(ssl, DYNAMIC_TYPE_ED25519,
(void**)&ssl->peerEd25519Key); (void**)&ssl->peerEd25519Key);
ssl->peerEd25519KeyPresent = 0; ssl->peerEd25519KeyPresent = 0;
@ -6781,6 +6799,9 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
); );
if (ret >= 0) { if (ret >= 0) {
/* CLIENT/SERVER: data verified with public key from
* certificate. */
ssl->options.peerAuthGood = 1;
FreeKey(ssl, DYNAMIC_TYPE_ED448, FreeKey(ssl, DYNAMIC_TYPE_ED448,
(void**)&ssl->peerEd448Key); (void**)&ssl->peerEd448Key);
ssl->peerEd448KeyPresent = 0; ssl->peerEd448KeyPresent = 0;
@ -6796,6 +6817,9 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
&res, ssl->peerFalconKey); &res, ssl->peerFalconKey);
if ((ret >= 0) && (res == 1)) { if ((ret >= 0) && (res == 1)) {
/* CLIENT/SERVER: data verified with public key from
* certificate. */
ssl->options.peerAuthGood = 1;
FreeKey(ssl, DYNAMIC_TYPE_FALCON, FreeKey(ssl, DYNAMIC_TYPE_FALCON,
(void**)&ssl->peerFalconKey); (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0; ssl->peerFalconKeyPresent = 0;
@ -6822,8 +6846,11 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
if (ret != 0) if (ret != 0)
goto exit_dcv; goto exit_dcv;
FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey); /* CLIENT/SERVER: data verified with public key from
* certificate. */
ssl->peerRsaKeyPresent = 0; ssl->peerRsaKeyPresent = 0;
FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey);
ssl->options.peerAuthGood = 1;
} }
#endif /* !NO_RSA && WC_RSA_PSS */ #endif /* !NO_RSA && WC_RSA_PSS */
@ -6835,7 +6862,6 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
case TLS_ASYNC_FINALIZE: case TLS_ASYNC_FINALIZE:
{ {
ssl->options.havePeerVerify = 1; ssl->options.havePeerVerify = 1;
ssl->options.peerAuthGood = 1;
/* Set final index */ /* Set final index */
args->idx += args->sz; args->idx += args->sz;
@ -7965,10 +7991,6 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
return DUPLICATE_MSG_E; return DUPLICATE_MSG_E;
} }
ssl->msgsReceived.got_certificate = 1; ssl->msgsReceived.got_certificate = 1;
if (ssl->options.side == WOLFSSL_SERVER_END &&
(!ssl->options.verifyPeer || !ssl->options.failNoCert)) {
ssl->options.peerAuthGood = 1;
}
break; break;
@ -8732,6 +8754,7 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
FALL_THROUGH; FALL_THROUGH;
case FIRST_REPLY_SECOND: case FIRST_REPLY_SECOND:
/* CLIENT: check peer authentication. */
if (!ssl->options.peerAuthGood) { if (!ssl->options.peerAuthGood) {
WOLFSSL_MSG("Server authentication did not happen"); WOLFSSL_MSG("Server authentication did not happen");
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
@ -9683,6 +9706,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
} }
} }
else { else {
/* SERVER: Peer auth good if not verifying client. */
ssl->options.peerAuthGood = 1; ssl->options.peerAuthGood = 1;
} }
} }
@ -9763,6 +9787,17 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
FALL_THROUGH; FALL_THROUGH;
case TLS13_ACCEPT_FINISHED_DONE : case TLS13_ACCEPT_FINISHED_DONE :
/* SERVER: When not resuming and verifying peer but no certificate
* received and not failing when not received then peer auth good.
*/
if (!ssl->options.resuming && ssl->options.verifyPeer &&
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
!ssl->options.verifyPostHandshake &&
#endif
!ssl->options.havePeerCert && !ssl->options.failNoCert) {
ssl->options.peerAuthGood = 1;
}
/* SERVER: check peer authentication. */
if (!ssl->options.peerAuthGood) { if (!ssl->options.peerAuthGood) {
WOLFSSL_MSG("Client authentication did not happen"); WOLFSSL_MSG("Client authentication did not happen");
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;