diff --git a/tests/unit/s2n_server_cert_request_test.c b/tests/unit/s2n_server_cert_request_test.c index 828eddfceb5..fbdd6392c92 100644 --- a/tests/unit/s2n_server_cert_request_test.c +++ b/tests/unit/s2n_server_cert_request_test.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); - s2n_cert_req_send(server_conn); + EXPECT_SUCCESS(s2n_cert_req_send(server_conn)); struct s2n_stuffer *in = &server_conn->handshake.io; uint8_t cert_types_len = 0; @@ -88,7 +88,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); EXPECT_SUCCESS(s2n_config_enable_cert_req_dss_legacy_compat(server_config)); - s2n_cert_req_send(server_conn); + EXPECT_SUCCESS(s2n_cert_req_send(server_conn)); struct s2n_stuffer *in = &server_conn->handshake.io; uint8_t cert_types_len = 0; @@ -105,6 +105,78 @@ int main(int argc, char **argv) EXPECT_SUCCESS(s2n_connection_free(server_conn)); }; + /* Test: certificate_authorities supported */ + { + /* Test: no cert_authorities sent by default */ + { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + conn->actual_protocol_version = S2N_TLS12; + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + EXPECT_SUCCESS(s2n_cert_req_send(conn)); + struct s2n_stuffer *output = &conn->handshake.io; + + uint8_t cert_types_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint8(output, &cert_types_len)); + EXPECT_TRUE(cert_types_len > 0); + EXPECT_SUCCESS(s2n_stuffer_skip_read(output, cert_types_len)); + + uint16_t sig_algs_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint16(output, &sig_algs_len)); + EXPECT_TRUE(sig_algs_len > 0); + EXPECT_SUCCESS(s2n_stuffer_skip_read(output, sig_algs_len)); + + uint16_t cert_authorities_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint16(output, &cert_authorities_len)); + EXPECT_EQUAL(cert_authorities_len, 0); + + EXPECT_EQUAL(s2n_stuffer_data_available(output), 0); + }; + + /* Test: cert_authorities sent if configured */ + { + DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_SERVER), + s2n_connection_ptr_free); + EXPECT_NOT_NULL(conn); + + DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), + s2n_config_ptr_free); + EXPECT_NOT_NULL(config); + EXPECT_SUCCESS(s2n_connection_set_config(conn, config)); + + /* If we use TLS1.1 instead of TLS1.2, we don't need to worry about + * skipping the signature algorithms. + */ + conn->actual_protocol_version = S2N_TLS11; + + const uint8_t ca_data[] = "these are my CAs"; + EXPECT_SUCCESS(s2n_alloc(&config->cert_authorities, sizeof(ca_data))); + EXPECT_MEMCPY_SUCCESS(config->cert_authorities.data, ca_data, sizeof(ca_data)); + + EXPECT_SUCCESS(s2n_cert_req_send(conn)); + struct s2n_stuffer *output = &conn->handshake.io; + + uint8_t cert_types_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint8(output, &cert_types_len)); + EXPECT_SUCCESS(s2n_stuffer_skip_read(output, cert_types_len)); + + uint16_t cert_authorities_len = 0; + EXPECT_SUCCESS(s2n_stuffer_read_uint16(output, &cert_authorities_len)); + EXPECT_EQUAL(cert_authorities_len, sizeof(ca_data)); + + uint8_t *cert_authorities_data = s2n_stuffer_raw_read(output, cert_authorities_len); + EXPECT_NOT_NULL(cert_authorities_data); + EXPECT_BYTEARRAY_EQUAL(cert_authorities_data, ca_data, sizeof(ca_data)); + + EXPECT_EQUAL(s2n_stuffer_data_available(output), 0); + }; + }; + END_TEST(); - return 0; } diff --git a/tls/extensions/s2n_cert_authorities.c b/tls/extensions/s2n_cert_authorities.c index 8dd8415d7da..92dfe625201 100644 --- a/tls/extensions/s2n_cert_authorities.c +++ b/tls/extensions/s2n_cert_authorities.c @@ -83,7 +83,7 @@ int s2n_config_set_cert_authorities_from_trust_store(struct s2n_config *config, return S2N_SUCCESS; } -static int s2n_cert_authorities_send(struct s2n_connection *conn, struct s2n_stuffer *out) +int s2n_cert_authorities_send(struct s2n_connection *conn, struct s2n_stuffer *out) { POSIX_ENSURE_REF(conn); POSIX_ENSURE_REF(conn->config); diff --git a/tls/s2n_server_cert_request.c b/tls/s2n_server_cert_request.c index 79929a32cda..d2173960c20 100644 --- a/tls/s2n_server_cert_request.c +++ b/tls/s2n_server_cert_request.c @@ -17,6 +17,7 @@ #include "crypto/s2n_certificate.h" #include "error/s2n_errno.h" #include "extensions/s2n_extension_list.h" +#include "extensions/s2n_cert_authorities.h" #include "stuffer/s2n_stuffer.h" #include "tls/s2n_cipher_suites.h" #include "tls/s2n_config.h" @@ -174,10 +175,8 @@ int s2n_cert_req_send(struct s2n_connection *conn) POSIX_GUARD_RESULT(s2n_signature_algorithms_supported_list_send(conn, out)); } - /* RFC 5246 7.4.4 - If the certificate_authorities list is empty, then the - * client MAY send any certificate of the appropriate ClientCertificateType */ - uint16_t acceptable_cert_authorities_len = 0; - POSIX_GUARD(s2n_stuffer_write_uint16(out, acceptable_cert_authorities_len)); + /* In TLS1.2, certificate_authorities is part of the message instead of an extension */ + POSIX_GUARD(s2n_cert_authorities_send(conn, out)); - return 0; + return S2N_SUCCESS; }