diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2022-11-30 20:07:11 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2022-11-30 20:07:11 +0300 |
commit | 3dfe99f4cc702156a58dce52df0cf2100c626241 (patch) | |
tree | 73ae0e2d09d6ffc5bbb24123bd97592ca45cfde0 | |
parent | 5941cbae8a1b816d4743f50c20c7a5631af4e8e1 (diff) | |
download | ydb-3dfe99f4cc702156a58dce52df0cf2100c626241.tar.gz |
Update contrib/restricted/aws/s2n to 1.3.28
54 files changed, 916 insertions, 246 deletions
diff --git a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt index b3c337c78b..8c122d8e34 100644 --- a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt +++ b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt @@ -156,6 +156,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_kex.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_key_log.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_key_update.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_next_protocol.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_prf.c @@ -186,7 +187,6 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls.c - ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c diff --git a/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt b/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt index c10014f87f..8881bf5fcc 100644 --- a/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/aws/s2n/CMakeLists.linux-aarch64.txt @@ -150,6 +150,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_kex.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_key_log.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_key_update.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_next_protocol.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_prf.c @@ -180,7 +181,6 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls.c - ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c diff --git a/contrib/restricted/aws/s2n/CMakeLists.linux.txt b/contrib/restricted/aws/s2n/CMakeLists.linux.txt index 504c30980d..96a5316961 100644 --- a/contrib/restricted/aws/s2n/CMakeLists.linux.txt +++ b/contrib/restricted/aws/s2n/CMakeLists.linux.txt @@ -157,6 +157,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_kex.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_key_log.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_key_update.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_next_protocol.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_ocsp_stapling.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_post_handshake.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_prf.c @@ -187,7 +188,6 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_signature_scheme.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls.c - ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_certificate_verify.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c diff --git a/contrib/restricted/aws/s2n/api/s2n.h b/contrib/restricted/aws/s2n/api/s2n.h index 7e2e6581c8..eda5bdd7a2 100644 --- a/contrib/restricted/aws/s2n/api/s2n.h +++ b/contrib/restricted/aws/s2n/api/s2n.h @@ -188,7 +188,7 @@ struct s2n_config; struct s2n_connection; /** - * Prevents S2N from calling `OPENSSL_crypto_init`/`OPENSSL_cleanup`/`EVP_cleanup` on OpenSSL versions + * Prevents S2N from calling `OPENSSL_init_crypto`/`OPENSSL_cleanup`/`EVP_cleanup` on OpenSSL versions * prior to 1.1.x. This allows applications or languages that also init OpenSSL to interoperate * with S2N. * @@ -197,7 +197,7 @@ struct s2n_connection; * * @note If you disable this and are using a version of OpenSSL/libcrypto < 1.1.x, you will * be responsible for library init and cleanup (specifically `OPENSSL_add_all_algorithms()` - * or `OPENSSL_crypto_init()`, and EVP_* APIs will not be usable unless the library is initialized. + * or `OPENSSL_init_crypto()`, and EVP_* APIs will not be usable unless the library is initialized. * * @returns S2N_SUCCESS on success. S2N_FAILURE on failure */ @@ -2818,19 +2818,25 @@ S2N_API extern uint64_t s2n_connection_get_wire_bytes_out(struct s2n_connection *conn); /** - * Access the protocol version supported by the client of the connection. + * Access the protocol version supported by the client. + * + * @note The return value corresponds to the macros defined as S2N_SSLv2, + * S2N_SSLv3, S2N_TLS10, S2N_TLS11, S2N_TLS12, and S2N_TLS13. * * @param conn A pointer to the connection - * @returns returns the protocol version number supported by the client_auth_type + * @returns returns the highest protocol version supported by the client */ S2N_API extern int s2n_connection_get_client_protocol_version(struct s2n_connection *conn); /** - * Access the protocol version supported by the server of the connection. + * Access the protocol version supported by the server. + * + * @note The return value corresponds to the macros defined as S2N_SSLv2, + * S2N_SSLv3, S2N_TLS10, S2N_TLS11, S2N_TLS12, and S2N_TLS13. * * @param conn A pointer to the connection - * @returns Returns the protocol version number supported by the server + * @returns Returns the highest protocol version supported by the server */ S2N_API extern int s2n_connection_get_server_protocol_version(struct s2n_connection *conn); @@ -2838,8 +2844,11 @@ extern int s2n_connection_get_server_protocol_version(struct s2n_connection *con /** * Access the protocol version selected for the connection. * + * @note The return value corresponds to the macros defined as S2N_SSLv2, + * S2N_SSLv3, S2N_TLS10, S2N_TLS11, S2N_TLS12, and S2N_TLS13. + * * @param conn A pointer to the connection - * @returns The protocol version number actually used by s2n-tls for the connection + * @returns The protocol version actually negotiated by the handshake */ S2N_API extern int s2n_connection_get_actual_protocol_version(struct s2n_connection *conn); @@ -2847,6 +2856,9 @@ extern int s2n_connection_get_actual_protocol_version(struct s2n_connection *con /** * Access the client hello protocol version for the connection. * + * @note The return value corresponds to the macros defined as S2N_SSLv2, + * S2N_SSLv3, S2N_TLS10, S2N_TLS11, S2N_TLS12, and S2N_TLS13. + * * @param conn A pointer to the connection * @returns The protocol version used to send the initial client hello message. */ diff --git a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c index 0768451c1b..f044352b6d 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c @@ -32,7 +32,7 @@ * AWS-LC define OPENSSL_VERSION_NUMBER. */ #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) #define S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC -#elif (S2N_OPENSSL_VERSION_AT_LEAST(1,1,0)) +#elif (S2N_OPENSSL_VERSION_AT_LEAST(1,1,0) && !defined(LIBRESSL_VERSION_NUMBER)) #define S2N_CHACHA20_POLY1305_AVAILABLE_OSSL #endif diff --git a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c index 9f6bc31249..513b6d09ed 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c @@ -37,7 +37,7 @@ static const BIGNUM *s2n_get_Ys_dh_param(struct s2n_dh_params *dh_params) const BIGNUM *Ys; /* DH made opaque in Openssl 1.1.0 */ -#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) +#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) DH_get0_key(dh_params->dh, &Ys, NULL); #else Ys = dh_params->dh->pub_key; @@ -49,7 +49,7 @@ static const BIGNUM *s2n_get_Ys_dh_param(struct s2n_dh_params *dh_params) static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params) { const BIGNUM *p; -#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) +#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) DH_get0_pqg(dh_params->dh, &p, NULL, NULL); #else p = dh_params->dh->p; @@ -61,7 +61,7 @@ static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params) static const BIGNUM *s2n_get_g_dh_param(struct s2n_dh_params *dh_params) { const BIGNUM *g; -#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) +#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) DH_get0_pqg(dh_params->dh, NULL, NULL, &g); #else g = dh_params->dh->g; @@ -109,7 +109,7 @@ static int s2n_set_p_g_Ys_dh_params(struct s2n_dh_params *dh_params, struct s2n_ BIGNUM *bn_g = BN_bin2bn(( const unsigned char * )g->data, g->size, NULL); BIGNUM *bn_Ys = BN_bin2bn(( const unsigned char * )Ys->data, Ys->size, NULL); -#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) +#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) /* Per https://www.openssl.org/docs/man1.1.0/crypto/DH_get0_pqg.html: * values that have been passed in should not be freed directly after this function has been called */ diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl.h index a6cebf982f..d0d2b2d2b2 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_openssl.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl.h @@ -25,7 +25,11 @@ */ #if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L) #undef OPENSSL_VERSION_NUMBER +#if LIBRESSL_VERSION_NUMBER < 0x3050000fL #define OPENSSL_VERSION_NUMBER 0x1000107fL +#else +#define OPENSSL_VERSION_NUMBER 0x1010000fL +#endif #endif /* Per https://wiki.openssl.org/index.php/Manual:OPENSSL_VERSION_NUMBER(3) @@ -38,7 +42,7 @@ #define S2N_OPENSSL_VERSION_AT_LEAST(major, minor, fix) \ (OPENSSL_VERSION_NUMBER >= ((major << 28) + (minor << 20) + (fix << 12))) -#if (S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)) && (!defined(OPENSSL_IS_BORINGSSL)) && (!defined(OPENSSL_IS_AWSLC)) +#if (S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)) && (!defined(OPENSSL_IS_BORINGSSL)) && (!defined(OPENSSL_IS_AWSLC)) && (!defined(LIBRESSL_VERSION_NUMBER)) #define s2n_evp_ctx_init(ctx) POSIX_GUARD_OSSL(EVP_CIPHER_CTX_init(ctx), S2N_ERR_DRBG) #define RESULT_EVP_CTX_INIT(ctx) RESULT_GUARD_OSSL(EVP_CIPHER_CTX_init(ctx), S2N_ERR_DRBG) #else diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c index 27d2f7c32c..ff6b5340b7 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c @@ -52,7 +52,7 @@ RSA *s2n_unsafe_rsa_get_non_const(const struct s2n_rsa_key *rsa_key) { static S2N_RESULT s2n_rsa_modulus_check(const RSA *rsa) { /* RSA was made opaque starting in Openssl 1.1.0 */ -#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) +#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) const BIGNUM *n = NULL; /* RSA still owns the memory for n */ RSA_get0_key(rsa, &n, NULL, NULL); diff --git a/contrib/restricted/aws/s2n/error/s2n_errno.c b/contrib/restricted/aws/s2n/error/s2n_errno.c index ce77f9f315..4d64fc4531 100644 --- a/contrib/restricted/aws/s2n/error/s2n_errno.c +++ b/contrib/restricted/aws/s2n/error/s2n_errno.c @@ -99,6 +99,14 @@ static const char *no_such_error = "Internal s2n error"; ERR_ENTRY(S2N_ERR_CERT_TYPE_UNSUPPORTED, "Certificate Type is unsupported") \ ERR_ENTRY(S2N_ERR_CERT_INVALID, "Certificate is invalid") \ ERR_ENTRY(S2N_ERR_CERT_MAX_CHAIN_DEPTH_EXCEEDED, "The maximum certificate chain depth has been exceeded") \ + ERR_ENTRY(S2N_ERR_CRL_LOOKUP_FAILED, "No CRL could be found for the corresponding certificate") \ + ERR_ENTRY(S2N_ERR_CRL_SIGNATURE, "The signature of the CRL is invalid") \ + ERR_ENTRY(S2N_ERR_CRL_ISSUER, "Unable to get the CRL issuer certificate") \ + ERR_ENTRY(S2N_ERR_CRL_UNHANDLED_CRITICAL_EXTENSION, "Unhandled critical CRL extension") \ + ERR_ENTRY(S2N_ERR_CRL_INVALID_THIS_UPDATE, "The CRL contains an invalid thisUpdate field") \ + ERR_ENTRY(S2N_ERR_CRL_INVALID_NEXT_UPDATE, "The CRL contains an invalid nextUpdate field") \ + ERR_ENTRY(S2N_ERR_CRL_NOT_YET_VALID, "The CRL is not yet valid") \ + ERR_ENTRY(S2N_ERR_CRL_EXPIRED, "The CRL has expired") \ ERR_ENTRY(S2N_ERR_INVALID_MAX_FRAG_LEN, "invalid Maximum Fragmentation Length encountered") \ ERR_ENTRY(S2N_ERR_MAX_FRAG_LEN_MISMATCH, "Negotiated Maximum Fragmentation Length from server does not match the requested length by client") \ ERR_ENTRY(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED, "TLS protocol version is not supported by configuration") \ diff --git a/contrib/restricted/aws/s2n/error/s2n_errno.h b/contrib/restricted/aws/s2n/error/s2n_errno.h index 40eebfa157..61e194891e 100644 --- a/contrib/restricted/aws/s2n/error/s2n_errno.h +++ b/contrib/restricted/aws/s2n/error/s2n_errno.h @@ -113,6 +113,14 @@ typedef enum { S2N_ERR_CERT_TYPE_UNSUPPORTED, S2N_ERR_CERT_INVALID, S2N_ERR_CERT_MAX_CHAIN_DEPTH_EXCEEDED, + S2N_ERR_CRL_LOOKUP_FAILED, + S2N_ERR_CRL_SIGNATURE, + S2N_ERR_CRL_ISSUER, + S2N_ERR_CRL_UNHANDLED_CRITICAL_EXTENSION, + S2N_ERR_CRL_INVALID_THIS_UPDATE, + S2N_ERR_CRL_INVALID_NEXT_UPDATE, + S2N_ERR_CRL_NOT_YET_VALID, + S2N_ERR_CRL_EXPIRED, S2N_ERR_INVALID_MAX_FRAG_LEN, S2N_ERR_MAX_FRAG_LEN_MISMATCH, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED, diff --git a/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h b/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h index 0701e6b270..9573242e8e 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h +++ b/contrib/restricted/aws/s2n/pq-crypto/s2n_pq_asm.h @@ -19,7 +19,7 @@ #define S2N_BLOCK_NONPORTABLE_OPTIMIZATIONS 0 #endif -#define S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED __AVX__ || __AVX2__ || __BMI2__ +#define S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED (__AVX__ || __AVX2__ || __BMI2__) #if S2N_BLOCK_NONPORTABLE_OPTIMIZATIONS && S2N_ANY_NONPORTABLE_OPTIMIZATIONS_ENABLED #define S2N_ENSURE_PORTABLE_OPTIMIZATIONS \ diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_ems.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_ems.c index 0fd8d83c5d..64664a5abb 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_ems.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_ems.c @@ -46,7 +46,8 @@ static int s2n_client_ems_recv(struct s2n_connection *conn, struct s2n_stuffer * { POSIX_ENSURE_REF(conn); - /* Read nothing. The extension just needs to exist. */ + /* Read nothing. The extension just needs to exist without data. */ + POSIX_ENSURE(s2n_stuffer_data_available(extension) == 0, S2N_ERR_UNSUPPORTED_EXTENSION); conn->ems_negotiated = true; return S2N_SUCCESS; @@ -65,7 +66,7 @@ static int s2n_client_ems_recv(struct s2n_connection *conn, struct s2n_stuffer * static bool s2n_client_ems_should_send(struct s2n_connection *conn) { /* Don't send this extension if the previous session did not negotiate EMS */ - if (conn->set_session && !conn->ems_negotiated) { + if (conn && conn->set_session && !conn->ems_negotiated) { return false; } else { return true; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c index 6abb8bf568..800fce4aaf 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c @@ -166,7 +166,7 @@ static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer * /* Write obfuscated ticket age */ uint32_t obfuscated_ticket_age = 0; uint64_t current_time = 0; - POSIX_GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_time)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, ¤t_time)); POSIX_GUARD_RESULT(s2n_generate_obfuscated_ticket_age(psk, current_time, &obfuscated_ticket_age)); POSIX_GUARD(s2n_stuffer_write_uint32(out, obfuscated_ticket_age)); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c index d8505894cd..e3513e00aa 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c @@ -62,7 +62,12 @@ static const s2n_extension_type *const client_hello_extensions[] = { &s2n_client_signature_algorithms_extension, &s2n_client_server_name_extension, + + /* We MUST process the NPN extension after the ALPN extension + * because NPN is only negotiated if ALPN is not */ &s2n_client_alpn_extension, + &s2n_client_npn_extension, + &s2n_client_status_request_extension, &s2n_client_sct_list_extension, &s2n_client_max_frag_len_extension, @@ -75,7 +80,6 @@ static const s2n_extension_type *const client_hello_extensions[] = { &s2n_psk_key_exchange_modes_extension, &s2n_client_early_data_indication_extension, &s2n_client_ems_extension, - &s2n_client_npn_extension, &s2n_client_psk_extension /* MUST be last */ }; @@ -124,10 +128,6 @@ static const s2n_extension_type *const encrypted_extensions[] = { &s2n_server_early_data_indication_extension, }; -static const s2n_extension_type *const tls12_encrypted_extensions[] = { - &s2n_npn_encrypted_extension, -}; - static const s2n_extension_type *const cert_req_extensions[] = { &s2n_server_signature_algorithms_extension, }; @@ -152,7 +152,6 @@ static s2n_extension_type_list extension_lists[] = { [S2N_EXTENSION_LIST_CERT_REQ] = S2N_EXTENSION_LIST(cert_req_extensions), [S2N_EXTENSION_LIST_CERTIFICATE] = S2N_EXTENSION_LIST(certificate_extensions), [S2N_EXTENSION_LIST_NST] = S2N_EXTENSION_LIST(nst_extensions), - [S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12] = S2N_EXTENSION_LIST(tls12_encrypted_extensions), [S2N_EXTENSION_LIST_EMPTY] = { .extension_types = NULL, .count = 0 }, }; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c index 4731f97ffb..42e9905199 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.c @@ -24,24 +24,39 @@ bool s2n_npn_should_send(struct s2n_connection *conn) { - return s2n_client_alpn_should_send(conn) && conn->config->npn_supported; + /* + *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-03#section-3 + *# For the same reasons, after a handshake has been performed for a + *# given connection, renegotiations on the same connection MUST NOT + *# include the "next_protocol_negotiation" extension. + */ + return s2n_client_alpn_should_send(conn) && conn->config->npn_supported && !s2n_handshake_is_renegotiation(conn); +} + +int s2n_client_npn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + /* Only use the NPN extension to negotiate a protocol if we don't have + * an option to use the ALPN extension. + */ + if (s2n_npn_should_send(conn) && !s2n_server_alpn_should_send(conn)) { + conn->npn_negotiated = true; + } + + return S2N_SUCCESS; } const s2n_extension_type s2n_client_npn_extension = { .iana_value = TLS_EXTENSION_NPN, .is_response = false, .send = s2n_extension_send_noop, - .recv = s2n_extension_recv_noop, + .recv = s2n_client_npn_recv, .should_send = s2n_npn_should_send, .if_missing = s2n_extension_noop_if_missing, }; bool s2n_server_npn_should_send(struct s2n_connection *conn) { - /* Only use the NPN extension to negotiate a protocol if we don't have - * an option to use the ALPN extension. - */ - return s2n_npn_should_send(conn) && !s2n_server_alpn_should_send(conn); + return conn->npn_negotiated; } int s2n_server_npn_send(struct s2n_connection *conn, struct s2n_stuffer *out) @@ -67,7 +82,7 @@ int s2n_server_npn_recv(struct s2n_connection *conn, struct s2n_stuffer *extensi } /* - *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-04#section-3 + *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-03#section-3 *# The "extension_data" field of a "next_protocol_negotiation" extension *# in a "ServerHello" contains an optional list of protocols advertised *# by the server. @@ -77,7 +92,7 @@ int s2n_server_npn_recv(struct s2n_connection *conn, struct s2n_stuffer *extensi } /* - *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-04#section-4 + *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-03#section-4 *# In the event that the client doesn't support any of server's protocols, or *# the server doesn't advertise any, it SHOULD select the first protocol *# that it supports. @@ -94,6 +109,8 @@ int s2n_server_npn_recv(struct s2n_connection *conn, struct s2n_stuffer *extensi conn->application_protocol[protocol.size] = '\0'; } + conn->npn_negotiated = true; + return S2N_SUCCESS; } @@ -105,73 +122,3 @@ const s2n_extension_type s2n_server_npn_extension = { .should_send = s2n_server_npn_should_send, .if_missing = s2n_extension_noop_if_missing, }; - -bool s2n_npn_encrypted_should_send(struct s2n_connection *conn) -{ - return s2n_server_alpn_should_send(conn); -} - -S2N_RESULT s2n_calculate_padding(uint8_t protocol_len, uint8_t *padding_len) -{ - RESULT_ENSURE_REF(padding_len); - - /* - *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-04#section-3 - *# The length of "padding" SHOULD be 32 - ((len(selected_protocol) + 2) % 32). - */ - *padding_len = 32 - ((protocol_len + 2) % 32); - return S2N_RESULT_OK; -} - -int s2n_npn_encrypted_extension_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - uint8_t protocol_len = strlen(conn->application_protocol); - POSIX_GUARD(s2n_stuffer_write_uint8(out, protocol_len)); - POSIX_GUARD(s2n_stuffer_write_bytes(out, (uint8_t*) conn->application_protocol, protocol_len)); - - uint8_t padding_len = 0; - POSIX_GUARD_RESULT(s2n_calculate_padding(protocol_len, &padding_len)); - POSIX_GUARD(s2n_stuffer_write_uint8(out, padding_len)); - for (size_t i = 0; i < padding_len; i++) { - POSIX_GUARD(s2n_stuffer_write_uint8(out, 0)); - } - - return S2N_SUCCESS; -} - -int s2n_npn_encrypted_extension_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - uint8_t protocol_len = 0; - POSIX_GUARD(s2n_stuffer_read_uint8(extension, &protocol_len)); - - uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len); - POSIX_ENSURE_REF(protocol); - POSIX_CHECKED_MEMCPY(conn->application_protocol, protocol, protocol_len); - conn->application_protocol[protocol_len] = '\0'; - - uint8_t expected_padding_len = 0; - POSIX_GUARD_RESULT(s2n_calculate_padding(protocol_len, &expected_padding_len)); - uint8_t padding_len = 0; - POSIX_GUARD(s2n_stuffer_read_uint8(extension, &padding_len)); - POSIX_ENSURE_EQ(padding_len, expected_padding_len); - - for (size_t i = 0; i < padding_len; i++) { - uint8_t byte = 0; - POSIX_GUARD(s2n_stuffer_read_uint8(extension, &byte)); - POSIX_ENSURE_EQ(byte, 0); - } - POSIX_ENSURE_EQ(s2n_stuffer_data_available(extension), 0); - - return S2N_SUCCESS; -} - -const s2n_extension_type s2n_npn_encrypted_extension = { - .iana_value = TLS_EXTENSION_NPN, - .is_response = true, - .send = s2n_npn_encrypted_extension_send, - .recv = s2n_npn_encrypted_extension_recv, - .should_send = s2n_npn_encrypted_should_send, - /* The NPN extension is the only one defined for TLS1.2 Encrypted Extensions. - * If it's missing, something has gone wrong. */ - .if_missing = s2n_extension_error_if_missing, -}; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h index 81f0f60220..0b03e5c1b4 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_npn.h @@ -19,4 +19,3 @@ extern const s2n_extension_type s2n_client_npn_extension; extern const s2n_extension_type s2n_server_npn_extension; -extern const s2n_extension_type s2n_npn_encrypted_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_ems.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_ems.c index 06f0474d8d..c5170eb714 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_ems.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_ems.c @@ -47,7 +47,8 @@ static int s2n_server_ems_recv(struct s2n_connection *conn, struct s2n_stuffer * { POSIX_ENSURE_REF(conn); - /* Read nothing. The extension just needs to exist. */ + /* Read nothing. The extension just needs to exist without any data. */ + POSIX_ENSURE(s2n_stuffer_data_available(extension) == 0, S2N_ERR_UNSUPPORTED_EXTENSION); conn->ems_negotiated = true; return S2N_SUCCESS; diff --git a/contrib/restricted/aws/s2n/tls/s2n_alerts.c b/contrib/restricted/aws/s2n/tls/s2n_alerts.c index 8ed8a3adc1..8431525276 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_alerts.c +++ b/contrib/restricted/aws/s2n/tls/s2n_alerts.c @@ -109,6 +109,14 @@ static S2N_RESULT s2n_translate_protocol_error_to_alert(int error_code, uint8_t S2N_NO_ALERT(S2N_ERR_CERT_TYPE_UNSUPPORTED); S2N_NO_ALERT(S2N_ERR_CERT_INVALID); S2N_NO_ALERT(S2N_ERR_CERT_MAX_CHAIN_DEPTH_EXCEEDED); + S2N_NO_ALERT(S2N_ERR_CRL_LOOKUP_FAILED); + S2N_NO_ALERT(S2N_ERR_CRL_SIGNATURE); + S2N_NO_ALERT(S2N_ERR_CRL_ISSUER); + S2N_NO_ALERT(S2N_ERR_CRL_UNHANDLED_CRITICAL_EXTENSION); + S2N_NO_ALERT(S2N_ERR_CRL_INVALID_THIS_UPDATE); + S2N_NO_ALERT(S2N_ERR_CRL_INVALID_NEXT_UPDATE); + S2N_NO_ALERT(S2N_ERR_CRL_NOT_YET_VALID); + S2N_NO_ALERT(S2N_ERR_CRL_EXPIRED); S2N_NO_ALERT(S2N_ERR_INVALID_MAX_FRAG_LEN); S2N_NO_ALERT(S2N_ERR_MAX_FRAG_LEN_MISMATCH); S2N_NO_ALERT(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); diff --git a/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c b/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c index dbdb9dfb78..585be4ff54 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c +++ b/contrib/restricted/aws/s2n/tls/s2n_change_cipher_spec.c @@ -49,9 +49,6 @@ int s2n_client_ccs_recv(struct s2n_connection *conn) struct s2n_blob seq = {.data = conn->secure->client_sequence_number,.size = sizeof(conn->secure->client_sequence_number) }; POSIX_GUARD(s2n_blob_zero(&seq)); - /* Compute the finished message */ - POSIX_GUARD(s2n_prf_client_finished(conn)); - /* Update the client to use the cipher-suite */ conn->client = conn->secure; diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c index df7aa796c6..f16304a6ce 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c +++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.c @@ -1056,11 +1056,12 @@ S2N_RESULT s2n_cipher_suites_cleanup(void) return S2N_RESULT_OK; } -S2N_RESULT s2n_cipher_suite_from_iana(const uint8_t iana[static S2N_TLS_CIPHER_SUITE_LEN], struct s2n_cipher_suite **cipher_suite) +S2N_RESULT s2n_cipher_suite_from_iana(const uint8_t *iana, size_t iana_len, struct s2n_cipher_suite **cipher_suite) { RESULT_ENSURE_REF(cipher_suite); *cipher_suite = NULL; RESULT_ENSURE_REF(iana); + RESULT_ENSURE_EQ(iana_len, S2N_TLS_CIPHER_SUITE_LEN); int low = 0; int top = s2n_array_len(s2n_all_cipher_suites) - 1; diff --git a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h index 4467cbb894..08d878575e 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h +++ b/contrib/restricted/aws/s2n/tls/s2n_cipher_suites.h @@ -160,7 +160,7 @@ extern struct s2n_cipher_suite s2n_tls13_chacha20_poly1305_sha256; extern int s2n_cipher_suites_init(void); S2N_RESULT s2n_cipher_suites_cleanup(void); -S2N_RESULT s2n_cipher_suite_from_iana(const uint8_t iana[S2N_TLS_CIPHER_SUITE_LEN], struct s2n_cipher_suite **cipher_suite); +S2N_RESULT s2n_cipher_suite_from_iana(const uint8_t *iana, size_t iana_len, struct s2n_cipher_suite **cipher_suite); extern int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN]); extern int s2n_set_cipher_as_sslv2_server(struct s2n_connection *conn, uint8_t * wire, uint16_t count); extern int s2n_set_cipher_as_tls_server(struct s2n_connection *conn, uint8_t * wire, uint16_t count); diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_finished.c b/contrib/restricted/aws/s2n/tls/s2n_client_finished.c index 348b1602cd..306f9b9ad7 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_client_finished.c +++ b/contrib/restricted/aws/s2n/tls/s2n_client_finished.c @@ -26,11 +26,13 @@ #include "utils/s2n_safety.h" S2N_RESULT s2n_finished_recv(struct s2n_connection *conn, uint8_t *our_version); -S2N_RESULT s2n_finished_send(struct s2n_connection *conn, uint8_t *seq_num, uint8_t *our_version); +S2N_RESULT s2n_finished_send(struct s2n_connection *conn, uint8_t *our_version); int s2n_client_finished_recv(struct s2n_connection *conn) { POSIX_ENSURE_REF(conn); + + POSIX_GUARD(s2n_prf_client_finished(conn)); uint8_t *verify_data = conn->handshake.client_finished; POSIX_GUARD_RESULT(s2n_finished_recv(conn, verify_data)); POSIX_ENSURE(!conn->handshake.rsa_failed, S2N_ERR_BAD_MESSAGE); @@ -41,13 +43,10 @@ int s2n_client_finished_send(struct s2n_connection *conn) { POSIX_ENSURE_REF(conn); - uint8_t *verify_data = conn->handshake.client_finished; - uint8_t *seq_num = conn->secure->client_sequence_number; POSIX_GUARD(s2n_prf_client_finished(conn)); - POSIX_GUARD_RESULT(s2n_finished_send(conn, seq_num, verify_data)); - - POSIX_ENSURE_REF(conn->secure); - conn->client = conn->secure; + uint8_t *verify_data = conn->handshake.client_finished; + POSIX_GUARD_RESULT(s2n_finished_send(conn, verify_data)); + POSIX_GUARD_RESULT(s2n_crypto_parameters_switch(conn)); return S2N_SUCCESS; } diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c index 37f4964f91..16704d1726 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c +++ b/contrib/restricted/aws/s2n/tls/s2n_client_key_exchange.c @@ -226,7 +226,7 @@ int s2n_client_key_recv(struct s2n_connection *conn) POSIX_ENSURE_REF(conn->secure->cipher_suite); const struct s2n_kex *key_exchange = conn->secure->cipher_suite->key_exchange_alg; - DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_blob_zeroize_free); + DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_free_or_wipe); POSIX_GUARD_RESULT(s2n_kex_client_key_recv(key_exchange, conn, &shared_key)); POSIX_GUARD(s2n_calculate_keys(conn, &shared_key)); @@ -325,7 +325,7 @@ int s2n_client_key_send(struct s2n_connection *conn) POSIX_ENSURE_REF(conn->secure->cipher_suite); const struct s2n_kex *key_exchange = conn->secure->cipher_suite->key_exchange_alg; - DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_blob_zeroize_free); + DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_free_or_wipe); POSIX_GUARD_RESULT(s2n_kex_client_key_send(key_exchange, conn, &shared_key)); diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.c b/contrib/restricted/aws/s2n/tls/s2n_config.c index adaa533287..01c15fc8c5 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_config.c +++ b/contrib/restricted/aws/s2n/tls/s2n_config.c @@ -886,7 +886,7 @@ int s2n_config_add_ticket_crypto_key(struct s2n_config *config, if (intro_time_in_seconds_from_epoch == 0) { uint64_t now = 0; - POSIX_GUARD(config->wall_clock(config->sys_clock_ctx, &now)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now)); session_ticket_key->intro_timestamp = now; } else { session_ticket_key->intro_timestamp = (intro_time_in_seconds_from_epoch * ONE_SEC_IN_NANOS); @@ -1031,3 +1031,22 @@ int s2n_config_set_renegotiate_request_cb(struct s2n_config *config, s2n_renegot config->renegotiate_request_ctx = ctx; return S2N_SUCCESS; } + +int s2n_config_set_npn(struct s2n_config *config, bool enable) +{ + POSIX_ENSURE_REF(config); + + config->npn_supported = enable; + + return S2N_SUCCESS; +} + +/* + * Wrapper for wall_clock callback. This wrapper will ensure right return of s2n_errno everytime wall_clock + * callback is called. + */ +S2N_RESULT s2n_config_wall_clock(struct s2n_config *config, uint64_t *output) +{ + RESULT_ENSURE(config->wall_clock(config->sys_clock_ctx, output) >= S2N_SUCCESS, S2N_ERR_CANCELLED); + return S2N_RESULT_OK; +} diff --git a/contrib/restricted/aws/s2n/tls/s2n_config.h b/contrib/restricted/aws/s2n/tls/s2n_config.h index e9659fa2f8..bd7254e325 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_config.h +++ b/contrib/restricted/aws/s2n/tls/s2n_config.h @@ -24,6 +24,7 @@ #include "tls/s2n_x509_validator.h" #include "utils/s2n_blob.h" #include "utils/s2n_set.h" +#include "tls/s2n_crl.h" #define S2N_MAX_TICKET_KEYS 48 #define S2N_MAX_TICKET_KEY_HASHES 500 /* 10KB */ @@ -125,6 +126,9 @@ struct s2n_config { uint8_t (*verify_host)(const char *host_name, size_t host_name_len, void *data); void *data_for_verify_host; + s2n_crl_lookup_callback crl_lookup_cb; + void *crl_lookup_ctx; + /* Application supplied callback to resolve domain name conflicts when loading certs. */ s2n_cert_tiebreak_callback cert_tiebreak_cb; @@ -178,3 +182,4 @@ int s2n_config_free_session_ticket_keys(struct s2n_config *config); void s2n_wipe_static_configs(void); extern struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config); int s2n_config_get_num_default_certs(struct s2n_config *config); +S2N_RESULT s2n_config_wall_clock(struct s2n_config *config, uint64_t *output); diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.h b/contrib/restricted/aws/s2n/tls/s2n_connection.h index 9d7d5bdf68..deacc58d82 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_connection.h +++ b/contrib/restricted/aws/s2n/tls/s2n_connection.h @@ -131,6 +131,10 @@ struct s2n_connection { * has been flushed */ unsigned dynamic_buffers:1; + /* Indicates protocol negotiation will be done through the NPN extension + * instead of the ALPN extension */ + unsigned npn_negotiated:1; + /* The configuration (cert, key .. etc ) */ struct s2n_config *config; diff --git a/contrib/restricted/aws/s2n/tls/s2n_crl.c b/contrib/restricted/aws/s2n/tls/s2n_crl.c index a3c404c353..a2b75fcbdd 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_crl.c +++ b/contrib/restricted/aws/s2n/tls/s2n_crl.c @@ -16,7 +16,8 @@ #include "s2n_crl.h" #include "tls/s2n_connection.h" -struct s2n_crl *s2n_crl_new(void) { +struct s2n_crl *s2n_crl_new(void) +{ DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free); PTR_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_crl))); PTR_GUARD_POSIX(s2n_blob_zero(&mem)); @@ -27,7 +28,8 @@ struct s2n_crl *s2n_crl_new(void) { return crl; } -int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len) { +int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len) +{ POSIX_ENSURE_REF(crl); POSIX_ENSURE(crl->crl == NULL, S2N_ERR_INVALID_ARGUMENT); @@ -51,7 +53,8 @@ int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len) { return S2N_SUCCESS; } -int s2n_crl_free(struct s2n_crl **crl) { +int s2n_crl_free(struct s2n_crl **crl) +{ if (crl == NULL) { return S2N_SUCCESS; } @@ -71,7 +74,8 @@ int s2n_crl_free(struct s2n_crl **crl) { return S2N_SUCCESS; } -int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash) { +int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash) +{ POSIX_ENSURE_REF(crl); POSIX_ENSURE_REF(crl->crl); POSIX_ENSURE_REF(hash); @@ -86,3 +90,187 @@ int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash) { return S2N_SUCCESS; } + +int s2n_crl_validate_active(struct s2n_crl *crl) +{ + POSIX_ENSURE_REF(crl); + POSIX_ENSURE_REF(crl->crl); + + ASN1_TIME *this_update = X509_CRL_get_lastUpdate(crl->crl); + POSIX_ENSURE_REF(this_update); + + int ret = X509_cmp_time(this_update, NULL); + POSIX_ENSURE(ret != 0, S2N_ERR_CRL_INVALID_THIS_UPDATE); + POSIX_ENSURE(ret < 0, S2N_ERR_CRL_NOT_YET_VALID); + + return S2N_SUCCESS; +} + +int s2n_crl_validate_not_expired(struct s2n_crl *crl) +{ + POSIX_ENSURE_REF(crl); + POSIX_ENSURE_REF(crl->crl); + + ASN1_TIME *next_update = X509_CRL_get_nextUpdate(crl->crl); + if (next_update == NULL) { + /* If the CRL has no nextUpdate field, assume it will never expire */ + return S2N_SUCCESS; + } + + int ret = X509_cmp_time(next_update, NULL); + POSIX_ENSURE(ret != 0, S2N_ERR_CRL_INVALID_NEXT_UPDATE); + POSIX_ENSURE(ret > 0, S2N_ERR_CRL_EXPIRED); + + return S2N_SUCCESS; +} + +S2N_RESULT s2n_crl_get_crls_from_lookup_list(struct s2n_x509_validator *validator, STACK_OF(X509_CRL) *crl_stack) +{ + RESULT_ENSURE_REF(validator); + RESULT_ENSURE_REF(validator->crl_lookup_list); + RESULT_ENSURE_REF(crl_stack); + + uint32_t num_lookups = 0; + RESULT_GUARD(s2n_array_num_elements(validator->crl_lookup_list, &num_lookups)); + for (uint32_t i = 0; i < num_lookups; i++) { + struct s2n_crl_lookup *lookup = NULL; + RESULT_GUARD(s2n_array_get(validator->crl_lookup_list, i, (void **) &lookup)); + RESULT_ENSURE_REF(lookup); + + if (lookup->crl == NULL) { + /* A CRL was intentionally not returned from the callback. Don't add anything to the stack*/ + continue; + } + + RESULT_ENSURE_REF(lookup->crl->crl); + if (!sk_X509_CRL_push(crl_stack, lookup->crl->crl)) { + RESULT_BAIL(S2N_ERR_INTERNAL_LIBCRYPTO_ERROR); + } + } + + return S2N_RESULT_OK; +} + +static S2N_RESULT s2n_crl_get_lookup_callback_status(struct s2n_x509_validator *validator, crl_lookup_callback_status *status) +{ + RESULT_ENSURE_REF(validator); + RESULT_ENSURE_REF(validator->crl_lookup_list); + + uint32_t num_lookups = 0; + RESULT_GUARD(s2n_array_num_elements(validator->crl_lookup_list, &num_lookups)); + for (uint32_t i = 0; i < num_lookups; i++) { + struct s2n_crl_lookup *lookup = NULL; + RESULT_GUARD(s2n_array_get(validator->crl_lookup_list, i, (void **) &lookup)); + RESULT_ENSURE_REF(lookup); + + if (lookup->status == AWAITING_RESPONSE) { + *status = AWAITING_RESPONSE; + return S2N_RESULT_OK; + } + } + + *status = FINISHED; + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_crl_handle_lookup_callback_result(struct s2n_x509_validator *validator) +{ + RESULT_ENSURE_REF(validator); + + crl_lookup_callback_status status = 0; + RESULT_GUARD(s2n_crl_get_lookup_callback_status(validator, &status)); + + switch (status) { + case FINISHED: + validator->state = READY_TO_VERIFY; + return S2N_RESULT_OK; + case AWAITING_RESPONSE: + validator->state = AWAITING_CRL_CALLBACK; + RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED); + default: + RESULT_BAIL(S2N_ERR_INVALID_CERT_STATE); + } +} + +S2N_RESULT s2n_crl_invoke_lookup_callbacks(struct s2n_connection *conn, struct s2n_x509_validator *validator) +{ + RESULT_ENSURE_REF(validator); + RESULT_ENSURE_REF(validator->cert_chain_from_wire); + + int cert_count = sk_X509_num(validator->cert_chain_from_wire); + DEFER_CLEANUP(struct s2n_array *crl_lookup_list = s2n_array_new_with_capacity(sizeof(struct s2n_crl_lookup), + cert_count), s2n_array_free_p); + RESULT_ENSURE_REF(crl_lookup_list); + + for (int i = 0; i < cert_count; ++i) { + struct s2n_crl_lookup * lookup = NULL; + RESULT_GUARD(s2n_array_pushback(crl_lookup_list, (void**) &lookup)); + + X509 *cert = sk_X509_value(validator->cert_chain_from_wire, i); + RESULT_ENSURE_REF(cert); + lookup->cert = cert; + lookup->cert_idx = i; + } + + validator->crl_lookup_list = crl_lookup_list; + ZERO_TO_DISABLE_DEFER_CLEANUP(crl_lookup_list); + + /* Invoke the crl lookup callbacks after the crl_lookup_list is stored on the validator. This ensures that if a + * callback fails, the memory for all other callbacks that may still be running remains allocated */ + uint32_t num_lookups = 0; + RESULT_GUARD(s2n_array_num_elements(validator->crl_lookup_list, &num_lookups)); + for (uint32_t i = 0; i < num_lookups; i++) { + struct s2n_crl_lookup *lookup = NULL; + RESULT_GUARD(s2n_array_get(validator->crl_lookup_list, i, (void**) &lookup)); + RESULT_ENSURE_REF(lookup); + + int result = conn->config->crl_lookup_cb(lookup, conn->config->crl_lookup_ctx); + RESULT_ENSURE(result == S2N_SUCCESS, S2N_ERR_CANCELLED); + } + + return S2N_RESULT_OK; +} + +int s2n_crl_ossl_verify_callback(int default_ossl_ret, X509_STORE_CTX *ctx) { + int err = X509_STORE_CTX_get_error(ctx); + switch (err) { + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_CRL_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return 1; + default: + return default_ossl_ret; + } +} + +int s2n_crl_lookup_get_cert_issuer_hash(struct s2n_crl_lookup *lookup, uint64_t *hash) +{ + POSIX_ENSURE_REF(lookup); + POSIX_ENSURE_REF(lookup->cert); + POSIX_ENSURE_REF(hash); + + unsigned long temp_hash = X509_issuer_name_hash(lookup->cert); + POSIX_ENSURE(temp_hash != 0, S2N_ERR_INTERNAL_LIBCRYPTO_ERROR); + + *hash = temp_hash; + + return S2N_SUCCESS; +} + +int s2n_crl_lookup_set(struct s2n_crl_lookup *lookup, struct s2n_crl *crl) +{ + POSIX_ENSURE_REF(lookup); + POSIX_ENSURE_REF(crl); + lookup->crl = crl; + lookup->status = FINISHED; + return S2N_SUCCESS; +} + +int s2n_crl_lookup_ignore(struct s2n_crl_lookup *lookup) +{ + POSIX_ENSURE_REF(lookup); + lookup->crl = NULL; + lookup->status = FINISHED; + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/s2n_crl.h b/contrib/restricted/aws/s2n/tls/s2n_crl.h index db8c967d32..f905f853ba 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_crl.h +++ b/contrib/restricted/aws/s2n/tls/s2n_crl.h @@ -16,16 +16,43 @@ #pragma once #include "api/s2n.h" +#include "utils/s2n_result.h" #include <openssl/x509v3.h> +struct s2n_x509_validator; + struct s2n_crl { X509_CRL *crl; }; +typedef enum { + AWAITING_RESPONSE, + FINISHED +} crl_lookup_callback_status; + +struct s2n_crl_lookup { + crl_lookup_callback_status status; + X509 *cert; + uint16_t cert_idx; + struct s2n_crl *crl; +}; + +typedef int (*s2n_crl_lookup_callback) (struct s2n_crl_lookup *lookup, void *context); + /* TODO: APIs are part of an unfinished CRL validation feature and are temporarily hidden * https://github.com/aws/s2n-tls/issues/3499 */ struct s2n_crl *s2n_crl_new(void); int s2n_crl_load_pem(struct s2n_crl *crl, uint8_t *pem, size_t len); int s2n_crl_free(struct s2n_crl **crl); int s2n_crl_get_issuer_hash(struct s2n_crl *crl, uint64_t *hash); +int s2n_crl_validate_active(struct s2n_crl *crl); +int s2n_crl_validate_not_expired(struct s2n_crl *crl); +int s2n_crl_lookup_get_cert_issuer_hash(struct s2n_crl_lookup *lookup, uint64_t *hash); +int s2n_crl_lookup_set(struct s2n_crl_lookup *lookup, struct s2n_crl *crl); +int s2n_crl_lookup_ignore(struct s2n_crl_lookup *lookup); + +S2N_RESULT s2n_crl_handle_lookup_callback_result(struct s2n_x509_validator *validator); +S2N_RESULT s2n_crl_invoke_lookup_callbacks(struct s2n_connection *conn, struct s2n_x509_validator *validator); +S2N_RESULT s2n_crl_get_crls_from_lookup_list(struct s2n_x509_validator *validator, STACK_OF(X509_CRL) *crl_stack); +int s2n_crl_ossl_verify_callback(int default_ossl_ret, X509_STORE_CTX *ctx); diff --git a/contrib/restricted/aws/s2n/tls/s2n_crypto.c b/contrib/restricted/aws/s2n/tls/s2n_crypto.c index a5fac27a10..79712dded0 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_crypto.c +++ b/contrib/restricted/aws/s2n/tls/s2n_crypto.c @@ -95,3 +95,25 @@ S2N_CLEANUP_RESULT s2n_crypto_parameters_free(struct s2n_crypto_parameters **par RESULT_GUARD_POSIX(s2n_free_object((uint8_t **) params, sizeof(struct s2n_crypto_parameters))); return S2N_RESULT_OK; } + +S2N_RESULT s2n_crypto_parameters_switch(struct s2n_connection *conn) +{ + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(conn->secure); + RESULT_ENSURE_REF(conn->initial); + + /* Only start encryption if we have not already switched to secure parameters */ + if (conn->mode == S2N_CLIENT && conn->client == conn->initial) { + struct s2n_blob seq = { 0 }; + RESULT_GUARD_POSIX(s2n_blob_init(&seq, conn->secure->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN)); + RESULT_GUARD_POSIX(s2n_blob_zero(&seq)); + conn->client = conn->secure; + } else if (conn->mode == S2N_SERVER && conn->server == conn->initial) { + struct s2n_blob seq = { 0 }; + RESULT_GUARD_POSIX(s2n_blob_init(&seq, conn->secure->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN)); + RESULT_GUARD_POSIX(s2n_blob_zero(&seq)); + conn->server = conn->secure; + } + + return S2N_RESULT_OK; +} diff --git a/contrib/restricted/aws/s2n/tls/s2n_crypto.h b/contrib/restricted/aws/s2n/tls/s2n_crypto.h index 37997bb8eb..7c13afe692 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_crypto.h +++ b/contrib/restricted/aws/s2n/tls/s2n_crypto.h @@ -69,3 +69,4 @@ struct s2n_crypto_parameters { S2N_RESULT s2n_crypto_parameters_new(struct s2n_crypto_parameters **params); S2N_RESULT s2n_crypto_parameters_wipe(struct s2n_crypto_parameters *params); S2N_CLEANUP_RESULT s2n_crypto_parameters_free(struct s2n_crypto_parameters **params); +S2N_RESULT s2n_crypto_parameters_switch(struct s2n_connection *conn); diff --git a/contrib/restricted/aws/s2n/tls/s2n_early_data.c b/contrib/restricted/aws/s2n/tls/s2n_early_data.c index 309f108f38..84ba90f9b9 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_early_data.c +++ b/contrib/restricted/aws/s2n/tls/s2n_early_data.c @@ -149,7 +149,8 @@ S2N_RESULT s2n_early_data_accept_or_reject(struct s2n_connection *conn) RESULT_ENSURE_REF(conn->config); if (conn->config->early_data_cb) { conn->handshake.early_data_async_state.conn = conn; - RESULT_GUARD_POSIX(conn->config->early_data_cb(conn, &conn->handshake.early_data_async_state)); + RESULT_ENSURE(conn->config->early_data_cb(conn, &conn->handshake.early_data_async_state) >= S2N_SUCCESS, + S2N_ERR_CANCELLED); if (conn->early_data_state == S2N_EARLY_DATA_REQUESTED) { RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED); } @@ -216,7 +217,7 @@ int s2n_psk_configure_early_data(struct s2n_psk *psk, uint32_t max_early_data_si const uint8_t cipher_suite_iana[] = { cipher_suite_first_byte, cipher_suite_second_byte }; struct s2n_cipher_suite *cipher_suite = NULL; - POSIX_GUARD_RESULT(s2n_cipher_suite_from_iana(cipher_suite_iana, &cipher_suite)); + POSIX_GUARD_RESULT(s2n_cipher_suite_from_iana(cipher_suite_iana, sizeof(cipher_suite_iana), &cipher_suite)); POSIX_ENSURE_REF(cipher_suite); POSIX_ENSURE(cipher_suite->prf_alg == psk->hmac_alg, S2N_ERR_INVALID_ARGUMENT); diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake.h b/contrib/restricted/aws/s2n/tls/s2n_handshake.h index e40a4d8d44..c417bcb2fd 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_handshake.h +++ b/contrib/restricted/aws/s2n/tls/s2n_handshake.h @@ -46,6 +46,7 @@ #define TLS_SERVER_CERT_STATUS 22 #define TLS_SERVER_SESSION_LOOKUP 23 #define TLS_KEY_UPDATE 24 +#define TLS_NPN 67 #define TLS_MESSAGE_HASH 254 /* This is the list of message types that we support */ @@ -62,6 +63,8 @@ typedef enum { CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, + /* Not a standardized message. Defined: https://datatracker.ietf.org/doc/html/draft-agl-tls-nextprotoneg-04 */ + CLIENT_NPN, CLIENT_FINISHED, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c index 7a28eb34b8..3df9b21270 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c +++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_io.c @@ -79,10 +79,11 @@ static struct s2n_handshake_action state_machine[] = { [CLIENT_KEY] = {TLS_HANDSHAKE, TLS_CLIENT_KEY, 'C', {s2n_client_key_recv, s2n_client_key_send}}, [CLIENT_CERT_VERIFY] = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_client_cert_verify_recv, s2n_client_cert_verify_send}}, [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_client_ccs_recv, s2n_ccs_send}}, + [CLIENT_NPN] = {TLS_HANDSHAKE, TLS_NPN, 'C', {s2n_next_protocol_recv, s2n_next_protocol_send}}, [CLIENT_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_client_finished_recv, s2n_client_finished_send}}, [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_server_ccs_recv}}, [SERVER_FINISHED] = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_server_finished_send, s2n_server_finished_recv}}, - [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}} + [APPLICATION_DATA] = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}}, }; /* @@ -134,6 +135,7 @@ static const char *message_names[] = { MESSAGE_NAME_ENTRY(HELLO_RETRY_MSG), MESSAGE_NAME_ENTRY(END_OF_EARLY_DATA), MESSAGE_NAME_ENTRY(APPLICATION_DATA), + MESSAGE_NAME_ENTRY(CLIENT_NPN), }; /* Maximum number of messages in a handshake */ @@ -156,12 +158,25 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED, APPLICATION_DATA}, + [NEGOTIATED | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + APPLICATION_DATA}, + [NEGOTIATED | FULL_HANDSHAKE ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE, @@ -170,6 +185,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE, @@ -178,6 +201,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE, @@ -186,6 +217,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE, @@ -194,6 +233,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS ] ={ CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE, @@ -202,6 +249,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_NPN ] ={ + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE, @@ -210,6 +265,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE, @@ -218,6 +281,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET ] ={ CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE, @@ -226,6 +297,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_SESSION_TICKET | WITH_NPN ] ={ + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE, + CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -234,6 +313,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH| WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -242,6 +329,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -250,6 +345,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -258,6 +361,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -266,6 +377,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -274,6 +393,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -282,6 +409,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -290,6 +425,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -298,6 +441,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -306,6 +457,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -314,6 +473,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -322,6 +489,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -330,6 +505,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -338,6 +521,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -346,6 +537,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] APPLICATION_DATA }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = { CLIENT_HELLO, SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, @@ -353,6 +552,14 @@ static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, APPLICATION_DATA }, + + [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = { + CLIENT_HELLO, + SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE, + CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED, + SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, + APPLICATION_DATA + }, }; /* @@ -597,7 +804,7 @@ static message_type_t tls13_handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_L }; /* clang-format on */ -#define MAX_HANDSHAKE_TYPE_LEN 123 +#define MAX_HANDSHAKE_TYPE_LEN 142 static char handshake_type_str[S2N_HANDSHAKES_COUNT][MAX_HANDSHAKE_TYPE_LEN] = {0}; static const char* tls12_handshake_type_names[] = { @@ -608,6 +815,7 @@ static const char* tls12_handshake_type_names[] = { "TLS12_PERFECT_FORWARD_SECRECY|", "OCSP_STATUS|", "WITH_SESSION_TICKET|", + "WITH_NPN|", }; static const char* tls13_handshake_type_names[] = { @@ -835,6 +1043,10 @@ int s2n_conn_set_handshake_type(struct s2n_connection *conn) POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH)); } + if (conn->npn_negotiated) { + POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_NPN)); + } + if (conn->config->use_tickets) { if (conn->session_ticket_status == S2N_DECRYPT_TICKET) { if (s2n_decrypt_session_ticket(conn, &conn->client_ticket_to_decrypt) == S2N_SUCCESS) { @@ -927,6 +1139,9 @@ const char *s2n_connection_get_handshake_type_name(struct s2n_connection *conn) handshake_type_names_len = s2n_array_len(tls12_handshake_type_names); } + /* Not all handshake strings will be created already. If the handshake string + * is not null, we can just return the handshake. Otherwise we have to compute + * it down below. */ if (handshake_type_str[handshake_type][0] != '\0') { return handshake_type_str[handshake_type]; } diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_type.h b/contrib/restricted/aws/s2n/tls/s2n_handshake_type.h index 2163457eb9..28199f8ef8 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_handshake_type.h +++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_type.h @@ -44,6 +44,9 @@ #define IS_ISSUING_NEW_SESSION_TICKET(conn) \ ( s2n_handshake_type_check_tls12_flag(conn, WITH_SESSION_TICKET) ) +#define IS_NPN_HANDSHAKE(conn) \ + ( s2n_handshake_type_check_tls12_flag(conn, WITH_NPN) ) + #define IS_HELLO_RETRY_HANDSHAKE(conn) \ ( s2n_handshake_type_check_tls13_flag(conn, HELLO_RETRY_REQUEST) ) @@ -71,6 +74,7 @@ typedef enum { TLS12_PERFECT_FORWARD_SECRECY = 16, OCSP_STATUS = 32, WITH_SESSION_TICKET = 64, + WITH_NPN = 128, } s2n_tls12_handshake_type_flag; S2N_RESULT s2n_handshake_type_set_tls12_flag(struct s2n_connection *conn, s2n_tls12_handshake_type_flag flag); diff --git a/contrib/restricted/aws/s2n/tls/s2n_kem.c b/contrib/restricted/aws/s2n/tls/s2n_kem.c index f86b0acbd8..82394f8f03 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_kem.c +++ b/contrib/restricted/aws/s2n/tls/s2n_kem.c @@ -225,9 +225,9 @@ int s2n_choose_kem_without_peer_pref_list(const uint8_t iana_value[S2N_TLS_CIPHE int s2n_kem_free(struct s2n_kem_params *kem_params) { if (kem_params != NULL) { - POSIX_GUARD(s2n_blob_zeroize_free(&kem_params->private_key)); - POSIX_GUARD(s2n_blob_zeroize_free(&kem_params->public_key)); - POSIX_GUARD(s2n_blob_zeroize_free(&kem_params->shared_secret)); + POSIX_GUARD(s2n_free_or_wipe(&kem_params->private_key)); + POSIX_GUARD(s2n_free_or_wipe(&kem_params->public_key)); + POSIX_GUARD(s2n_free_or_wipe(&kem_params->shared_secret)); } return S2N_SUCCESS; } diff --git a/contrib/restricted/aws/s2n/tls/s2n_next_protocol.c b/contrib/restricted/aws/s2n/tls/s2n_next_protocol.c new file mode 100644 index 0000000000..bfe3ee4043 --- /dev/null +++ b/contrib/restricted/aws/s2n/tls/s2n_next_protocol.c @@ -0,0 +1,101 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "error/s2n_errno.h" +#include "utils/s2n_safety.h" +#include "stuffer/s2n_stuffer.h" +#include "tls/s2n_tls.h" + +S2N_RESULT s2n_calculate_padding(uint8_t protocol_len, uint8_t *padding_len) +{ + RESULT_ENSURE_REF(padding_len); + + /* + *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-03#section-3 + *# The length of "padding" SHOULD be 32 - ((len(selected_protocol) + 2) % 32). + */ + *padding_len = 32 - (((uint16_t)protocol_len + 2) % 32); + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_write_npn_protocol(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + RESULT_ENSURE_REF(conn); + + uint8_t protocol_len = strlen(conn->application_protocol); + RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, protocol_len)); + RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, (uint8_t*) conn->application_protocol, protocol_len)); + + uint8_t padding_len = 0; + RESULT_GUARD(s2n_calculate_padding(protocol_len, &padding_len)); + RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, padding_len)); + uint8_t *data_ptr = s2n_stuffer_raw_write(out, padding_len); + RESULT_ENSURE_REF(data_ptr); + RESULT_CHECKED_MEMSET(data_ptr, 0, padding_len); + + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_read_npn_protocol(struct s2n_connection *conn, struct s2n_stuffer *in) +{ + RESULT_ENSURE_REF(conn); + + uint8_t protocol_len = 0; + RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &protocol_len)); + + uint8_t *protocol = s2n_stuffer_raw_read(in, protocol_len); + RESULT_ENSURE_REF(protocol); + RESULT_CHECKED_MEMCPY(conn->application_protocol, protocol, protocol_len); + conn->application_protocol[protocol_len] = '\0'; + + uint8_t expected_padding_len = 0; + RESULT_GUARD(s2n_calculate_padding(protocol_len, &expected_padding_len)); + uint8_t padding_len = 0; + RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &padding_len)); + RESULT_ENSURE_EQ(padding_len, expected_padding_len); + + uint8_t *data_ptr = s2n_stuffer_raw_read(in, padding_len); + RESULT_ENSURE_REF(data_ptr); + uint8_t empty_array[UINT8_MAX] = { 0 }; + RESULT_ENSURE_EQ(s2n_constant_time_equals(data_ptr, empty_array, padding_len), 1); + + RESULT_ENSURE_EQ(s2n_stuffer_data_available(in), 0); + + return S2N_RESULT_OK; +} + +int s2n_next_protocol_send(struct s2n_connection *conn) +{ + POSIX_ENSURE_REF(conn); + POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE); + + struct s2n_stuffer *out = &conn->handshake.io; + POSIX_GUARD_RESULT(s2n_write_npn_protocol(conn, out)); + + POSIX_GUARD_RESULT(s2n_crypto_parameters_switch(conn)); + + return S2N_SUCCESS; +} + +int s2n_next_protocol_recv(struct s2n_connection *conn) +{ + POSIX_ENSURE_REF(conn); + POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE); + + struct s2n_stuffer *in = &conn->handshake.io; + POSIX_GUARD_RESULT(s2n_read_npn_protocol(conn, in)); + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/s2n_prf.c b/contrib/restricted/aws/s2n/tls/s2n_prf.c index 2ff9f0c6de..df33d330cf 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_prf.c +++ b/contrib/restricted/aws/s2n/tls/s2n_prf.c @@ -500,6 +500,8 @@ static int s2n_prf(struct s2n_connection *conn, struct s2n_blob *secret, struct int s2n_tls_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret) { + POSIX_ENSURE_REF(conn); + struct s2n_blob client_random = {.size = sizeof(conn->handshake_params.client_random), .data = conn->handshake_params.client_random}; struct s2n_blob server_random = {.size = sizeof(conn->handshake_params.server_random), .data = conn->handshake_params.server_random}; struct s2n_blob master_secret = {.size = sizeof(conn->secrets.tls12.master_secret), .data = conn->secrets.tls12.master_secret}; @@ -512,6 +514,8 @@ int s2n_tls_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *prem int s2n_hybrid_prf_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret) { + POSIX_ENSURE_REF(conn); + struct s2n_blob client_random = {.size = sizeof(conn->handshake_params.client_random), .data = conn->handshake_params.client_random}; struct s2n_blob server_random = {.size = sizeof(conn->handshake_params.server_random), .data = conn->handshake_params.server_random}; struct s2n_blob master_secret = {.size = sizeof(conn->secrets.tls12.master_secret), .data = conn->secrets.tls12.master_secret}; @@ -575,6 +579,8 @@ int s2n_prf_calculate_master_secret(struct s2n_connection *conn, struct s2n_blob */ S2N_RESULT s2n_tls_prf_extended_master_secret(struct s2n_connection *conn, struct s2n_blob *premaster_secret, struct s2n_blob *session_hash, struct s2n_blob *sha1_hash) { + RESULT_ENSURE_REF(conn); + struct s2n_blob extended_master_secret = {.size = sizeof(conn->secrets.tls12.master_secret), .data = conn->secrets.tls12.master_secret}; uint8_t extended_master_secret_label[] = "extended master secret"; @@ -590,6 +596,7 @@ S2N_RESULT s2n_prf_get_digest_for_ems(struct s2n_connection *conn, struct s2n_bl { RESULT_ENSURE_REF(conn); RESULT_ENSURE_REF(conn->handshake.hashes); + RESULT_ENSURE_REF(message); RESULT_ENSURE_REF(output); struct s2n_hash_state *hash_state = &conn->handshake.hashes->hash_workspace; diff --git a/contrib/restricted/aws/s2n/tls/s2n_psk.c b/contrib/restricted/aws/s2n/tls/s2n_psk.c index b33071dca5..7a1c4a295d 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_psk.c +++ b/contrib/restricted/aws/s2n/tls/s2n_psk.c @@ -696,7 +696,7 @@ S2N_RESULT s2n_psk_validate_keying_material(struct s2n_connection *conn) uint32_t min_lifetime = ONE_SEC_IN_NANOS; uint64_t current_time = 0; - RESULT_GUARD_POSIX(conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_time)); + RESULT_GUARD(s2n_config_wall_clock(conn->config, ¤t_time)); RESULT_ENSURE(chosen_psk->keying_material_expiration > current_time + min_lifetime, S2N_ERR_KEYING_MATERIAL_EXPIRED); return S2N_RESULT_OK; diff --git a/contrib/restricted/aws/s2n/tls/s2n_resume.c b/contrib/restricted/aws/s2n/tls/s2n_resume.c index 3d79e28dce..356bd772e6 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_resume.c +++ b/contrib/restricted/aws/s2n/tls/s2n_resume.c @@ -55,7 +55,7 @@ static int s2n_tls12_serialize_resumption_state(struct s2n_connection *conn, str S2N_ERROR_IF(s2n_stuffer_space_remaining(to) < S2N_TLS12_STATE_SIZE_IN_BYTES, S2N_ERR_STUFFER_IS_FULL); /* Get the time */ - POSIX_GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now)); /* Write the entry */ POSIX_GUARD(s2n_stuffer_write_uint8(to, S2N_SERIALIZED_FORMAT_TLS12_V3)); @@ -99,7 +99,7 @@ static S2N_RESULT s2n_tls13_serialize_resumption_state(struct s2n_connection *co struct s2n_ticket_fields *ticket_fields = &conn->tls13_ticket_fields; /* Get the time */ - RESULT_GUARD_POSIX(conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_time)); + RESULT_GUARD(s2n_config_wall_clock(conn->config, ¤t_time)); RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, S2N_SERIALIZED_FORMAT_TLS13_V1)); RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, conn->actual_protocol_version)); @@ -152,7 +152,7 @@ static int s2n_tls12_deserialize_resumption_state(struct s2n_connection *conn, s S2N_ERROR_IF(memcmp(conn->secure->cipher_suite->iana_value, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN), S2N_ERR_INVALID_SERIALIZED_SESSION_STATE); uint64_t now; - POSIX_GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now)); uint64_t then; POSIX_GUARD(s2n_stuffer_read_uint64(from, &then)); @@ -262,7 +262,7 @@ static S2N_RESULT s2n_tls13_deserialize_session_state(struct s2n_connection *con uint8_t iana_id[S2N_TLS_CIPHER_SUITE_LEN] = { 0 }; RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(from, iana_id, S2N_TLS_CIPHER_SUITE_LEN)); struct s2n_cipher_suite *cipher_suite = NULL; - RESULT_GUARD(s2n_cipher_suite_from_iana(iana_id, &cipher_suite)); + RESULT_GUARD(s2n_cipher_suite_from_iana(iana_id, sizeof(iana_id), &cipher_suite)); RESULT_ENSURE_REF(cipher_suite); psk.hmac_alg = cipher_suite->prf_alg; @@ -275,7 +275,7 @@ static S2N_RESULT s2n_tls13_deserialize_session_state(struct s2n_connection *con *# and MAY delete tickets earlier based on local policy. */ uint64_t current_time = 0; - RESULT_GUARD_POSIX(conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_time)); + RESULT_GUARD(s2n_config_wall_clock(conn->config, ¤t_time)); RESULT_GUARD(s2n_validate_ticket_age(current_time, psk.ticket_issue_time)); RESULT_GUARD_POSIX(s2n_stuffer_read_uint32(from, &psk.ticket_age_add)); @@ -417,7 +417,7 @@ int s2n_resume_from_cache(struct s2n_connection *conn) if (result == S2N_CALLBACK_BLOCKED) { POSIX_BAIL(S2N_ERR_ASYNC_BLOCKED); } - POSIX_GUARD(result); + POSIX_ENSURE(result >= S2N_SUCCESS, S2N_ERR_CANCELLED); S2N_ERROR_IF(size != entry.size, S2N_ERR_SIZE_MISMATCH); @@ -575,7 +575,7 @@ int s2n_config_is_encrypt_decrypt_key_available(struct s2n_config *config) { uint64_t now; struct s2n_ticket_key *ticket_key = NULL; - POSIX_GUARD(config->wall_clock(config->sys_clock_ctx, &now)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now)); POSIX_ENSURE_REF(config->ticket_keys); uint32_t ticket_keys_len = 0; @@ -658,7 +658,7 @@ struct s2n_ticket_key *s2n_get_ticket_encrypt_decrypt_key(struct s2n_config *con struct s2n_ticket_key *ticket_key = NULL; uint64_t now; - PTR_GUARD_POSIX(config->wall_clock(config->sys_clock_ctx, &now)); + PTR_GUARD_RESULT(s2n_config_wall_clock(config, &now)); PTR_ENSURE_REF(config->ticket_keys); uint32_t ticket_keys_len = 0; @@ -699,7 +699,7 @@ struct s2n_ticket_key *s2n_find_ticket_key(struct s2n_config *config, const uint { uint64_t now; struct s2n_ticket_key *ticket_key = NULL; - PTR_GUARD_POSIX(config->wall_clock(config->sys_clock_ctx, &now)); + PTR_GUARD_RESULT(s2n_config_wall_clock(config, &now)); PTR_ENSURE_REF(config->ticket_keys); uint32_t ticket_keys_len = 0; @@ -830,7 +830,7 @@ int s2n_decrypt_session_ticket(struct s2n_connection *conn, struct s2n_stuffer * POSIX_GUARD_RESULT(s2n_deserialize_resumption_state(conn, &from->blob, &state_stuffer)); uint64_t now; - POSIX_GUARD(conn->config->wall_clock(conn->config->sys_clock_ctx, &now)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(conn->config, &now)); /* If the key is in decrypt-only state, then a new key is assigned * for the ticket. @@ -924,7 +924,7 @@ int s2n_config_wipe_expired_ticket_crypto_keys(struct s2n_config *config, int8_t } uint64_t now; - POSIX_GUARD(config->wall_clock(config->sys_clock_ctx, &now)); + POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now)); POSIX_ENSURE_REF(config->ticket_keys); uint32_t ticket_keys_len = 0; diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_finished.c b/contrib/restricted/aws/s2n/tls/s2n_server_finished.c index 02d73ac4aa..3c105657ed 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_server_finished.c +++ b/contrib/restricted/aws/s2n/tls/s2n_server_finished.c @@ -45,14 +45,10 @@ S2N_RESULT s2n_finished_recv(struct s2n_connection *conn, uint8_t *local_verify_ return S2N_RESULT_OK; } -S2N_RESULT s2n_finished_send(struct s2n_connection *conn, uint8_t *seq_num, uint8_t *verify_data) +S2N_RESULT s2n_finished_send(struct s2n_connection *conn, uint8_t *verify_data) { RESULT_ENSURE_REF(conn); - struct s2n_blob seq = { 0 }; - RESULT_GUARD_POSIX(s2n_blob_init(&seq, seq_num, S2N_TLS_SEQUENCE_NUM_LEN)); - RESULT_GUARD_POSIX(s2n_blob_zero(&seq)); - uint8_t length = conn->handshake.finished_len; RESULT_ENSURE_GT(length, 0); @@ -73,12 +69,9 @@ int s2n_server_finished_send(struct s2n_connection *conn) POSIX_ENSURE_REF(conn); uint8_t *verify_data = conn->handshake.server_finished; - uint8_t *seq_num = conn->secure->server_sequence_number; POSIX_GUARD(s2n_prf_server_finished(conn)); - POSIX_GUARD_RESULT(s2n_finished_send(conn, seq_num, verify_data)); - - POSIX_ENSURE_REF(conn->secure); - conn->server = conn->secure; + POSIX_GUARD_RESULT(s2n_finished_send(conn, verify_data)); + POSIX_GUARD_RESULT(s2n_crypto_parameters_switch(conn)); if (s2n_connection_is_session_resumed(conn)) { POSIX_GUARD(s2n_prf_key_expansion(conn)); diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c b/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c index 08b5371d24..74392aa969 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c +++ b/contrib/restricted/aws/s2n/tls/s2n_server_new_session_ticket.c @@ -67,7 +67,8 @@ int s2n_server_nst_recv(struct s2n_connection *conn) { struct s2n_session_ticket ticket = { .ticket_data = mem, .session_lifetime = session_lifetime }; - POSIX_GUARD(conn->config->session_ticket_cb(conn, conn->config->session_ticket_ctx, &ticket)); + POSIX_ENSURE(conn->config->session_ticket_cb(conn, conn->config->session_ticket_ctx, &ticket) >= S2N_SUCCESS, + S2N_ERR_CANCELLED); } } @@ -407,7 +408,8 @@ S2N_RESULT s2n_tls13_server_nst_recv(struct s2n_connection *conn, struct s2n_stu .ticket_data = session_state, .session_lifetime = ticket_lifetime }; - RESULT_GUARD_POSIX(conn->config->session_ticket_cb(conn, conn->config->session_ticket_ctx, &ticket)); + RESULT_ENSURE(conn->config->session_ticket_cb(conn, conn->config->session_ticket_ctx, &ticket) >= S2N_SUCCESS, + S2N_ERR_CANCELLED); } return S2N_RESULT_OK; diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls.h b/contrib/restricted/aws/s2n/tls/s2n_tls.h index a4bffb18bf..03a5737770 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_tls.h +++ b/contrib/restricted/aws/s2n/tls/s2n_tls.h @@ -37,8 +37,8 @@ extern int s2n_server_hello_send(struct s2n_connection *conn); extern int s2n_server_hello_recv(struct s2n_connection *conn); extern int s2n_encrypted_extensions_send(struct s2n_connection *conn); extern int s2n_encrypted_extensions_recv(struct s2n_connection *conn); -extern int s2n_tls12_encrypted_extensions_send(struct s2n_connection *conn); -extern int s2n_tls12_encrypted_extensions_recv(struct s2n_connection *conn); +extern int s2n_next_protocol_send(struct s2n_connection *conn); +extern int s2n_next_protocol_recv(struct s2n_connection *conn); extern int s2n_server_cert_send(struct s2n_connection *conn); extern int s2n_server_cert_recv(struct s2n_connection *conn); extern int s2n_server_status_send(struct s2n_connection *conn); diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c b/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c deleted file mode 100644 index b248ac5d3b..0000000000 --- a/contrib/restricted/aws/s2n/tls/s2n_tls12_encrypted_extensions.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -#include "error/s2n_errno.h" -#include "utils/s2n_safety.h" -#include "stuffer/s2n_stuffer.h" - -#include "tls/s2n_tls.h" -#include "tls/extensions/s2n_extension_list.h" - -int s2n_tls12_encrypted_extensions_send(struct s2n_connection *conn) -{ - POSIX_ENSURE_REF(conn); - POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE); - - struct s2n_stuffer *out = &conn->handshake.io; - POSIX_GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12, conn, out)); - return S2N_SUCCESS; -} - -int s2n_tls12_encrypted_extensions_recv(struct s2n_connection *conn) -{ - POSIX_ENSURE_REF(conn); - POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE); - - struct s2n_stuffer *in = &conn->handshake.io; - POSIX_GUARD(s2n_extension_list_recv(S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS_TLS12, conn, in)); - return S2N_SUCCESS; -} diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c index 91729d3a1e..f6fc69cfdc 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c +++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_handshake.c @@ -94,7 +94,7 @@ int s2n_tls13_compute_pq_hybrid_shared_secret(struct s2n_connection *conn, struc struct s2n_ecc_evp_params *client_ecc_params = &client_kem_group_params->ecc_params; POSIX_ENSURE_REF(client_ecc_params); - DEFER_CLEANUP(struct s2n_blob ecdhe_shared_secret = { 0 }, s2n_blob_zeroize_free); + DEFER_CLEANUP(struct s2n_blob ecdhe_shared_secret = { 0 }, s2n_free_or_wipe); /* Compute the ECDHE shared secret, and retrieve the PQ shared secret. */ if (conn->mode == S2N_CLIENT) { diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c index dbf7608ffe..3b2cd361b3 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c +++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_key_schedule.c @@ -149,6 +149,8 @@ static S2N_RESULT s2n_set_key(struct s2n_connection *conn, s2n_extract_secret_ty static S2N_RESULT s2n_client_key_schedule(struct s2n_connection *conn) { + RESULT_ENSURE_REF(conn); + message_type_t message_type = s2n_conn_get_current_message_type(conn); /** @@ -224,6 +226,8 @@ static S2N_RESULT s2n_client_key_schedule(struct s2n_connection *conn) static S2N_RESULT s2n_server_key_schedule(struct s2n_connection *conn) { + RESULT_ENSURE_REF(conn); + message_type_t message_type = s2n_conn_get_current_message_type(conn); /** diff --git a/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c b/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c index 95f398d566..d24e8b6344 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c +++ b/contrib/restricted/aws/s2n/tls/s2n_tls13_secrets.c @@ -103,12 +103,10 @@ S2N_RESULT s2n_tls13_empty_transcripts_init() static S2N_RESULT s2n_calculate_transcript_digest(struct s2n_connection *conn) { RESULT_ENSURE_REF(conn); - RESULT_ENSURE_REF(conn->secure); - RESULT_ENSURE_REF(conn->secure->cipher_suite); RESULT_ENSURE_REF(conn->handshake.hashes); s2n_hash_algorithm hash_algorithm = S2N_HASH_NONE; - RESULT_GUARD_POSIX(s2n_hmac_hash_alg(conn->secure->cipher_suite->prf_alg, &hash_algorithm)); + RESULT_GUARD_POSIX(s2n_hmac_hash_alg(CONN_HMAC_ALG(conn), &hash_algorithm)); uint8_t digest_size = 0; RESULT_GUARD_POSIX(s2n_hash_digest_size(hash_algorithm, &digest_size)); @@ -168,6 +166,10 @@ static S2N_RESULT s2n_derive_secret_with_context(struct s2n_connection *conn, s2n_extract_secret_type_t input_secret_type, const struct s2n_blob *label, message_type_t transcript_end_msg, struct s2n_blob *output) { + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(label); + RESULT_ENSURE_REF(output); + RESULT_ENSURE(CONN_SECRETS(conn).extract_secret_type == input_secret_type, S2N_ERR_SECRET_SCHEDULE_STATE); RESULT_ENSURE(s2n_conn_get_current_message_type(conn) == transcript_end_msg, S2N_ERR_SECRET_SCHEDULE_STATE); RESULT_GUARD(s2n_derive_secret(CONN_HMAC_ALG(conn), &CONN_SECRET(conn, extract_secret), @@ -178,6 +180,9 @@ static S2N_RESULT s2n_derive_secret_with_context(struct s2n_connection *conn, static S2N_RESULT s2n_derive_secret_without_context(struct s2n_connection *conn, s2n_extract_secret_type_t input_secret_type, struct s2n_blob *output) { + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(output); + RESULT_ENSURE(CONN_SECRETS(conn).extract_secret_type == input_secret_type, S2N_ERR_SECRET_SCHEDULE_STATE); RESULT_GUARD(s2n_derive_secret(CONN_HMAC_ALG(conn), &CONN_SECRET(conn, extract_secret), &s2n_tls13_label_derived_secret, &EMPTY_CONTEXT(CONN_HMAC_ALG(conn)), output)); @@ -196,6 +201,10 @@ static S2N_RESULT s2n_derive_secret_without_context(struct s2n_connection *conn, static S2N_RESULT s2n_tls13_compute_finished_key(struct s2n_connection *conn, const struct s2n_blob *base_key, struct s2n_blob *output) { + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(base_key); + RESULT_ENSURE_REF(output); + RESULT_GUARD(s2n_handshake_set_finished_len(conn, output->size)); /* @@ -213,6 +222,9 @@ static S2N_RESULT s2n_tls13_compute_finished_key(struct s2n_connection *conn, static S2N_RESULT s2n_trigger_secret_callbacks(struct s2n_connection *conn, const struct s2n_blob *secret, s2n_extract_secret_type_t secret_type, s2n_mode mode) { + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(secret); + static const s2n_secret_type_t conversions[][2] = { [S2N_EARLY_SECRET] = { S2N_CLIENT_EARLY_TRAFFIC_SECRET, S2N_CLIENT_EARLY_TRAFFIC_SECRET }, [S2N_HANDSHAKE_SECRET] = { S2N_SERVER_HANDSHAKE_TRAFFIC_SECRET, S2N_CLIENT_HANDSHAKE_TRAFFIC_SECRET }, @@ -258,6 +270,8 @@ S2N_RESULT s2n_extract_early_secret(struct s2n_psk *psk) */ static S2N_RESULT s2n_extract_early_secret_for_schedule(struct s2n_connection *conn) { + RESULT_ENSURE_REF(conn); + struct s2n_psk *psk = conn->psk_params.chosen_psk; s2n_hmac_algorithm hmac_alg = CONN_HMAC_ALG(conn); @@ -301,6 +315,9 @@ static S2N_RESULT s2n_extract_early_secret_for_schedule(struct s2n_connection *c */ S2N_RESULT s2n_derive_binder_key(struct s2n_psk *psk, struct s2n_blob *output) { + RESULT_ENSURE_REF(psk); + RESULT_ENSURE_REF(output); + const struct s2n_blob *label = &s2n_tls13_label_resumption_psk_binder_key; if (psk->type == S2N_PSK_TYPE_EXTERNAL) { label = &s2n_tls13_label_external_psk_binder_key; @@ -341,12 +358,14 @@ static S2N_RESULT s2n_derive_client_early_traffic_secret(struct s2n_connection * */ static S2N_RESULT s2n_extract_handshake_secret(struct s2n_connection *conn) { + RESULT_ENSURE_REF(conn); + struct s2n_blob derived_secret = { 0 }; uint8_t derived_secret_bytes[S2N_TLS13_SECRET_MAX_LEN] = { 0 }; RESULT_GUARD_POSIX(s2n_blob_init(&derived_secret, derived_secret_bytes, S2N_TLS13_SECRET_MAX_LEN)); RESULT_GUARD(s2n_derive_secret_without_context(conn, S2N_EARLY_SECRET, &derived_secret)); - DEFER_CLEANUP(struct s2n_blob shared_secret = { 0 }, s2n_blob_zeroize_free); + DEFER_CLEANUP(struct s2n_blob shared_secret = { 0 }, s2n_free_or_wipe); RESULT_GUARD_POSIX(s2n_tls13_compute_shared_secret(conn, &shared_secret)); RESULT_GUARD(s2n_extract_secret(CONN_HMAC_ALG(conn), @@ -366,6 +385,9 @@ static S2N_RESULT s2n_extract_handshake_secret(struct s2n_connection *conn) */ static S2N_RESULT s2n_derive_client_handshake_traffic_secret(struct s2n_connection *conn, struct s2n_blob *output) { + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(output); + RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_HANDSHAKE_SECRET, &s2n_tls13_label_client_handshake_traffic_secret, @@ -395,6 +417,9 @@ static S2N_RESULT s2n_derive_client_handshake_traffic_secret(struct s2n_connecti */ static S2N_RESULT s2n_derive_server_handshake_traffic_secret(struct s2n_connection *conn, struct s2n_blob *output) { + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(output); + RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_HANDSHAKE_SECRET, &s2n_tls13_label_server_handshake_traffic_secret, @@ -425,6 +450,8 @@ static S2N_RESULT s2n_derive_server_handshake_traffic_secret(struct s2n_connecti */ static S2N_RESULT s2n_extract_master_secret(struct s2n_connection *conn) { + RESULT_ENSURE_REF(conn); + struct s2n_blob derived_secret = { 0 }; uint8_t derived_secret_bytes[S2N_TLS13_SECRET_MAX_LEN] = { 0 }; RESULT_GUARD_POSIX(s2n_blob_init(&derived_secret, derived_secret_bytes, S2N_TLS13_SECRET_MAX_LEN)); @@ -480,6 +507,11 @@ static S2N_RESULT s2n_derive_server_application_traffic_secret(struct s2n_connec */ S2N_RESULT s2n_derive_resumption_master_secret(struct s2n_connection *conn) { + RESULT_ENSURE_REF(conn); + /* Secret derivation requires these fields to be non-null. */ + RESULT_ENSURE_REF(conn->secure); + RESULT_ENSURE_REF(conn->secure->cipher_suite); + RESULT_GUARD(s2n_derive_secret_with_context(conn, S2N_MASTER_SECRET, &s2n_tls13_label_resumption_master_secret, @@ -545,6 +577,10 @@ S2N_RESULT s2n_tls13_derive_secret(struct s2n_connection *conn, s2n_extract_secr S2N_RESULT s2n_tls13_secrets_clean(struct s2n_connection *conn) { RESULT_ENSURE_REF(conn); + /* Secret clean requires these fields to be non-null. */ + RESULT_ENSURE_REF(conn->secure); + RESULT_ENSURE_REF(conn->secure->cipher_suite); + if (conn->actual_protocol_version < S2N_TLS13) { return S2N_RESULT_OK; } @@ -572,6 +608,8 @@ S2N_RESULT s2n_tls13_secrets_update(struct s2n_connection *conn) if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { return S2N_RESULT_OK; } + + /* Secret update requires these fields to be non-null. */ RESULT_ENSURE_REF(conn->secure); RESULT_ENSURE_REF(conn->secure->cipher_suite); @@ -614,6 +652,9 @@ S2N_RESULT s2n_tls13_secrets_get(struct s2n_connection *conn, s2n_extract_secret { RESULT_ENSURE_REF(conn); RESULT_ENSURE_REF(secret); + /* Getting secrets requires these fields to be non-null. */ + RESULT_ENSURE_REF(conn->secure); + RESULT_ENSURE_REF(conn->secure->cipher_suite); uint8_t *secrets[][2] = { [S2N_EARLY_SECRET] = { NULL, CONN_SECRETS(conn).client_early_secret }, diff --git a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c index ca6dd8aede..696e7ed463 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c +++ b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.c @@ -22,6 +22,7 @@ #include "tls/extensions/s2n_extension_list.h" #include "tls/s2n_config.h" #include "tls/s2n_connection.h" +#include "tls/s2n_crl.h" #include <arpa/inet.h> #include <sys/socket.h> @@ -44,6 +45,8 @@ DEFINE_POINTER_CLEANUP_FUNC(OCSP_BASICRESP*, OCSP_BASICRESP_free); /* Time used by default for nextUpdate if none provided in OCSP: 1 hour since thisUpdate. */ #define DEFAULT_OCSP_NEXT_UPDATE_PERIOD 3600000000000 +DEFINE_POINTER_CLEANUP_FUNC(STACK_OF(X509_CRL)*, sk_X509_CRL_free); + uint8_t s2n_x509_ocsp_stapling_supported(void) { return S2N_OCSP_STAPLING_SUPPORTED; } @@ -147,6 +150,7 @@ int s2n_x509_validator_init_no_x509_validation(struct s2n_x509_validator *valida validator->max_chain_depth = DEFAULT_MAX_CHAIN_DEPTH; validator->state = INIT; validator->cert_chain_from_wire = sk_X509_new_null(); + validator->crl_lookup_list = NULL; return 0; } @@ -164,6 +168,7 @@ int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x50 } validator->cert_chain_from_wire = sk_X509_new_null(); validator->state = INIT; + validator->crl_lookup_list = NULL; return 0; } @@ -174,7 +179,7 @@ static inline void wipe_cert_chain(STACK_OF(X509) *cert_chain) { } } -void s2n_x509_validator_wipe(struct s2n_x509_validator *validator) { +int s2n_x509_validator_wipe(struct s2n_x509_validator *validator) { if (validator->store_ctx) { X509_STORE_CTX_free(validator->store_ctx); validator->store_ctx = NULL; @@ -185,6 +190,12 @@ void s2n_x509_validator_wipe(struct s2n_x509_validator *validator) { validator->skip_cert_validation = 0; validator->state = UNINIT; validator->max_chain_depth = 0; + if (validator->crl_lookup_list) { + POSIX_GUARD_RESULT(s2n_array_free(validator->crl_lookup_list)); + validator->crl_lookup_list = NULL; + } + + return S2N_SUCCESS; } int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth) { @@ -370,6 +381,11 @@ static S2N_RESULT s2n_x509_validator_process_cert_chain(struct s2n_x509_validato RESULT_GUARD_OSSL(X509_STORE_CTX_init(validator->store_ctx, validator->trust_store->trust_store, leaf, validator->cert_chain_from_wire), S2N_ERR_INTERNAL_LIBCRYPTO_ERROR); + if (conn->config->crl_lookup_cb) { + RESULT_GUARD(s2n_crl_invoke_lookup_callbacks(conn, validator)); + RESULT_GUARD(s2n_crl_handle_lookup_callback_result(validator)); + } + validator->state = READY_TO_VERIFY; return S2N_RESULT_OK; @@ -381,8 +397,28 @@ static S2N_RESULT s2n_x509_validator_verify_cert_chain(struct s2n_x509_validator X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(validator->store_ctx); X509_VERIFY_PARAM_set_depth(param, validator->max_chain_depth); + DEFER_CLEANUP(STACK_OF(X509_CRL) *crl_stack = NULL, sk_X509_CRL_free_pointer); + + if (conn->config->crl_lookup_cb) { + X509_STORE_CTX_set_verify_cb(validator->store_ctx, s2n_crl_ossl_verify_callback); + + crl_stack = sk_X509_CRL_new_null(); + RESULT_GUARD(s2n_crl_get_crls_from_lookup_list(validator, crl_stack)); + + /* Set the CRL list that the libcrypto will use to validate certificates with */ + X509_STORE_CTX_set0_crls(validator->store_ctx, crl_stack); + + /* Enable CRL validation for certificates in X509_verify_cert */ + RESULT_GUARD_OSSL(X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK), + S2N_ERR_INTERNAL_LIBCRYPTO_ERROR); + + /* Enable CRL validation for all certificates, not just the leaf */ + RESULT_GUARD_OSSL(X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK_ALL), + S2N_ERR_INTERNAL_LIBCRYPTO_ERROR); + } + uint64_t current_sys_time = 0; - conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_sys_time); + RESULT_GUARD(s2n_config_wall_clock(conn->config, ¤t_sys_time)); /* this wants seconds not nanoseconds */ time_t current_time = (time_t)(current_sys_time / 1000000000); @@ -394,6 +430,17 @@ static S2N_RESULT s2n_x509_validator_verify_cert_chain(struct s2n_x509_validator switch (ossl_error) { case X509_V_ERR_CERT_HAS_EXPIRED: RESULT_BAIL(S2N_ERR_CERT_EXPIRED); + case X509_V_ERR_CERT_REVOKED: + RESULT_BAIL(S2N_ERR_CERT_REVOKED); + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + RESULT_BAIL(S2N_ERR_CRL_LOOKUP_FAILED); + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + RESULT_BAIL(S2N_ERR_CRL_SIGNATURE); + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + RESULT_BAIL(S2N_ERR_CRL_ISSUER); + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + RESULT_BAIL(S2N_ERR_CRL_UNHANDLED_CRITICAL_EXTENSION); default: RESULT_BAIL(S2N_ERR_CERT_UNTRUSTED); } @@ -431,7 +478,15 @@ static S2N_RESULT s2n_x509_validator_read_leaf_info(struct s2n_connection *conn, S2N_RESULT s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn, uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_pkey_type *pkey_type, struct s2n_pkey *public_key_out) { - RESULT_ENSURE(validator->state == INIT, S2N_ERR_INVALID_CERT_STATE); + switch (validator->state) { + case INIT: + break; + case AWAITING_CRL_CALLBACK: + RESULT_GUARD(s2n_crl_handle_lookup_callback_result(validator)); + break; + default: + RESULT_BAIL(S2N_ERR_INVALID_CERT_STATE); + } if (validator->state == INIT) { RESULT_GUARD(s2n_x509_validator_process_cert_chain(validator, conn, cert_chain_in, cert_chain_len)); @@ -551,8 +606,7 @@ S2N_RESULT s2n_x509_validator_validate_cert_stapled_ocsp_response(struct s2n_x50 } uint64_t current_time = 0; - RESULT_GUARD_POSIX(conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_time)); - + RESULT_GUARD(s2n_config_wall_clock(conn->config, ¤t_time)); RESULT_ENSURE(current_time >= this_update, S2N_ERR_CERT_INVALID); RESULT_ENSURE(current_time <= next_update, S2N_ERR_CERT_EXPIRED); diff --git a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h index c1f379f8e9..784eedce05 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h +++ b/contrib/restricted/aws/s2n/tls/s2n_x509_validator.h @@ -33,6 +33,7 @@ typedef enum { UNINIT, INIT, READY_TO_VERIFY, + AWAITING_CRL_CALLBACK, VALIDATED, OCSP_VALIDATED, } validator_state; @@ -60,6 +61,7 @@ struct s2n_x509_validator { uint16_t max_chain_depth; STACK_OF(X509) *cert_chain_from_wire; int state; + struct s2n_array *crl_lookup_list; }; /** Some libcrypto implementations do not support OCSP validation. Returns 1 if supported, 0 otherwise. */ @@ -99,7 +101,7 @@ int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x50 int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth); /** Cleans up underlying memory and data members. Struct can be reused afterwards. */ -void s2n_x509_validator_wipe(struct s2n_x509_validator *validator); +int s2n_x509_validator_wipe(struct s2n_x509_validator *validator); /** * Validates a certificate chain against the configured trust store in safe mode. In unsafe mode, it will find the public key diff --git a/contrib/restricted/aws/s2n/utils/s2n_array.c b/contrib/restricted/aws/s2n/utils/s2n_array.c index 1df7f1e101..4d65b19924 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_array.c +++ b/contrib/restricted/aws/s2n/utils/s2n_array.c @@ -45,47 +45,64 @@ static S2N_RESULT s2n_array_enlarge(struct s2n_array *array, uint32_t capacity) uint32_t array_elements_size; RESULT_GUARD_POSIX(s2n_mul_overflow(array->element_size, array->len, &array_elements_size)); RESULT_CHECKED_MEMSET(array->mem.data + array_elements_size, 0, array->mem.size - array_elements_size); - RESULT_GUARD(s2n_array_validate(array)); + RESULT_POSTCONDITION(s2n_array_validate(array)); return S2N_RESULT_OK; } struct s2n_array *s2n_array_new(uint32_t element_size) { - struct s2n_blob mem = {0}; + struct s2n_array *array = s2n_array_new_with_capacity(element_size, S2N_INITIAL_ARRAY_SIZE); + PTR_ENSURE_REF(array); + + return array; +} + +struct s2n_array *s2n_array_new_with_capacity(uint32_t element_size, uint32_t capacity) +{ + DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free); PTR_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_array))); - struct s2n_array *array = (void *) mem.data; + DEFER_CLEANUP(struct s2n_array *array = (void *) mem.data, s2n_array_free_p); + ZERO_TO_DISABLE_DEFER_CLEANUP(mem); - *array = (struct s2n_array) {.mem = {0}, .len = 0, .element_size = element_size}; + PTR_GUARD_RESULT(s2n_array_init_with_capacity(array, element_size, capacity)); - if (s2n_result_is_error(s2n_array_enlarge(array, S2N_INITIAL_ARRAY_SIZE))) { - /* Avoid memory leak if allocation fails */ - PTR_GUARD_POSIX(s2n_free(&mem)); - return NULL; - } - return array; + struct s2n_array *array_ret = array; + ZERO_TO_DISABLE_DEFER_CLEANUP(array); + + return array_ret; } S2N_RESULT s2n_array_init(struct s2n_array *array, uint32_t element_size) { RESULT_ENSURE_REF(array); - *array = (struct s2n_array){.element_size = element_size}; + RESULT_GUARD(s2n_array_init_with_capacity(array, element_size, 0)); + + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_array_init_with_capacity(struct s2n_array *array, uint32_t element_size, uint32_t capacity) +{ + RESULT_ENSURE_REF(array); + + *array = (struct s2n_array) { .element_size = element_size }; + + RESULT_GUARD(s2n_array_enlarge(array, capacity)); - RESULT_GUARD(s2n_array_validate(array)); return S2N_RESULT_OK; } S2N_RESULT s2n_array_pushback(struct s2n_array *array, void **element) { - RESULT_GUARD(s2n_array_validate(array)); + RESULT_PRECONDITION(s2n_array_validate(array)); RESULT_ENSURE_REF(element); return s2n_array_insert(array, array->len, element); } S2N_RESULT s2n_array_get(struct s2n_array *array, uint32_t idx, void **element) { - RESULT_GUARD(s2n_array_validate(array)); + RESULT_PRECONDITION(s2n_array_validate(array)); RESULT_ENSURE_REF(element); RESULT_ENSURE(idx < array->len, S2N_ERR_ARRAY_INDEX_OOB); *element = array->mem.data + (array->element_size * idx); @@ -102,7 +119,7 @@ S2N_RESULT s2n_array_insert_and_copy(struct s2n_array *array, uint32_t idx, void S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t idx, void **element) { - RESULT_GUARD(s2n_array_validate(array)); + RESULT_PRECONDITION(s2n_array_validate(array)); RESULT_ENSURE_REF(element); /* index == len is ok since we're about to add one element */ RESULT_ENSURE(idx <= array->len, S2N_ERR_ARRAY_INDEX_OOB); @@ -131,13 +148,13 @@ S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t idx, void **elemen *element = array->mem.data + array->element_size * idx; array->len++; - RESULT_GUARD(s2n_array_validate(array)); + RESULT_POSTCONDITION(s2n_array_validate(array)); return S2N_RESULT_OK; } S2N_RESULT s2n_array_remove(struct s2n_array *array, uint32_t idx) { - RESULT_GUARD(s2n_array_validate(array)); + RESULT_PRECONDITION(s2n_array_validate(array)); RESULT_ENSURE(idx < array->len, S2N_ERR_ARRAY_INDEX_OOB); /* If the removed element is the last one, no need to move anything. @@ -156,12 +173,13 @@ S2N_RESULT s2n_array_remove(struct s2n_array *array, uint32_t idx) 0, array->element_size); + RESULT_POSTCONDITION(s2n_array_validate(array)); return S2N_RESULT_OK; } S2N_RESULT s2n_array_num_elements(struct s2n_array *array, uint32_t *len) { - RESULT_GUARD(s2n_array_validate(array)); + RESULT_PRECONDITION(s2n_array_validate(array)); RESULT_ENSURE_MUT(len); *len = array->len; @@ -171,7 +189,7 @@ S2N_RESULT s2n_array_num_elements(struct s2n_array *array, uint32_t *len) S2N_RESULT s2n_array_capacity(struct s2n_array *array, uint32_t *capacity) { - RESULT_GUARD(s2n_array_validate(array)); + RESULT_PRECONDITION(s2n_array_validate(array)); RESULT_ENSURE_MUT(capacity); *capacity = array->mem.size / array->element_size; @@ -182,9 +200,12 @@ S2N_RESULT s2n_array_capacity(struct s2n_array *array, uint32_t *capacity) S2N_CLEANUP_RESULT s2n_array_free_p(struct s2n_array **parray) { RESULT_ENSURE_REF(parray); + struct s2n_array *array = *parray; + if (array == NULL) { + return S2N_RESULT_OK; + } - RESULT_ENSURE_REF(array); /* Free the elements */ RESULT_GUARD_POSIX(s2n_free(&array->mem)); diff --git a/contrib/restricted/aws/s2n/utils/s2n_array.h b/contrib/restricted/aws/s2n/utils/s2n_array.h index a8f81325ee..f41eb5c1d2 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_array.h +++ b/contrib/restricted/aws/s2n/utils/s2n_array.h @@ -33,7 +33,9 @@ struct s2n_array { extern S2N_RESULT s2n_array_validate(const struct s2n_array *array); extern struct s2n_array *s2n_array_new(uint32_t element_size); +extern struct s2n_array *s2n_array_new_with_capacity(uint32_t element_size, uint32_t capacity); extern S2N_RESULT s2n_array_init(struct s2n_array *array, uint32_t element_size); +extern S2N_RESULT s2n_array_init_with_capacity(struct s2n_array *array, uint32_t element_size, uint32_t capacity); extern S2N_RESULT s2n_array_pushback(struct s2n_array *array, void **element); extern S2N_RESULT s2n_array_get(struct s2n_array *array, uint32_t idx, void **element); extern S2N_RESULT s2n_array_insert(struct s2n_array *array, uint32_t idx, void **element); diff --git a/contrib/restricted/aws/s2n/utils/s2n_mem.c b/contrib/restricted/aws/s2n/utils/s2n_mem.c index 4d88a52bcc..d2084c363c 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_mem.c +++ b/contrib/restricted/aws/s2n/utils/s2n_mem.c @@ -246,7 +246,7 @@ int s2n_dup(struct s2n_blob *from, struct s2n_blob *to) int s2n_mem_init(void) { - POSIX_GUARD(s2n_mem_init_cb()); + POSIX_ENSURE(s2n_mem_init_cb() >= S2N_SUCCESS, S2N_ERR_CANCELLED); initialized = true; @@ -266,7 +266,7 @@ uint32_t s2n_mem_get_page_size(void) int s2n_mem_cleanup(void) { POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED); - POSIX_GUARD(s2n_mem_cleanup_cb()); + POSIX_ENSURE(s2n_mem_cleanup_cb() >= S2N_SUCCESS, S2N_ERR_CANCELLED); initialized = false; @@ -289,20 +289,20 @@ int s2n_free_without_wipe(struct s2n_blob *b) POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED); POSIX_ENSURE(s2n_blob_is_growable(b), S2N_ERR_FREE_STATIC_BLOB); - POSIX_GUARD(s2n_mem_free_cb(b->data, b->allocated)); + if (b->data) { + POSIX_ENSURE(s2n_mem_free_cb(b->data, b->allocated) >= S2N_SUCCESS, S2N_ERR_CANCELLED); + } *b = (struct s2n_blob) {0}; return S2N_SUCCESS; } -int s2n_blob_zeroize_free(struct s2n_blob *b) { - POSIX_ENSURE(initialized, S2N_ERR_NOT_INITIALIZED); +int s2n_free_or_wipe(struct s2n_blob *b) { POSIX_ENSURE_REF(b); - - POSIX_GUARD(s2n_blob_zero(b)); + int zero_rc = s2n_blob_zero(b); if (b->allocated) { - POSIX_GUARD(s2n_free(b)); + POSIX_GUARD(s2n_free_without_wipe(b)); } - return S2N_SUCCESS; + return zero_rc; } diff --git a/contrib/restricted/aws/s2n/utils/s2n_mem.h b/contrib/restricted/aws/s2n/utils/s2n_mem.h index 4c0fb76822..75f74a0a87 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_mem.h +++ b/contrib/restricted/aws/s2n/utils/s2n_mem.h @@ -27,6 +27,15 @@ int s2n_alloc(struct s2n_blob *b, uint32_t size); int s2n_realloc(struct s2n_blob *b, uint32_t size); int s2n_free(struct s2n_blob *b); int s2n_free_without_wipe(struct s2n_blob *b); -int s2n_blob_zeroize_free(struct s2n_blob *b); int s2n_free_object(uint8_t **p_data, uint32_t size); int s2n_dup(struct s2n_blob *from, struct s2n_blob *to); + +/* Unlike free, s2n_free_or_wipe accepts static blobs. + * It frees allocated blobs and wipes static blobs. + * + * This is mostly useful for some of the s2n-tls shared secret generation logic, + * which allocates memory for some algorithms and uses static memory for others. + * + * Prefer s2n_free. Only use this method if completely necessary. + */ +int s2n_free_or_wipe(struct s2n_blob *b); diff --git a/contrib/restricted/aws/s2n/utils/s2n_random.c b/contrib/restricted/aws/s2n/utils/s2n_random.c index 9c0efc0f9f..5d79f061d2 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_random.c +++ b/contrib/restricted/aws/s2n/utils/s2n_random.c @@ -116,7 +116,7 @@ S2N_RESULT s2n_get_seed_entropy(struct s2n_blob *blob) { RESULT_ENSURE_REF(blob); - RESULT_GUARD_POSIX(s2n_rand_seed_cb(blob->data, blob->size)); + RESULT_ENSURE(s2n_rand_seed_cb(blob->data, blob->size) >= S2N_SUCCESS, S2N_ERR_CANCELLED); return S2N_RESULT_OK; } @@ -369,7 +369,7 @@ static int s2n_rand_init_impl(void) S2N_RESULT s2n_rand_init(void) { - RESULT_GUARD_POSIX(s2n_rand_init_cb()); + RESULT_ENSURE(s2n_rand_init_cb() >=S2N_SUCCESS, S2N_ERR_CANCELLED); RESULT_GUARD(s2n_ensure_initialized_drbgs()); @@ -409,7 +409,7 @@ static int s2n_rand_cleanup_impl(void) S2N_RESULT s2n_rand_cleanup(void) { - RESULT_GUARD_POSIX(s2n_rand_cleanup_cb()); + RESULT_ENSURE(s2n_rand_cleanup_cb() >= S2N_SUCCESS, S2N_ERR_CANCELLED); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Cleanup our rand ENGINE in libcrypto */ diff --git a/contrib/restricted/aws/s2n/utils/s2n_timer.c b/contrib/restricted/aws/s2n/utils/s2n_timer.c index ae93f6a7bb..4b834ef6ad 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_timer.c +++ b/contrib/restricted/aws/s2n/utils/s2n_timer.c @@ -21,7 +21,8 @@ S2N_RESULT s2n_timer_start(struct s2n_config *config, struct s2n_timer *timer) { - RESULT_GUARD_POSIX(config->monotonic_clock(config->monotonic_clock_ctx, &timer->time)); + RESULT_ENSURE(config->monotonic_clock(config->monotonic_clock_ctx, &timer->time) >= S2N_SUCCESS, + S2N_ERR_CANCELLED); return S2N_RESULT_OK; } @@ -30,7 +31,8 @@ S2N_RESULT s2n_timer_elapsed(struct s2n_config *config, struct s2n_timer *timer, { uint64_t current_time; - RESULT_GUARD_POSIX(config->monotonic_clock(config->monotonic_clock_ctx, ¤t_time)); + RESULT_ENSURE(config->monotonic_clock(config->monotonic_clock_ctx, ¤t_time) >= S2N_SUCCESS, + S2N_ERR_CANCELLED); *nanoseconds = current_time - timer->time; |