diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 707c68cb51d..1e0ccea9d62 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -997,6 +997,7 @@ WOLFSSL_SNIFFER_NO_RECOVERY WOLFSSL_SP_ARM32_UDIV WOLFSSL_SP_FAST_NCT_EXPTMOD WOLFSSL_SP_INT_SQR_VOLATILE +WOLFSSL_SSLKEYLOGFILE_USE_ENV WOLFSSL_STACK_CHECK WOLFSSL_STM32C5 WOLFSSL_STM32F3 diff --git a/configure.ac b/configure.ac index 537a51ff99c..4efba915b31 100644 --- a/configure.ac +++ b/configure.ac @@ -5490,7 +5490,7 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PSK_ONE_ID" fi -# Certificate Authentication with External PSK (RFC 8773bis) +# Certificate Authentication with External PSK (RFC 9973, obsoletes RFC 8773) AC_ARG_ENABLE([cert-with-extern-psk], [AS_HELP_STRING([--enable-cert-with-extern-psk],[Enable Certificate Authentication with External PSKs for TLS 1.3 (default: disabled)])], [ ENABLED_CERT_WITH_EXTERN_PSK=$enableval ], diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 59f44c3a54f..17cf99ef626 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -15313,7 +15313,7 @@ void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl, \ingroup Setup \brief Enable or disable TLS 1.3 certificate authentication with external - PSK (RFC8773bis) on a context. + PSK (RFC 9973) on a context. When enabled, wolfSSL advertises and accepts the `tls_cert_with_extern_psk` extension for TLS 1.3 handshakes using external @@ -15348,7 +15348,7 @@ int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx, int state); \ingroup Setup \brief Enable or disable TLS 1.3 certificate authentication with external - PSK (RFC8773bis) on a connection. + PSK (RFC 9973) on a connection. This call applies to a single WOLFSSL object. Any non-zero \p state value enables the feature and zero disables it. diff --git a/scripts/sniffer-tls13-keylog.sslkeylog b/scripts/sniffer-tls13-keylog.sslkeylog index dde5ad96ac2..0a8aef80775 100644 --- a/scripts/sniffer-tls13-keylog.sslkeylog +++ b/scripts/sniffer-tls13-keylog.sslkeylog @@ -1,3 +1,7 @@ +# RFC 9850: reader must ignore comment lines, blank lines, and malformed +# lines such as the INCOMPLETE_KEYLOG_LINE entry below + +INCOMPLETE_KEYLOG_LINE deadbeef CLIENT_HANDSHAKE_TRAFFIC_SECRET b28ffa242be7ecc3ef669ea686dc842c0de9efe938a0f047c28cb359710991f8 cfe4b2e9ef157938936ed15627e65338e6b5f5b251b1718e28b028eabecf3633 CLIENT_HANDSHAKE_TRAFFIC_SECRET b28ffa242be7ecc3ef669ea686dc842c0de9efe938a0f047c28cb359710991f8 cfe4b2e9ef157938936ed15627e65338e6b5f5b251b1718e28b028eabecf3633 SERVER_HANDSHAKE_TRAFFIC_SECRET b28ffa242be7ecc3ef669ea686dc842c0de9efe938a0f047c28cb359710991f8 737fd782b2e50c4982011f0ec7249d3f91b7e9e25529631c4794cfd4a83ceaf1 diff --git a/src/internal.c b/src/internal.c index 0ea1b04f2b7..feebabf54fc 100644 --- a/src/internal.c +++ b/src/internal.c @@ -23002,6 +23002,13 @@ const char* AlertTypeToString(int type) return certificate_required_str; } + case general_error: + { + static const char general_error_str[] = + "general_error"; + return general_error_str; + } + case no_application_protocol: { static const char no_application_protocol_str[] = diff --git a/src/sniffer.c b/src/sniffer.c index 7f0c4322552..a5bdf54d380 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -7582,7 +7582,10 @@ static int parseKeyLogFile(const char* fileName, char* error) /* 2 chars for Hexadecimal representation, plus null terminator */ char clientRandomHex[2 * CLIENT_RANDOM_LENGTH + 1] = {0}; char secretHex[2 * SECRET_LENGTH + 1] = {0}; - + /* One keylog record. RFC 9850 requires line based parsing so that comment + * and malformed lines cannot desynchronize the fields. Sized to hold the + * longest valid line plus separators and terminator. */ + char line[256]; file = fopen(fileName, "r"); if (file == NULL) { @@ -7591,10 +7594,27 @@ static int parseKeyLogFile(const char* fileName, char* error) return WOLFSSL_SNIFFER_ERROR; } - /* Format specifiers for each column should be: - * MAX_PREFIX_LENGTH, 2*CLIENT_RANDOM_LENGTH, and 2*SECRET_LENGTH */ - while (fscanf(file, "%31s %64s %96s", prefix, clientRandomHex, secretHex) - == 3) { + while (fgets(line, (int)sizeof(line), file) != NULL) { + /* RFC 9850 Section 1: ignore empty lines and lines whose first + * character is the octothorpe ('#') comment marker. */ + if (line[0] == '#' || line[0] == '\n' || line[0] == '\r' || + line[0] == '\0') { + continue; + } + + /* Clear the field buffers so that a short field on one line cannot + * pick up stale bytes left by a previous line. */ + XMEMSET(prefix, 0, sizeof(prefix)); + XMEMSET(clientRandomHex, 0, sizeof(clientRandomHex)); + XMEMSET(secretHex, 0, sizeof(secretHex)); + + /* RFC 9850 Section 2: silently ignore lines that do not conform to the + * "label SP random SP secret" format so that secrets can still be + * recovered from a corrupted file. */ + if (sscanf(line, "%31s %64s %96s", prefix, clientRandomHex, secretHex) + != 3) { + continue; + } if (XSTRCMP(prefix, "CLIENT_RANDOM") == 0) { type = SNIFFER_SECRET_TLS12_MASTER_SECRET; @@ -7621,6 +7641,14 @@ static int parseKeyLogFile(const char* fileName, char* error) continue; } + /* The client random is always CLIENT_RANDOM_LENGTH bytes. Reject a + * line whose random field is not the exact expected length. The secret + * length is left variable because it depends on the negotiated hash. */ + if (XSTRLEN(clientRandomHex) != (size_t)(2 * CLIENT_RANDOM_LENGTH)) { + fprintf(stderr, "malformed client random for prefix: %s\n", prefix); + continue; + } + hexToBin(clientRandomHex, clientRandom, CLIENT_RANDOM_LENGTH); hexToBin(secretHex, secret, SECRET_LENGTH); ret = addSecretNode(clientRandom, type, secret, error); @@ -7629,6 +7657,7 @@ static int parseKeyLogFile(const char* fileName, char* error) fclose(file); ForceZero(secret, SECRET_LENGTH); ForceZero(secretHex, sizeof(secretHex)); + ForceZero(line, sizeof(line)); return ret; } } @@ -7636,6 +7665,7 @@ static int parseKeyLogFile(const char* fileName, char* error) ForceZero(secret, SECRET_LENGTH); ForceZero(secretHex, sizeof(secretHex)); + ForceZero(line, sizeof(line)); return 0; } diff --git a/src/ssl.c b/src/ssl.c index f5a309552c1..9e01a7c4ff8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3722,7 +3722,18 @@ int tlsShowSecrets(WOLFSSL* ssl, void* secret, int secretSz, #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE) { - FILE* f = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "a"); + const char* keyLogFile = WOLFSSL_SSLKEYLOGFILE_OUTPUT; + FILE* f; + #ifdef WOLFSSL_SSLKEYLOGFILE_USE_ENV + /* RFC 9850: prefer the SSLKEYLOGFILE environment variable so other + * tools can share the path, else use the compile-time path. XGETENV is + * NULL where environment access is unavailable. Opt-in so a build with + * the variable exported for other applications is not affected. */ + const char* keyLogEnv = XGETENV("SSLKEYLOGFILE"); + if (keyLogEnv != NULL && keyLogEnv[0] != '\0') + keyLogFile = keyLogEnv; + #endif + f = XFOPEN(keyLogFile, "a"); if (f != XBADFILE) { XFWRITE(pmsBuf, 1, pmsPos, f); XFCLOSE(f); diff --git a/src/tls.c b/src/tls.c index 69c2e0a710b..9db47bfeee3 100644 --- a/src/tls.c +++ b/src/tls.c @@ -102,6 +102,7 @@ * WOLFSSL_SNIFFER: Enable TLS packet sniffing support default: off * WOLFSSL_SNIFFER_KEYLOGFILE: Sniffer keylog file support default: off * WOLFSSL_SSLKEYLOGFILE: Enable SSL key log file output default: off + * WOLFSSL_SSLKEYLOGFILE_USE_ENV: Use SSLKEYLOGFILE env var path default: off * WOLFSSL_SRTP: Enable SRTP extension support default: off * WOLFSSL_DUAL_ALG_CERTS: Enable dual algorithm certificates default: off * WOLFSSL_HAVE_PRF: Enable TLS PRF function access default: off @@ -16694,7 +16695,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #endif #if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) if (ssl->options.certWithExternPsk) { - /* RFC8773bis requires psk_dhe_ke with cert_with_extern_psk. */ + /* RFC 9973 requires psk_dhe_ke with cert_with_extern_psk. */ modes |= 1 << PSK_DHE_KE; } #endif @@ -18753,12 +18754,12 @@ WOLFSSL_TEST_VIS int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (msgType == client_hello && isRequest) { TLSX* pskm; - /* RFC8773bis: CH2 after HRR must keep CH1's extension set. */ + /* RFC 9973: CH2 after HRR must keep CH1's extension set. */ if (secondClientHello && !prevHasPskWithCert) { WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED); return EXT_NOT_ALLOWED; } - /* RFC8773bis: cert_with_extern_psk depends on these extensions. */ + /* RFC 9973: cert_with_extern_psk depends on these extensions. */ if (!hasPsk || !hasPskModes || !hasKeyShare || !hasSg || !hasSigAlg) { WOLFSSL_ERROR_VERBOSE(EXT_MISSING); @@ -18776,7 +18777,7 @@ WOLFSSL_TEST_VIS int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, } #endif pskm = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES); - /* RFC8773bis requires client support for psk_dhe_ke mode. */ + /* RFC 9973 requires client support for psk_dhe_ke mode. */ if (pskm == NULL || (pskm->val & (1 << PSK_DHE_KE)) == 0) { WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED); return EXT_NOT_ALLOWED; @@ -18792,7 +18793,7 @@ WOLFSSL_TEST_VIS int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, } else if (msgType == client_hello && isRequest && secondClientHello && prevHasPskWithCert) { - /* RFC8773bis: reject dropping the extension in CH2 after HRR. */ + /* RFC 9973: reject dropping the extension in CH2 after HRR. */ WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED); return EXT_NOT_ALLOWED; } diff --git a/src/tls13.c b/src/tls13.c index b8c7dbbc912..0edd6316dbf 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -72,6 +72,7 @@ * (no ciphersuite requires it currently) * WOLFSSL_ERROR_CODE_OPENSSL: Use OpenSSL-compatible error codes default: off * WOLFSSL_SSLKEYLOGFILE_OUTPUT: Set key log output file path default: off + * WOLFSSL_SSLKEYLOGFILE_USE_ENV: Use SSLKEYLOGFILE env var path default: off * WOLFSSL_RW_THREADED: Enable read/write threading support default: off * WOLFSSL_ASYNC_IO: Enable async I/O operations default: off * WOLFSSL_NONBLOCK_OCSP: Non-blocking OCSP processing default: off @@ -6004,12 +6005,12 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK if (ssl->options.certWithExternPsk && psk->resumption) { - /* RFC8773bis mode requires external PSK, not ticket resumption. */ + /* RFC 9973 mode requires external PSK, not ticket resumption. */ WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR); return PSK_KEY_ERROR; } if (ssl->options.certWithExternPsk && ssl->options.shSentKeyShare == 0) { - /* RFC8773bis Sec. 3: cert_with_extern_psk requires psk_dhe_ke; + /* RFC 9973 Sect. 3: cert_with_extern_psk requires psk_dhe_ke; * a ServerHello without a key_share confirms only psk_ke. */ WOLFSSL_MSG("cert_with_extern_psk: ServerHello missing key_share"); WOLFSSL_ERROR_VERBOSE(EXT_MISSING); @@ -6244,8 +6245,10 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, *inOutIdx += OPAQUE16_LEN; if ((*inOutIdx - begin) + len > size) return BUFFER_ERROR; - if (len == 0) - return INVALID_PARAMETER; + /* RFC 9846 Section 4.4.2: CertificateRequest.extensions has a lower bound of + * 0, so an empty extensions block is parsed rather than rejected here. A + * request missing the mandatory signature_algorithms extension is caught by + * the check below. */ if ((ret = TLSX_Parse(ssl, input + *inOutIdx, len, certificate_request, &peerSuites))) { return ret; @@ -6554,7 +6557,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, } if (ret == WOLFSSL_TICKET_RET_OK) { #if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(HAVE_SESSION_TICKET) - /* RFC 8773bis Sect. 5.1: all PSKs listed alongside + /* RFC 9973 Sect. 5.1: all PSKs listed alongside * tls_cert_with_extern_psk MUST be external PSKs. A successfully * decrypted session ticket identity is a resumption PSK, so the * server MUST abort with illegal_parameter regardless of whether @@ -6879,7 +6882,7 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, extEarlyData = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA); if (extEarlyData != NULL) { /* Check if accepting early data and first PSK. - * RFC 8773bis: early_data is not compatible with + * RFC 9973: early_data is not compatible with * cert_with_extern_psk, so skip key derivation in that case. */ if (ssl->earlyData != no_early_data && first && ssl->options.maxEarlyDataSz > 0 @@ -6949,7 +6952,7 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, ssl->options.sendVerify = SEND_CERT; certExt->resp = 1; #ifdef WOLFSSL_EARLY_DATA - /* RFC 8773bis: early_data is not compatible with + /* RFC 9973: early_data is not compatible with * cert_with_extern_psk. TLSX_Parse already rejects the * combination in the ClientHello, but clear the response flag * here as a defense-in-depth measure. */ @@ -12401,6 +12404,19 @@ int SendTls13KeyUpdate(WOLFSSL* ssl) } #endif /* WOLFSSL_DTLS13 */ + if (!ssl->options.dtls) { + /* RFC 9846 Section 4.7.3: a sending implementation MUST NOT allow its + * number of key updates to exceed 2^48-1. Receivers MUST NOT enforce + * this on the peer. */ + if (w64GTE(ssl->keys.keyUpdateCount, + w64From32(TLS13_KEY_UPDATE_MAX_HI32, + TLS13_KEY_UPDATE_MAX_LO32))) { + WOLFSSL_MSG("TLS 1.3 key update count at maximum; refusing " + "KeyUpdate"); + return BAD_STATE_E; + } + } + outputSz = OPAQUE8_LEN + MAX_MSG_EXTRA; /* Check buffers are big enough and grow if needed. */ if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) @@ -12472,6 +12488,9 @@ int SendTls13KeyUpdate(WOLFSSL* ssl) return ret; if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0) return ret; + + /* Count this key update against the RFC 9846 sender limit. */ + w64Increment(&ssl->keys.keyUpdateCount); } @@ -16419,10 +16438,25 @@ int tls13ShowSecrets(WOLFSSL* ssl, int id, const unsigned char* secret, byte clientRandom[RAN_LEN]; int clientRandomSz; XFILE fp; +#if defined(WOLFSSL_SSLKEYLOGFILE_OUTPUT) && defined(WOLFSSL_SSLKEYLOGFILE_USE_ENV) + const char* keyLogFile; +#endif (void) ctx; #ifdef WOLFSSL_SSLKEYLOGFILE_OUTPUT +#ifdef WOLFSSL_SSLKEYLOGFILE_USE_ENV + /* RFC 9850: prefer the SSLKEYLOGFILE environment variable so tools such as + * curl and Wireshark can share the path, else use the compile-time path. + * XGETENV resolves to NULL where environment access is unavailable. Opt-in + * so a build with the variable exported for other applications is not + * affected. */ + keyLogFile = XGETENV("SSLKEYLOGFILE"); + if (keyLogFile == NULL || keyLogFile[0] == '\0') + keyLogFile = WOLFSSL_SSLKEYLOGFILE_OUTPUT; + fp = XFOPEN(keyLogFile, "ab"); +#else fp = XFOPEN(WOLFSSL_SSLKEYLOGFILE_OUTPUT, "ab"); +#endif if (fp == XBADFILE) { return BAD_FUNC_ARG; } diff --git a/tests/api/test_tls13.c b/tests/api/test_tls13.c index 75c453a1211..fe311bf548f 100644 --- a/tests/api/test_tls13.c +++ b/tests/api/test_tls13.c @@ -1206,7 +1206,7 @@ int test_tls13_cert_with_extern_psk_rejects_resumption(void) ssl_s = NULL; /* Step 2: attempt to resume while also offering cert_with_extern_psk. - * RFC 8773bis Sect. 5.1 requires all PSKs offered alongside + * RFC 9973 Sect. 5.1 requires all PSKs offered alongside * cert_with_extern_psk to be external PSKs. The client MUST therefore * suppress the resumption ticket identity from the pre_shared_key * extension. The handshake succeeds as a cert_with_extern_psk handshake @@ -8652,3 +8652,52 @@ int test_tls13_AEAD_limit_KU_aes128_ccm_8_sha256(void) return EXPECT_RESULT(); } +/* RFC 9846 Section 4.7.3: a sending implementation MUST NOT allow its number of + * key updates to exceed 2^48-1. Establish a TLS 1.3 connection and exercise both + * sides of the boundary: one update seeded just below the ceiling must succeed + * and advance the sender count to exactly 2^48-1, and a further update once the + * count has reached the ceiling must be refused with BAD_STATE_E without + * advancing the count. The count is inspected directly because + * SendTls13KeyUpdate enforces the limit before touching the transport. */ +int test_tls13_KeyUpdate_sender_limit(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT) && \ + !defined(NO_WOLFSSL_SERVER) && \ + defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) + struct test_memio_ctx test_ctx; + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + if (EXPECT_SUCCESS() && ssl_c != NULL) { + w64wrapper ceiling; + + ceiling = w64From32(TLS13_KEY_UPDATE_MAX_HI32, TLS13_KEY_UPDATE_MAX_LO32); + + /* One below the ceiling: the update is allowed and must advance the + * sender count by one, reaching exactly 2^48-1. */ + ssl_c->keys.keyUpdateCount = w64From32(TLS13_KEY_UPDATE_MAX_HI32, + TLS13_KEY_UPDATE_MAX_LO32 - 1); + ExpectIntEQ(wolfSSL_update_keys(ssl_c), WOLFSSL_SUCCESS); + ExpectTrue(w64Equal(ssl_c->keys.keyUpdateCount, ceiling)); + + /* At the ceiling: a further update must be refused rather than + * advancing the count past 2^48-1. */ + ExpectIntEQ(wolfSSL_update_keys(ssl_c), WC_NO_ERR_TRACE(BAD_STATE_E)); + ExpectTrue(w64Equal(ssl_c->keys.keyUpdateCount, ceiling)); + } + + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); +#endif + return EXPECT_RESULT(); +} + diff --git a/tests/api/test_tls13.h b/tests/api/test_tls13.h index 08cb3408445..05f2be54f2d 100644 --- a/tests/api/test_tls13.h +++ b/tests/api/test_tls13.h @@ -102,6 +102,7 @@ int test_tls13_AEAD_limit_KU_aes128_gcm_sha256(void); int test_tls13_AEAD_limit_KU_aes256_gcm_sha384(void); int test_tls13_AEAD_limit_KU_aes128_ccm_sha256(void); int test_tls13_AEAD_limit_KU_aes128_ccm_8_sha256(void); +int test_tls13_KeyUpdate_sender_limit(void); int test_tls13_pqc_hybrid_async_server(void); #define TEST_TLS13_DECLS \ @@ -183,6 +184,7 @@ int test_tls13_pqc_hybrid_async_server(void); TEST_DECL_GROUP("tls13", test_tls13_AEAD_limit_KU_aes256_gcm_sha384), \ TEST_DECL_GROUP("tls13", test_tls13_AEAD_limit_KU_aes128_ccm_sha256), \ TEST_DECL_GROUP("tls13", test_tls13_AEAD_limit_KU_aes128_ccm_8_sha256), \ + TEST_DECL_GROUP("tls13", test_tls13_KeyUpdate_sender_limit), \ TEST_DECL_GROUP("tls13", test_tls13_pqc_hybrid_async_server) #endif /* WOLFCRYPT_TEST_TLS13_H */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d54496e0f9c..60e2a2e425d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2964,6 +2964,7 @@ typedef struct Keys { #ifdef WOLFSSL_TLS13 byte updateResponseReq; /* KeyUpdate response from peer required. */ byte keyUpdateRespond; /* KeyUpdate is to be responded to. */ + w64wrapper keyUpdateCount; /* Sending key updates performed (RFC 9846). */ #endif #ifdef WOLFSSL_RENESAS_TSIP_TLS @@ -2977,6 +2978,12 @@ typedef struct Keys { #endif } Keys; +/* RFC 9846 Section 4.7.3: a TLS 1.3 sender MUST NOT allow its number of key + * updates to exceed 2^48-1. Receivers MUST NOT enforce this. Expressed as the + * high and low 32-bit halves of a w64wrapper. */ +#define TLS13_KEY_UPDATE_MAX_HI32 0x0000FFFFU +#define TLS13_KEY_UPDATE_MAX_LO32 0xFFFFFFFFU + /* Forward declare opaque pointer to make available for func def */ typedef struct Options Options; @@ -2999,7 +3006,7 @@ typedef struct Options Options; #define TLSXT_SERVER_CERTIFICATE 0x0014 /* RFC8446 */ #define TLSXT_ENCRYPT_THEN_MAC 0x0016 /* RFC 7366 */ #define TLSXT_EXTENDED_MASTER_SECRET 0x0017 /* HELLO_EXT_EXTMS */ -#define TLSXT_CERT_WITH_EXTERN_PSK 0x0021 /* RFC 8773bis */ +#define TLSXT_CERT_WITH_EXTERN_PSK 0x0021 /* RFC 9973 */ #define TLSXT_SESSION_TICKET 0x0023 #define TLSXT_PRE_SHARED_KEY 0x0029 #define TLSXT_EARLY_DATA 0x002a diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b5a0fb4a07a..7ad5749c016 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1010,6 +1010,7 @@ enum AlertDescription { bad_certificate_status_response = 113, /**< RFC 6066, section 8 */ unknown_psk_identity = 115, /**< RFC 4279, section 2 */ certificate_required = 116, /**< RFC 8446, section 8.2 */ + general_error = 117, /**< RFC 9846, section 6.2 */ no_application_protocol = 120, ech_required = 121 /**< RFC 9849, section 5 */ };