Improvements to TLS v1.3 code

Reset list of supported sig algorithms before sending certificate
request on server.
Refactored setting of ticket for both TLS13 and earlier.
Remember the type of key for deciding which sig alg to use with TLS13
CertificateVerify.
RSA PKCS #1.5 not allowed in TLS13 for CertificateVerify.
Remove all remaining DTLS code as spec barely started.
Turn off SHA512 code where decision based on cipher suite hash.
Fix fragment handling to work with encrypted messages.
Test public APIS.
pull/1002/head
Sean Parkinson 2017-06-29 09:00:44 +10:00
parent c748d9dae9
commit d2ce95955d
7 changed files with 381 additions and 255 deletions

View File

@ -181,7 +181,8 @@ static void ShowVersions(void)
/* Measures average time to create, connect and disconnect a connection (TPS).
Benchmark = number of connections. */
static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519)
int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519,
int helloRetry)
{
/* time passed in number of connects give average */
int times = benchmark;
@ -192,11 +193,12 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
#endif
#ifdef WOLFSSL_TLS13
byte* reply[80];
char msg[] = "hello wolfssl!";
static const char msg[] = "hello wolfssl!";
#endif
(void)resumeSession;
(void)useX25519;
(void)helloRetry;
while (loops--) {
#ifndef NO_SESSION_CACHE
@ -210,6 +212,10 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
if (ssl == NULL)
err_sys("unable to get SSL object");
#ifdef WOLFSSL_TLS13
if (helloRetry)
wolfSSL_NoKeyShares(ssl);
#endif
tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
@ -832,8 +838,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef HAVE_EXTENDED_MASTER
byte disableExtMasterSecret = 0;
#endif
#ifdef WOLFSSL_TLS13
int helloRetry = 0;
#ifdef WOLFSSL_TLS13
int onlyKeyShare = 0;
int noPskDheKe = 0;
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
@ -884,6 +890,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void)alpn_opt;
(void)updateKeysIVs;
(void)useX25519;
(void)helloRetry;
StackTrap();
@ -1609,7 +1616,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (benchmark) {
((func_args*)args)->return_code =
ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP,
benchmark, resumeSession, useX25519);
benchmark, resumeSession, useX25519,
helloRetry);
wolfSSL_CTX_free(ctx);
exit(EXIT_SUCCESS);
}

View File

@ -79,6 +79,22 @@ if [ $RESULT -ne 0 ]; then
fi
echo ""
# Usual TLS v1.3 server / TLS v1.3 client - fragment.
echo -e "\n\nTLS v1.3 server with TLS v1.3 client - fragment"
port=0
./examples/server/server -v 4 -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v 4 -F 1 -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -ne 0 ]; then
echo -e "\n\nTLS v1.3 and fragments not working"
do_cleanup
exit 1
fi
echo ""
# Use HelloRetryRequest with TLS v1.3 server / TLS v1.3 client.
echo -e "\n\nTLS v1.3 HelloRetryRequest"
port=0
@ -322,6 +338,22 @@ if [ $? -eq 0 ]; then
echo ""
fi
# TLS 1.3 cipher suites server / client.
echo -e "\n\nTLS v1.3 cipher suite mismatch"
port=0
./examples/server/server -v 4 -R $ready_file -p $port -l TLS13-CHACHA20-POLY1305-SHA256 &
server_pid=$!
create_port
./examples/client/client -v 4 -p $port -l TLS13-AES256-GCM-SHA384
RESULT=$?
remove_ready_file
if [ $RESULT -ne 1 ]; then
echo -e "\n\nIssue with mismatched TLS v1.3 cipher suites"
do_cleanup
exit 1
fi
echo ""
# TLS 1.3 server / TLS 1.2 client.
echo -e "\n\nTLS v1.3 server downgrading to TLS v1.2"
port=0

View File

