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