From d2ce95955d491459bdbbdc3563fa629e76ae8bb9 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 29 Jun 2017 09:00:44 +1000 Subject: [PATCH] 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. --- examples/client/client.c | 16 ++- scripts/tls13.test | 32 +++++ src/internal.c | 103 +++++++------- src/ssl.c | 6 + src/tls13.c | 284 +++++++++++---------------------------- tests/api.c | 187 ++++++++++++++++++++++++++ wolfssl/internal.h | 8 ++ 7 files changed, 381 insertions(+), 255 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index bd2422a45..8a2f9db81 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -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); } diff --git a/scripts/tls13.test b/scripts/tls13.test index 0632c4f8e..8bf57f471 100755 --- a/scripts/tls13.test +++ b/scripts/tls13.test @@ -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 diff --git a/src/internal.c b/src/internal.c index c215465f8..79283d3da 100755 --- a/src/internal.c +++ b/src/internal.c @@ -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)) { diff --git a/src/ssl.c b/src/ssl.c index 2955fb9d7..0acc0832c 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -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); diff --git a/src/tls13.c b/src/tls13.c index 6ee7f2bcc..3981b1f48 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -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; diff --git a/tests/api.c b/tests/api.c index 94a093999..8f4033fff 100644 --- a/tests/api.c +++ b/tests/api.c @@ -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); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 50ae73dd4..0f28c4106 100755 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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