@ -1687,8 +1687,8 @@ void InitCipherSpecs(CipherSpecs* cs)
cs->block_size = 0;
}
static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
int haveRSAsig, int haveAnon, int tls1_2)
void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig,
int haveAnon, int tls1_2)
{
int idx = 0;
@ -3833,7 +3833,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#ifdef WOLFSSL_TLS13
ssl->buffers.certChainCnt = ctx->certChainCnt;
#endif
ssl->buffers.key = ctx->privateKey;
ssl->buffers.key = ctx->privateKey;
ssl->buffers.keyType = ctx->privateKeyType;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
@ -15488,7 +15489,13 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
ssl->suites->sigAlgo = ssl->specs.sig_algo;
/* set defaults */
if (IsAtLeastTLSv1_2(ssl)) {
if (IsAtLeastTLSv1_3(ssl->version)) {
ssl->suites->hashAlgo = sha256_mac;
#ifndef NO_CERTS
ssl->suites->sigAlgo = ssl->buffers.keyType;
#endif
}
else if (IsAtLeastTLSv1_2(ssl)) {
#ifdef WOLFSSL_ALLOW_TLS_SHA1
ssl->suites->hashAlgo = sha_mac;
#else
@ -15509,14 +15516,14 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
continue;
if (sigAlgo == ed25519_sa_algo &&
ssl->specs.sig_algo == ecc_dsa_sa_algo) {
ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
ssl->suites->sigAlgo = sigAlgo;
ssl->suites->hashAlgo = sha512_mac;
break;
}
#endif
if (sigAlgo == ssl->specs.sig_algo || (sigAlgo == rsa_pss_sa_algo &&
ssl->specs.sig_algo == rsa_sa_algo)) {
if (sigAlgo == ssl->suites->sigAlgo || (sigAlgo == rsa_pss_sa_algo &&
ssl->suites->sigAlgo == rsa_sa_algo)) {
if (hashAlgo == sha_mac) {
ssl->suites->sigAlgo = sigAlgo;
break;
@ -18890,7 +18897,7 @@ exit_scke:
#ifndef NO_CERTS
/* Decode the private key - RSA or ECC - and creates a key object.
/* Decode the private key - RSA, ECC, or Ed25519 - and creates a key object.
* The signature type is set as well.
* The maximum length of a signature is returned.
*
@ -19474,12 +19481,49 @@ exit_scv:
#ifdef HAVE_SESSION_TICKET
int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length)
{
/* Free old dynamic ticket if we already had one */
if (ssl->session.isDynamic) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
ssl->session.ticket = ssl->session.staticTicket;
ssl->session.isDynamic = 0;
}
if (length > sizeof(ssl->session.staticTicket)) {
byte* sessionTicket =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
if (sessionTicket == NULL)
return MEMORY_E;
ssl->session.ticket = sessionTicket;
ssl->session.isDynamic = 1;
}
ssl->session.ticketLen = length;
if (length > 0) {
XMEMCPY(ssl->session.ticket, ticket, length);
if (ssl->session_ticket_cb != NULL) {
ssl->session_ticket_cb(ssl,
ssl->session.ticket, ssl->session.ticketLen,
ssl->session_ticket_ctx);
}
/* Create a fake sessionID based on the ticket, this will
* supercede the existing session cache info. */
ssl->options.haveSessionId = 1;
XMEMCPY(ssl->arrays->sessionID,
ssl->session.ticket + length - ID_LEN, ID_LEN);
}
return 0;
}
static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 size)
{
word32 begin = *inOutIdx;
word32 lifetime;
word16 length;
int ret;
if (ssl->expect_session_ticket == 0) {
WOLFSSL_MSG("Unexpected session ticket");
@ -19501,51 +19545,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if ((*inOutIdx - begin) + length > size)
return BUFFER_ERROR;
if (length > sizeof(ssl->session.staticTicket)) {
/* Free old dynamic ticket if we already had one */
if (ssl->session.isDynamic)
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
ssl->session.ticket =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
if (ssl->session.ticket == NULL) {
/* Set to static ticket to avoid null pointer error */
ssl->session.ticket = ssl->session.staticTicket;
ssl->session.isDynamic = 0;
return MEMORY_E;
}
ssl->session.isDynamic = 1;
} else {
if(ssl->session.isDynamic) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
}
ssl->session.isDynamic = 0;
ssl->session.ticket = ssl->session.staticTicket;
}
/* If the received ticket including its length is greater than
* a length value, the save it. Otherwise, don't save it. */
if ((ret = SetTicket(ssl, input + *inOutIdx, length)) != 0)
return ret;
*inOutIdx += length;
if (length > 0) {
XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
*inOutIdx += length;
ssl->session.ticketLen = length;
ssl->timeout = lifetime;
if (ssl->session_ticket_cb != NULL) {
ssl->session_ticket_cb(ssl,
ssl->session.ticket, ssl->session.ticketLen,
ssl->session_ticket_ctx);
}
/* Create a fake sessionID based on the ticket, this will
* supercede the existing session cache info. */
ssl->options.haveSessionId = 1;
XMEMCPY(ssl->arrays->sessionID,
ssl->session.ticket + length - ID_LEN, ID_LEN);
#ifndef NO_SESSION_CACHE
AddSession(ssl);
#endif
}
else {
ssl->session.ticketLen = 0;
}
if (IsEncryptionOn(ssl, 0)) {

View File

@ -4708,12 +4708,14 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ret = RSA_KEY_SIZE_E;
WOLFSSL_MSG("Private Key size too small");
}
ssl->buffers.keyType = rsa_sa_algo;
}
else if(ctx) {
if (RsaSz < ctx->minRsaKeySz) {
ret = RSA_KEY_SIZE_E;
WOLFSSL_MSG("Private Key size too small");
}
ctx->privateKeyType = rsa_sa_algo;
}
rsaKey = 1;
(void)rsaKey; /* for no ecc builds */
@ -4764,9 +4766,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
eccKey = 1;
if (ssl) {
ssl->options.haveStaticECC = 1;
ssl->buffers.keyType = ecc_dsa_sa_algo;
}
else if (ctx) {
ctx->haveStaticECC = 1;
ctx->privateKeyType = ecc_dsa_sa_algo;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
@ -4804,6 +4808,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
WOLFSSL_MSG("ED25519 private key too small");
return ECC_KEY_SIZE_E;
}
ssl->buffers.keyType = ed25519_sa_algo;
}
else if (ctx) {
if (ED25519_KEY_SIZE < ctx->minEccKeySz) {
@ -4811,6 +4816,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
WOLFSSL_MSG("ED25519 private key too small");
return ECC_KEY_SIZE_E;
}
ctx->privateKeyType = ed25519_sa_algo;
}
wc_ed25519_free(&key);

View File

@ -190,8 +190,8 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
byte* ikm, int ikmLen, int mac)
{
int ret;
int hash;
int len;
int hash = 0;
int len = 0;
switch (mac) {
#ifndef NO_SHA256
@ -208,15 +208,12 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_TLS13_SHA512
case sha512_mac:
hash = SHA512;
len = SHA512_DIGEST_SIZE;
break;
#endif
default:
return BAD_FUNC_ARG;
}
/* When length is 0 then use zeroed data of digest length. */
@ -368,7 +365,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
digestAlg = SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
ret = wc_InitSha512_ex(&digest.sha512, ssl->heap, INVALID_DEVID);
if (ret == 0) {
@ -426,7 +423,7 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
word32 hashOutSz = 0;
const byte* protocol;
word32 protocolLen;
int digestAlg;
int digestAlg = 0;
switch (hashAlgo) {
#ifndef NO_SHA256
@ -447,7 +444,7 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
hashSz = SHA512_DIGEST_SIZE;
digestAlg = SHA512;
@ -455,10 +452,6 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
break;
#endif
default:
ret = BAD_FUNC_ARG;
break;
}
if (ret != 0)
return ret;
@ -920,13 +913,13 @@ static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
break;
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
hashType = SHA512;
hashSz = SHA512_DIGEST_SIZE;
ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
break;
#endif /* WOLFSSL_SHA512 */
#endif /* WOLFSSL_TLS13_SHA512 */
}
if (ret != 0)
return ret;
@ -1329,23 +1322,6 @@ static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
{
int ret = BAD_FUNC_ARG;
if (ssl->hsHashes == NULL) {
return BAD_FUNC_ARG;
}
#ifndef NO_OLD_TLS
#ifndef NO_SHA
ret = wc_ShaUpdate(&ssl->hsHashes->hashSha, input, sz);
if (ret != 0)
return ret;
#endif
#ifndef NO_MD5
ret = wc_Md5Update(&ssl->hsHashes->hashMd5, input, sz);
if (ret != 0)
return ret;
#endif
#endif /* !NO_OLD_TLS */
#ifndef NO_SHA256
ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, input, sz);
if (ret != 0)
@ -1356,7 +1332,7 @@ static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
if (ret != 0)
return ret;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, input, sz);
if (ret != 0)
return ret;
@ -1706,8 +1682,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
WOLFSSL_BUFFER(output + dataSz, macSz);
#endif
if (ssl->encrypt.nonce)
ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ);
ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ);
break;
}
@ -1908,15 +1883,14 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
WOLFSSL_BUFFER(output, dataSz);
#endif
if (ssl->decrypt.nonce)
ForceZero(ssl->decrypt.nonce, AEAD_NONCE_SZ);
ForceZero(ssl->decrypt.nonce, AEAD_NONCE_SZ);
break;
}
}
#ifndef WOLFSSL_EARLY_DATA
if (ret < 0 && !ssl->options.dtls) {
if (ret < 0) {
SendAlert(ssl, alert_fatal, bad_record_mac);
ret = VERIFY_MAC_ERROR;
}
@ -2443,7 +2417,7 @@ static int RestartHandshakeHash(WOLFSSL* ssl)
hash = hashes.sha384;
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
hash = hashes.sha512;
break;
@ -2849,8 +2823,9 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
if (len == 0)
return INVALID_PARAMETER;
if ((ret = TLSX_Parse(ssl, (byte *)(input + *inOutIdx), len,
certificate_request, &peerSuites)))
certificate_request, &peerSuites))) {
return ret;
}
*inOutIdx += len;
PickHashSigAlgo(ssl, peerSuites.hashSigAlgo, peerSuites.hashSigAlgoSz);
@ -3305,8 +3280,8 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ssl->chVersion = pv; /* store */
i += OPAQUE16_LEN;
if ((ssl->version.major == SSLv3_MAJOR &&
ssl->version.minor < TLSv1_3_MINOR) || ssl->options.dtls) {
if (ssl->version.major == SSLv3_MAJOR &&
ssl->version.minor < TLSv1_3_MINOR) {
return DoClientHello(ssl, input, inOutIdx, helloSz);
}
@ -3732,6 +3707,9 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
WOLFSSL_ENTER("SendTls13CertificateRequest");
if (ssl->options.side == WOLFSSL_SERVER_END)
InitSuitesHashSigAlgo(ssl->suites, 1, 1, 0, 1);
#ifdef WOLFSSL_TLS13_DRAFT_18
i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
reqSz = OPAQUE8_LEN + reqCtxLen + REQ_HEADER_SZ + REQ_HEADER_SZ;
@ -3858,17 +3836,11 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
#endif
#endif
#ifndef NO_RSA
case rsa_sa_algo:
output[0] = hashAlgo;
output[1] = rsa_sa_algo;
break;
#ifdef WC_RSA_PSS
/* PSS signatures: 0x080[4-6] */
case rsa_pss_sa_algo:
output[0] = rsa_pss_sa_algo;
output[1] = hashAlgo;
break;
#endif
#endif
/* ED448: 0x0808 */
}
@ -3884,13 +3856,11 @@ static INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
{
switch (input[0]) {
case NEW_SA_MAJOR:
#ifdef WC_RSA_PSS
/* PSS signatures: 0x080[4-6] */
if (input[1] <= sha512_mac) {
*hsType = input[0];
*hashAlgo = input[1];
}
#endif
#ifdef HAVE_ED25519
/* ED25519: 0x0807 */
if (input[1] == ED25519_SA_MINOR) {
@ -3921,24 +3891,24 @@ static INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash)
#ifndef NO_SHA256
case sha256_mac:
ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
if (ret != 0)
break;
return SHA256_DIGEST_SIZE;
if (ret == 0)
ret = SHA256_DIGEST_SIZE;
break;
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
case sha384_mac:
ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
if (ret != 0)
break;
return SHA384_DIGEST_SIZE;
if (ret == 0)
ret = SHA384_DIGEST_SIZE;
break;
#endif /* WOLFSSL_SHA384 */
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
if (ret != 0)
break;
return SHA512_DIGEST_SIZE;
#endif /* WOLFSSL_SHA512 */
if (ret == 0)
ret = SHA512_DIGEST_SIZE;
break;
#endif /* WOLFSSL_TLS13_SHA512 */
}
return ret;
}
@ -4017,18 +3987,12 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
{
Digest digest;
int hashSz = 0;
int hashOid = 0;
int ret = BAD_FUNC_ARG;
byte* hash;
(void)sigAlgo;
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo)
hash = sig;
else
#endif
hash = sigData;
hash = sig;
/* Digest the signature data. */
switch (hashAlgo) {
@ -4042,7 +4006,6 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
wc_Sha256Free(&digest.sha256);
}
hashSz = SHA256_DIGEST_SIZE;
hashOid = SHA256h;
break;
#endif
#ifdef WOLFSSL_SHA384
@ -4055,7 +4018,6 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
wc_Sha384Free(&digest.sha384);
}
hashSz = SHA384_DIGEST_SIZE;
hashOid = SHA384h;
break;
#endif
#ifdef WOLFSSL_SHA512
@ -4068,7 +4030,6 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
wc_Sha512Free(&digest.sha512);
}
hashSz = SHA512_DIGEST_SIZE;
hashOid = SHA512h;
break;
#endif
}
@ -4076,15 +4037,7 @@ static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
if (ret != 0)
return ret;
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo)
return hashSz;
else
#endif
{
/* Encode the signature data as per PKCS #1.5 */
return wc_EncodeSignature(sig, hash, hashSz, hashOid);
}
return hashSz;
}
#endif /* !NO_RSA */
@ -4166,18 +4119,12 @@ static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
int ret = 0;
byte sigData[MAX_SIG_DATA_SZ];
word16 sigDataSz;
#ifdef WOLFSSL_SMALL_STACK
byte* encodedSig = NULL;
#else
byte encodedSig[MAX_ENCODED_SIG_SZ];
#endif
word32 sigSz;
ret = CreateSigData(ssl, sigData, &sigDataSz, 1);
if (ret != 0)
return ret;
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo) {
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
@ -4195,31 +4142,6 @@ static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
ret = wc_RsaPSS_CheckPadding(sigData, sigSz, decSig, decSigSz,
hashType);
}
else
#endif
{
#ifdef WOLFSSL_SMALL_STACK
encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, ssl->heap,
DYNAMIC_TYPE_SIGNATURE);
if (encodedSig == NULL) {
return MEMORY_E;
}
#endif
sigSz = CreateRSAEncodedSig(encodedSig, sigData, sigDataSz, sigAlgo,
hashAlgo);
/* Check the encoded and decrypted signature data match. */
if (decSigSz != sigSz || decSig == NULL ||
XMEMCMP(decSig, encodedSig, sigSz) != 0) {
ret = VERIFY_CERT_ERROR;
}
#ifdef WOLFSSL_SMALL_STACK
if (encodedSig != NULL)
XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
#endif
}
return ret;
}
@ -4419,7 +4341,6 @@ static int SendTls13Certificate(WOLFSSL* ssl)
else
AddTls13RecordHeader(output, fragSz, handshake, ssl);
/* TODO: [TLS13] Test with fragments and multiple CA certs */
if (certSz > 0 && ssl->fragOffset < certSz + OPAQUE16_LEN) {
/* Put in the leaf certificate and empty extension. */
word32 copySz = AddCertExt(ssl->buffers.certificate->buffer, certSz,
@ -4613,14 +4534,8 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
goto exit_scv;
/* Add signature algorithm. */
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
#ifdef WC_RSA_PSS
if (ssl->pssAlgo & (1 << ssl->suites->hashAlgo))
args->sigAlgo = rsa_pss_sa_algo;
else
#endif
args->sigAlgo = rsa_sa_algo;
}
if (ssl->hsType == DYNAMIC_TYPE_RSA)
args->sigAlgo = rsa_pss_sa_algo;
else if (ssl->hsType == DYNAMIC_TYPE_ECC)
args->sigAlgo = ecc_dsa_sa_algo;
#ifdef HAVE_ED25519
@ -4902,7 +4817,7 @@ static void FreeDcv13Args(WOLFSSL* ssl, void* pArgs)
{
Dcv13Args* args = (Dcv13Args*)pArgs;
if (args->sigData) {
if (args->sigData != NULL) {
XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
args->sigData = NULL;
}
@ -5661,9 +5576,7 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
word32* inOutIdx, word32 size)
{
#ifdef HAVE_SESSION_TICKET
#ifdef WOLFSSL_EARLY_DATA
int ret;
#endif
word32 begin = *inOutIdx;
word32 lifetime;
word32 ageAdd;
@ -5694,22 +5607,9 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
if ((*inOutIdx - begin) + length > size)
return BUFFER_ERROR;
/* Free old dynamic ticket if we already had one. */
if (ssl->session.isDynamic) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
/* Reset back to static by default. */
ssl->session.ticket = NULL;
ssl->session.isDynamic = 0;
ssl->session.ticket = ssl->session.staticTicket;
}
/* Use dynamic ticket if required.*/
if (length > sizeof(ssl->session.staticTicket)) {
ssl->session.ticket = (byte*)XMALLOC(length, ssl->heap,
DYNAMIC_TYPE_SESSION_TICK);
if (ssl->session.ticket == NULL)
return MEMORY_E;
ssl->session.isDynamic = 1;
}
if ((ret = SetTicket(ssl, input + *inOutIdx, length)) != 0)
return ret;
*inOutIdx += length;
now = TimeNowInMilliseconds();
if (now == (word32)GETTIME_ERROR)
@ -5724,19 +5624,6 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
#ifdef WOLFSSL_EARLY_DATA
ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
#endif
XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
*inOutIdx += length;
ssl->session.ticketLen = length;
if (ssl->session_ticket_cb != NULL) {
ssl->session_ticket_cb(ssl, ssl->session.ticket,
ssl->session.ticketLen,
ssl->session_ticket_ctx);
}
ssl->options.haveSessionId = 1;
XMEMCPY(ssl->arrays->sessionID, ssl->session.ticket + length - ID_LEN,
ID_LEN);
if ((*inOutIdx - begin) + EXTS_SZ > size)
return BUFFER_ERROR;
@ -5812,7 +5699,7 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
return ret;
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
ret = wc_Sha512Copy(&ssl->hsHashes->hashSha512, &digest.sha512);
if (ret != 0)
@ -5859,7 +5746,7 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
return ret;
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_TLS13_SHA512
case sha512_mac:
ret = wc_Sha512Copy(&digest.sha512, &ssl->hsHashes->hashSha384);
if (ret != 0)
@ -6181,7 +6068,7 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
return OUT_OF_ORDER_E;
}
if (ssl->options.side == WOLFSSL_CLIENT_END && !ssl->options.dtls &&
if (ssl->options.side == WOLFSSL_CLIENT_END &&
ssl->options.serverState == NULL_STATE &&
type != server_hello && type != hello_retry_request) {
WOLFSSL_MSG("First server message not server hello");
@ -6189,14 +6076,6 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
return OUT_OF_ORDER_E;
}
if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls &&
type == server_hello_done &&
ssl->options.serverState < SERVER_HELLO_COMPLETE) {
WOLFSSL_MSG("Server hello done received before server hello in DTLS");
SendAlert(ssl, alert_fatal, unexpected_message);
return OUT_OF_ORDER_E;
}
if (ssl->options.side == WOLFSSL_SERVER_END &&
ssl->options.clientState == NULL_STATE && type != client_hello) {
WOLFSSL_MSG("First client message not client hello");
@ -6396,7 +6275,7 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
totalSz);
}
inputLength = ssl->buffers.inputBuffer.length - *inOutIdx;
inputLength = ssl->buffers.inputBuffer.length - *inOutIdx - ssl->keys.padSz;
/* If there is a pending fragmented handshake message,
* pending message size will be non-zero. */
@ -6428,7 +6307,7 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
input + *inOutIdx - HANDSHAKE_HEADER_SZ,
inputLength);
ssl->arrays->pendingMsgOffset = inputLength;
*inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
*inOutIdx += inputLength + ssl->keys.padSz - HANDSHAKE_HEADER_SZ;
return 0;
}
@ -6437,14 +6316,14 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
}
else {
if (inputLength + ssl->arrays->pendingMsgOffset >
ssl->arrays->pendingMsgSz) {
ssl->arrays->pendingMsgSz) {
return BUFFER_ERROR;
}
XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
input + *inOutIdx, inputLength);
ssl->arrays->pendingMsgOffset += inputLength;
*inOutIdx += inputLength;
*inOutIdx += inputLength + ssl->keys.padSz;
if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
{
@ -6464,6 +6343,7 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
return ret;
}
/* The client connecting to the server.
* The protocol version is expecting to be TLS v1.3.
* If the server downgrades, and older versions of the protocol are compiled
@ -6682,17 +6562,18 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
* A value of NULL indicates to generate a new random secret.
* secretSz Size of secret data in bytes.
* Use a value of 0 to indicate use of default size.
* returns BAD_FUNC_ARG when ssl is NULL, not using TLS v1.3, or called on a
* client; SSL_SUCCESS on success and otherwise failure.
* returns BAD_FUNC_ARG when ssl is NULL or not using TLS v1.3, SIDE_ERROR when
* called on a client; SSL_SUCCESS on success and otherwise failure.
*/
int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret,
unsigned int secretSz)
{
int ret;
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version) ||
ssl->options.side == WOLFSSL_CLIENT_END)
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;
if (secretSz == 0) {
#if !defined(NO_SHA) && defined(NO_SHA256)
@ -6713,7 +6594,8 @@ int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret,
ssl->heap, DYNAMIC_TYPE_COOKIE_PWD);
}
newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
newSecret = (byte*)XMALLOC(secretSz, ssl->heap,
DYNAMIC_TYPE_COOKIE_PWD);
if (newSecret == NULL) {
ssl->buffers.tls13CookieSecret.buffer = NULL;
ssl->buffers.tls13CookieSecret.length = 0;
@ -6749,10 +6631,12 @@ int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret,
*/
int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
{
int ret = BAD_FUNC_ARG;
int ret;
if (ssl == NULL)
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_SERVER_END)
return SIDE_ERROR;
ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
if (ret != 0)
@ -6768,10 +6652,12 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
*/
int wolfSSL_NoKeyShares(WOLFSSL* ssl)
{
int ret = BAD_FUNC_ARG;
int ret;
if (ssl == NULL)
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_SERVER_END)
return SIDE_ERROR;
ret = TLSX_KeyShare_Empty(ssl);
if (ret != 0)
@ -6787,8 +6673,10 @@ int wolfSSL_NoKeyShares(WOLFSSL* ssl)
*/
int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
return BAD_FUNC_ARG;
if (ctx->method->side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;
#ifdef HAVE_SESSION_TICKET
ctx->noTicketTls13 = 1;
@ -6805,9 +6693,10 @@ int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx)
*/
int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl)
{
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version) ||
ssl->options.side == WOLFSSL_CLIENT_END)
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;
#ifdef HAVE_SESSION_TICKET
ssl->options.noTicketTls13 = 1;
@ -6823,7 +6712,7 @@ int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl)
*/
int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
return BAD_FUNC_ARG;
ctx->noPskDheKe = 1;
@ -6880,7 +6769,7 @@ int wolfSSL_update_keys(WOLFSSL* ssl)
*/
int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
return BAD_FUNC_ARG;
if (ctx->method->side == WOLFSSL_SERVER_END)
return SIDE_ERROR;
@ -6997,13 +6886,6 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
return SSL_FATAL_ERROR;
}
#endif
#ifdef WOLFSSL_DTLS
if (ssl->version.major == DTLS_MAJOR) {
ssl->options.dtls = 1;
ssl->options.tls = 1;
ssl->options.tls1_1 = 1;
}
#endif
if (ssl->buffers.outputBuffer.length > 0) {
if ((ssl->error = SendBuffered(ssl)) == 0) {
@ -7197,16 +7079,6 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
}
#endif /* NO_HANDSHAKE_DONE_CB */
#ifdef WOLFSSL_SESSION_EXPORT
if (ssl->dtls_export) {
if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
WOLFSSL_MSG("Export DTLS session error");
WOLFSSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;
}
}
#endif
WOLFSSL_LEAVE("SSL_accept()", SSL_SUCCESS);
return SSL_SUCCESS;
@ -7229,9 +7101,9 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
*/
int wolfSSL_CTX_set_max_early_data(WOLFSSL_CTX* ctx, unsigned int sz)
{
if (ctx == NULL)
if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
return BAD_FUNC_ARG;
if (ctx->method->side == WOLFSSL_SERVER_END)
if (ctx->method->side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;
ctx->maxEarlyDataSz = sz;
@ -7253,7 +7125,7 @@ int wolfSSL_set_max_early_data(WOLFSSL* ssl, unsigned int sz)
{
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
if (ssl->options.side != WOLFSSL_SERVER_END)
if (ssl->options.side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;
ssl->options.maxEarlyDataSz = sz;
@ -7267,8 +7139,9 @@ int wolfSSL_set_max_early_data(WOLFSSL* ssl, unsigned int sz)
* data Early data to write
* sz The size of the eary data in bytes.
* outSz The number of early data bytes written.
* returns BAD_FUNC_ARG when ssl, data or outSz is NULL or when sz is negative;
* SIDE ERROR when not a client; or the number of early data bytes written.
* returns BAD_FUNC_ARG when: ssl, data or outSz is NULL; sz is negative;
* or not using TLS v1.3. SIDE ERROR when not a server. Otherwise the number of
* early data bytes written.
*/
int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
{
@ -7278,6 +7151,8 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
if (ssl == NULL || data == NULL || sz < 0 || outSz == NULL)
return BAD_FUNC_ARG;
if (!IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_SERVER_END)
return SIDE_ERROR;
@ -7307,8 +7182,9 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
* data Buffer to put the early data into.
* sz The size of the buffer in bytes.
* outSz The number of early data bytes read.
* returns BAD_FUNC_ARG when ssl, data or outSz is NULL or when sz is negative;
* SIDE ERROR when not a server; or the number of early data bytes read.
* returns BAD_FUNC_ARG when: ssl, data or outSz is NULL; sz is negative;
* or not using TLS v1.3. SIDE ERROR when not a server. Otherwise the number of
* early data bytes read.
*/
int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz)
{
@ -7319,6 +7195,8 @@ int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz)
if (ssl == NULL || data == NULL || sz < 0 || outSz == NULL)
return BAD_FUNC_ARG;
if (!IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
if (ssl->options.side == WOLFSSL_CLIENT_END)
return SIDE_ERROR;

View File

@ -7256,6 +7256,188 @@ static void test_wc_ecc_get_curve_id_from_params(void)
#endif /* NO_CERTS */
#ifdef WOLFSSL_TLS13
#ifdef WOLFSSL_SEND_HRR_COOKIE
static byte fixedKey[SHA384_DIGEST_SIZE] = { 0, };
#endif
#ifdef WOLFSSL_EARLY_DATA
static const char earlyData[] = "Early Data";
static char earlyDataBuffer[1];
#endif
static int test_tls13_apis(void)
{
int ret = 0;
WOLFSSL_CTX* clientTls12Ctx;
WOLFSSL* clientTls12Ssl;
WOLFSSL_CTX* serverTls12Ctx;
WOLFSSL* serverTls12Ssl;
WOLFSSL_CTX* clientCtx;
WOLFSSL* clientSsl;
WOLFSSL_CTX* serverCtx;
WOLFSSL* serverSsl;
#ifndef NO_CERTS
const char* ourCert = svrCertFile;
const char* ourKey = svrKeyFile;
#endif
#ifdef WOLFSSL_EARLY_DATA
int outSz;
#endif
clientTls12Ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
clientTls12Ssl = wolfSSL_new(clientTls12Ctx);
serverTls12Ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
#ifndef NO_CERTS
wolfSSL_CTX_use_certificate_chain_file(serverTls12Ctx, ourCert);
wolfSSL_CTX_use_PrivateKey_file(serverTls12Ctx, ourKey, SSL_FILETYPE_PEM);
#endif
serverTls12Ssl = wolfSSL_new(serverTls12Ctx);
clientCtx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
clientSsl = wolfSSL_new(clientCtx);
serverCtx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
#ifndef NO_CERTS
wolfSSL_CTX_use_certificate_chain_file(serverCtx, ourCert);
wolfSSL_CTX_use_PrivateKey_file(serverCtx, ourKey, SSL_FILETYPE_PEM);
#endif
serverSsl = wolfSSL_new(serverCtx);
#ifdef WOLFSSL_SEND_HRR_COOKIE
AssertIntEQ(wolfSSL_send_hrr_cookie(NULL, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_send_hrr_cookie(clientSsl, NULL, 0), SIDE_ERROR);
AssertIntEQ(wolfSSL_send_hrr_cookie(serverTls12Ssl, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_send_hrr_cookie(serverSsl, NULL, 0), SSL_SUCCESS);
AssertIntEQ(wolfSSL_send_hrr_cookie(serverSsl, fixedKey, sizeof(fixedKey)),
SSL_SUCCESS);
#endif
AssertIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_SECP256R1), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_SECP256R1),
SIDE_ERROR);
AssertIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_SECP256R1),
SSL_SUCCESS);
AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_SECP256R1),
SSL_SUCCESS);
AssertIntEQ(wolfSSL_NoKeyShares(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_NoKeyShares(serverSsl), SIDE_ERROR);
AssertIntEQ(wolfSSL_NoKeyShares(clientTls12Ssl), SSL_SUCCESS);
AssertIntEQ(wolfSSL_NoKeyShares(clientSsl), SSL_SUCCESS);
AssertIntEQ(wolfSSL_CTX_no_ticket_TLSv13(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_no_ticket_TLSv13(clientCtx), SIDE_ERROR);
AssertIntEQ(wolfSSL_CTX_no_ticket_TLSv13(serverTls12Ctx), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_no_ticket_TLSv13(serverCtx), 0);
AssertIntEQ(wolfSSL_no_ticket_TLSv13(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_no_ticket_TLSv13(clientSsl), SIDE_ERROR);
AssertIntEQ(wolfSSL_no_ticket_TLSv13(serverTls12Ssl), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_no_ticket_TLSv13(serverSsl), 0);
AssertIntEQ(wolfSSL_CTX_no_dhe_psk(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_no_dhe_psk(clientTls12Ctx), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_no_dhe_psk(serverCtx), 0);
AssertIntEQ(wolfSSL_CTX_no_dhe_psk(clientCtx), 0);
AssertIntEQ(wolfSSL_no_dhe_psk(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_no_dhe_psk(clientTls12Ssl), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_no_dhe_psk(serverSsl), 0);
AssertIntEQ(wolfSSL_no_dhe_psk(clientSsl), 0);
AssertIntEQ(wolfSSL_update_keys(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_update_keys(clientTls12Ssl), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_update_keys(serverSsl), BUILD_MSG_ERROR);
AssertIntEQ(wolfSSL_update_keys(clientSsl), BUILD_MSG_ERROR);
#if !defined(NO_CERTS) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
AssertIntEQ(wolfSSL_CTX_allow_post_handshake_auth(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_allow_post_handshake_auth(serverCtx), SIDE_ERROR);
AssertIntEQ(wolfSSL_CTX_allow_post_handshake_auth(clientTls12Ctx),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_allow_post_handshake_auth(clientCtx), 0);
AssertIntEQ(wolfSSL_allow_post_handshake_auth(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_allow_post_handshake_auth(serverSsl), SIDE_ERROR);
AssertIntEQ(wolfSSL_allow_post_handshake_auth(clientTls12Ssl),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_allow_post_handshake_auth(clientSsl), 0);
AssertIntEQ(wolfSSL_request_certificate(NULL), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_request_certificate(clientSsl), SIDE_ERROR);
AssertIntEQ(wolfSSL_request_certificate(serverTls12Ssl),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_request_certificate(serverSsl), NOT_READY_ERROR);
#endif
#ifdef WOLFSSL_EARLY_DATA
AssertIntEQ(wolfSSL_CTX_set_max_early_data(NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_max_early_data(clientCtx, 0), SIDE_ERROR);
AssertIntEQ(wolfSSL_CTX_set_max_early_data(serverTls12Ctx, 0),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_CTX_set_max_early_data(serverCtx, 0), 0);
AssertIntEQ(wolfSSL_set_max_early_data(NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_max_early_data(clientSsl, 0), SIDE_ERROR);
AssertIntEQ(wolfSSL_set_max_early_data(serverTls12Ssl, 0), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_set_max_early_data(serverSsl, 0), 0);
AssertIntEQ(wolfSSL_write_early_data(NULL, earlyData, sizeof(earlyData),
&outSz), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_write_early_data(clientSsl, NULL, sizeof(earlyData),
&outSz), BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_write_early_data(clientSsl, earlyData, -1, &outSz),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
sizeof(earlyData), NULL),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_write_early_data(serverSsl, earlyData,
sizeof(earlyData), &outSz),
SIDE_ERROR);
AssertIntEQ(wolfSSL_write_early_data(clientTls12Ssl, earlyData,
sizeof(earlyData), &outSz),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
sizeof(earlyData), &outSz),
SSL_FATAL_ERROR);
AssertIntEQ(wolfSSL_read_early_data(NULL, earlyDataBuffer,
sizeof(earlyDataBuffer), &outSz),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_read_early_data(serverSsl, NULL,
sizeof(earlyDataBuffer), &outSz),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_read_early_data(serverSsl, earlyDataBuffer, -1, &outSz),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_read_early_data(serverSsl, earlyDataBuffer,
sizeof(earlyDataBuffer), NULL),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_read_early_data(clientSsl, earlyDataBuffer,
sizeof(earlyDataBuffer), &outSz),
SIDE_ERROR);
AssertIntEQ(wolfSSL_read_early_data(serverTls12Ssl, earlyDataBuffer,
sizeof(earlyDataBuffer), &outSz),
BAD_FUNC_ARG);
AssertIntEQ(wolfSSL_read_early_data(serverSsl, earlyDataBuffer,
sizeof(earlyDataBuffer), &outSz),
SSL_FATAL_ERROR);
#endif
wolfSSL_free(serverSsl);
wolfSSL_CTX_free(serverCtx);
wolfSSL_free(clientSsl);
wolfSSL_CTX_free(clientCtx);
wolfSSL_free(serverTls12Ssl);
wolfSSL_CTX_free(serverTls12Ctx);
wolfSSL_free(clientTls12Ssl);
wolfSSL_CTX_free(clientTls12Ctx);
return ret;
}
#endif
/*----------------------------------------------------------------------------*
| Main
@ -7328,6 +7510,11 @@ void ApiTest(void)
test_wc_ecc_get_curve_id_from_name();
test_wc_ecc_get_curve_id_from_params();
#ifdef WOLFSSL_TLS13
/* TLS v1.3 API tests */
test_tls13_apis();
#endif
#ifndef NO_CERTS
/* Bad certificate signature tests */
AssertIntEQ(test_EccSigFailure_cm(), ASN_SIG_CONFIRM_E);

View File

@ -1502,6 +1502,9 @@ typedef struct Suites {
} Suites;
WOLFSSL_LOCAL void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
int haveRSAsig, int haveAnon,
int tls1_2);
WOLFSSL_LOCAL void InitSuites(Suites*, ProtocolVersion, word16, word16, word16, word16,
word16, word16, word16, int);
WOLFSSL_LOCAL int MatchSuite(WOLFSSL* ssl, Suites* peerSuites);
@ -2182,6 +2185,7 @@ struct WOLFSSL_CTX {
int certChainCnt;
#endif
DerBuffer* privateKey;
byte privateKeyType;
WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */
#endif
#ifdef KEEP_OUR_CERT
@ -2685,6 +2689,7 @@ typedef struct Buffers {
#ifndef NO_CERTS
DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */
DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */
byte keyType; /* Type of key: RSA, ECC, Ed25519 */
DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */
/* chain after self, in DER, with leading size for each cert */
#ifdef WOLFSSL_TLS13
@ -3557,6 +3562,9 @@ WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree);
WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl);
WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl);
WOLFSSL_LOCAL int SetTicket(WOLFSSL*, const byte*, word32);
#ifndef NO_CERTS
#ifndef NO_RSA
#ifdef WC_RSA_PSS