int main(int argc, char **argv) { BEGIN_TEST(); /* Test generate->write->read->compute_shared with all supported curves */ for (int i = 0; i < sizeof(s2n_ecc_supported_curves) / sizeof(s2n_ecc_supported_curves[0]); i++) { struct s2n_ecc_params server_params, client_params; struct s2n_stuffer wire; struct s2n_blob server_shared, client_shared, ecdh_params_sent, ecdh_params_received; EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&wire, 1024)); /* Server generates a key for a given curve */ server_params.negotiated_curve = &s2n_ecc_supported_curves[i]; EXPECT_SUCCESS(s2n_ecc_generate_ephemeral_key(&server_params)); /* Server sends the public */ EXPECT_SUCCESS(s2n_ecc_write_ecc_params(&server_params, &wire, &ecdh_params_sent)); /* Client reads the public */ struct s2n_ecdhe_raw_server_params ecdhe_data = {{0}}; EXPECT_SUCCESS(s2n_ecc_read_ecc_params(&wire, &ecdh_params_received, &ecdhe_data)); EXPECT_SUCCESS(s2n_ecc_parse_ecc_params(&client_params, &ecdhe_data)); /* The client got the curve */ EXPECT_EQUAL(client_params.negotiated_curve, server_params.negotiated_curve); /* Client sends its public */ EXPECT_SUCCESS(s2n_ecc_compute_shared_secret_as_client(&client_params, &wire, &client_shared)); /* Server receives it */ EXPECT_SUCCESS(s2n_ecc_compute_shared_secret_as_server(&server_params, &wire, &server_shared)); /* Shared is the same for the client and the server */ EXPECT_EQUAL(client_shared.size, server_shared.size); EXPECT_BYTEARRAY_EQUAL(client_shared.data, server_shared.data, client_shared.size); /* Clean up */ EXPECT_SUCCESS(s2n_stuffer_free(&wire)); EXPECT_SUCCESS(s2n_free(&server_shared)); EXPECT_SUCCESS(s2n_free(&client_shared)); EXPECT_SUCCESS(s2n_ecc_params_free(&server_params)); EXPECT_SUCCESS(s2n_ecc_params_free(&client_params)); } END_TEST(); }
int main(int argc, char **argv) { unsigned char publicKey[BIKE1_L1_PUBLIC_KEY_BYTES]; unsigned char privateKey[BIKE1_L1_SECRET_KEY_BYTES]; unsigned char clientSharedSecretPlaintext[BIKE1_L1_SHARED_SECRET_BYTES]; unsigned char serverSharedSecretPlaintext[BIKE1_L1_SHARED_SECRET_BYTES]; unsigned char encryptedSecret[BIKE1_L1_CIPHERTEXT_BYTES]; BEGIN_TEST(); // BIKE is not supported in FIPS mode if (s2n_is_in_fips_mode()) { END_TEST(); } EXPECT_SUCCESS(BIKE1_L1_crypto_kem_keypair(publicKey, privateKey)); EXPECT_SUCCESS(BIKE1_L1_crypto_kem_enc(encryptedSecret, clientSharedSecretPlaintext, publicKey)); EXPECT_SUCCESS(BIKE1_L1_crypto_kem_dec(serverSharedSecretPlaintext, encryptedSecret, privateKey)); EXPECT_BYTEARRAY_EQUAL(serverSharedSecretPlaintext, clientSharedSecretPlaintext, BIKE1_L1_SHARED_SECRET_BYTES); END_TEST(); }
int main(int argc, char **argv) { BEGIN_TEST(); EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0)); EXPECT_SUCCESS(setenv("S2N_DONT_MLOCK", "1", 0)); EXPECT_SUCCESS(s2n_init()); /* Client doens't use the server name extension. */ { struct s2n_connection *client_conn; struct s2n_connection *server_conn; struct s2n_config *server_config; s2n_blocked_status client_blocked; s2n_blocked_status server_blocked; int server_to_client[2]; int client_to_server[2]; /* Create nonblocking pipes */ EXPECT_SUCCESS(pipe(server_to_client)); EXPECT_SUCCESS(pipe(client_to_server)); for (int i = 0; i < 2; i++) { EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1); EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1); } EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1])); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1])); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); do { int ret; ret = s2n_negotiate(client_conn, &client_blocked); EXPECT_TRUE(ret == 0 || (client_blocked && errno == EAGAIN)); ret = s2n_negotiate(server_conn, &server_blocked); EXPECT_TRUE(ret == 0 || (server_blocked && errno == EAGAIN)); } while (client_blocked || server_blocked); /* Verify that the server didn't receive the server name. */ EXPECT_NULL(s2n_get_server_name(server_conn)); EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); for (int i = 0; i < 2; i++) { EXPECT_SUCCESS(close(server_to_client[i])); EXPECT_SUCCESS(close(client_to_server[i])); } } /* Client uses the server name extension. */ { struct s2n_connection *client_conn; struct s2n_connection *server_conn; struct s2n_config *server_config; s2n_blocked_status client_blocked; s2n_blocked_status server_blocked; int server_to_client[2]; int client_to_server[2]; const char *sent_server_name = "awesome.amazonaws.com"; const char *received_server_name; /* Create nonblocking pipes */ EXPECT_SUCCESS(pipe(server_to_client)); EXPECT_SUCCESS(pipe(client_to_server)); for (int i = 0; i < 2; i++) { EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1); EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1); } EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1])); /* Set the server name */ EXPECT_SUCCESS(s2n_set_server_name(client_conn, sent_server_name)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1])); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); do { int ret; ret = s2n_negotiate(client_conn, &client_blocked); EXPECT_TRUE(ret == 0 || (client_blocked && errno == EAGAIN)); ret = s2n_negotiate(server_conn, &server_blocked); EXPECT_TRUE(ret == 0 || (server_blocked && errno == EAGAIN)); } while (client_blocked || server_blocked); /* Verify that the server name was received intact. */ EXPECT_NOT_NULL(received_server_name = s2n_get_server_name(server_conn)); EXPECT_EQUAL(strlen(received_server_name), strlen(sent_server_name)); EXPECT_BYTEARRAY_EQUAL(received_server_name, sent_server_name, strlen(received_server_name)); EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); for (int i = 0; i < 2; i++) { EXPECT_SUCCESS(close(server_to_client[i])); EXPECT_SUCCESS(close(client_to_server[i])); } } /* Client sends multiple server names. */ { struct s2n_connection *server_conn; struct s2n_config *server_config; s2n_blocked_status server_blocked; int server_to_client[2]; int client_to_server[2]; const char *sent_server_name = "svr"; const char *received_server_name; uint8_t client_extensions[] = { /* Extension type TLS_EXTENSION_SERVER_NAME */ 0x00, 0x00, /* Extension size */ 0x00, 0x0C, /* All server names len */ 0x00, 0x0A, /* First server name type - host name */ 0x00, /* First server name len */ 0x00, 0x03, /* First server name, matches sent_server_name */ 's', 'v', 'r', /* Second server name type - host name */ 0x00, /* Second server name len */ 0x00, 0x01, /* Second server name */ 0xFF, }; int client_extensions_len = sizeof(client_extensions); uint8_t client_hello_message[] = { /* Protocol version TLS 1.2 */ 0x03, 0x03, /* Client random */ ZERO_TO_THIRTY_ONE, /* SessionID len - 32 bytes */ 0x20, /* Session ID */ ZERO_TO_THIRTY_ONE, /* Cipher suites len */ 0x00, 0x02, /* Cipher suite - TLS_RSA_WITH_AES_128_CBC_SHA256 */ 0x00, 0x3C, /* Compression methods len */ 0x01, /* Compression method - none */ 0x00, /* Extensions len */ (client_extensions_len >> 8) & 0xff, (client_extensions_len & 0xff), }; int body_len = sizeof(client_hello_message) + client_extensions_len; uint8_t message_header[] = { /* Handshake message type CLIENT HELLO */ 0x01, /* Body len */ (body_len >> 16) & 0xff, (body_len >> 8) & 0xff, (body_len & 0xff), }; int message_len = sizeof(message_header) + body_len; uint8_t record_header[] = { /* Record type HANDSHAKE */ 0x16, /* Protocol version TLS 1.2 */ 0x03, 0x03, /* Message len */ (message_len >> 8) & 0xff, (message_len & 0xff), }; /* Create nonblocking pipes */ EXPECT_SUCCESS(pipe(server_to_client)); EXPECT_SUCCESS(pipe(client_to_server)); for (int i = 0; i < 2; i++) { EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1); EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1); } EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1])); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); /* Send the client hello */ EXPECT_EQUAL(write(client_to_server[1], record_header, sizeof(record_header)), sizeof(record_header)); EXPECT_EQUAL(write(client_to_server[1], message_header, sizeof(message_header)), sizeof(message_header)); EXPECT_EQUAL(write(client_to_server[1], client_hello_message, sizeof(client_hello_message)), sizeof(client_hello_message)); EXPECT_EQUAL(write(client_to_server[1], client_extensions, sizeof(client_extensions)), sizeof(client_extensions)); /* Verify that the CLIENT HELLO is accepted */ s2n_negotiate(server_conn, &server_blocked); EXPECT_EQUAL(server_blocked, 1); EXPECT_EQUAL(server_conn->handshake.state, CLIENT_KEY); /* Verify that the server name was received intact. */ EXPECT_NOT_NULL(received_server_name = s2n_get_server_name(server_conn)); EXPECT_EQUAL(strlen(received_server_name), strlen(sent_server_name)); EXPECT_BYTEARRAY_EQUAL(received_server_name, sent_server_name, strlen(received_server_name)); EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); for (int i = 0; i < 2; i++) { EXPECT_SUCCESS(close(server_to_client[i])); EXPECT_SUCCESS(close(client_to_server[i])); } } /* Client doesn't use the OCSP extension. */ { struct s2n_connection *client_conn; struct s2n_connection *server_conn; struct s2n_config *server_config; s2n_blocked_status client_blocked; s2n_blocked_status server_blocked; int server_to_client[2]; int client_to_server[2]; uint32_t length; /* Create nonblocking pipes */ EXPECT_SUCCESS(pipe(server_to_client)); EXPECT_SUCCESS(pipe(client_to_server)); for (int i = 0; i < 2; i++) { EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1); EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1); } EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1])); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1])); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_with_status(server_config, certificate, private_key, server_ocsp_status, sizeof(server_ocsp_status))); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); do { int ret; ret = s2n_negotiate(client_conn, &client_blocked); EXPECT_TRUE(ret == 0 || client_blocked); ret = s2n_negotiate(server_conn, &server_blocked); EXPECT_TRUE(ret == 0 || server_blocked); } while (client_blocked || server_blocked); /* Verify that the client didn't receive an OCSP response. */ EXPECT_NULL(s2n_connection_get_ocsp_response(client_conn, &length)); EXPECT_EQUAL(length, 0); EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); for (int i = 0; i < 2; i++) { EXPECT_SUCCESS(close(server_to_client[i])); EXPECT_SUCCESS(close(client_to_server[i])); } } /* Server doesn't support the OCSP extension. */ { struct s2n_connection *client_conn; struct s2n_connection *server_conn; struct s2n_config *server_config; struct s2n_config *client_config; s2n_blocked_status client_blocked; s2n_blocked_status server_blocked; int server_to_client[2]; int client_to_server[2]; uint32_t length; /* Create nonblocking pipes */ EXPECT_SUCCESS(pipe(server_to_client)); EXPECT_SUCCESS(pipe(client_to_server)); for (int i = 0; i < 2; i++) { EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1); EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1); } EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1])); EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_status_request_type(client_config, S2N_STATUS_REQUEST_OCSP)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1])); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); do { int ret; ret = s2n_negotiate(client_conn, &client_blocked); EXPECT_TRUE(ret == 0 || client_blocked); ret = s2n_negotiate(server_conn, &server_blocked); EXPECT_TRUE(ret == 0 || server_blocked); } while (client_blocked || server_blocked); /* Verify that the client didn't receive an OCSP response. */ EXPECT_NULL(s2n_connection_get_ocsp_response(client_conn, &length)); EXPECT_EQUAL(length, 0); EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); EXPECT_SUCCESS(s2n_config_free(client_config)); for (int i = 0; i < 2; i++) { EXPECT_SUCCESS(close(server_to_client[i])); EXPECT_SUCCESS(close(client_to_server[i])); } } /* Server and client support the OCSP extension. */ { struct s2n_connection *client_conn; struct s2n_connection *server_conn; struct s2n_config *server_config; struct s2n_config *client_config; s2n_blocked_status client_blocked; s2n_blocked_status server_blocked; int server_to_client[2]; int client_to_server[2]; uint32_t length; /* Create nonblocking pipes */ EXPECT_SUCCESS(pipe(server_to_client)); EXPECT_SUCCESS(pipe(client_to_server)); for (int i = 0; i < 2; i++) { EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1); EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1); } EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1])); EXPECT_NOT_NULL(client_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_set_status_request_type(client_config, S2N_STATUS_REQUEST_OCSP)); EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0])); EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1])); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_with_status(server_config, certificate, private_key, server_ocsp_status, sizeof(server_ocsp_status))); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); do { int ret; ret = s2n_negotiate(client_conn, &client_blocked); EXPECT_TRUE(ret == 0 || client_blocked); ret = s2n_negotiate(server_conn, &server_blocked); EXPECT_TRUE(ret == 0 || server_blocked); } while (client_blocked || server_blocked); /* Verify that the client didn't receive an OCSP response. */ EXPECT_NULL(s2n_connection_get_ocsp_response(client_conn, &length)); EXPECT_EQUAL(length, 0); EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); EXPECT_SUCCESS(s2n_config_free(client_config)); for (int i = 0; i < 2; i++) { EXPECT_SUCCESS(close(server_to_client[i])); EXPECT_SUCCESS(close(client_to_server[i])); } } END_TEST(); return 0; }
int main(int argc, char **argv) { BEGIN_TEST(); EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0)); /* Part 1 setup a client and server connection with everything they need for a key exchange */ struct s2n_connection *client_conn, *server_conn; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); struct s2n_config *server_config, *client_config; client_config = s2n_fetch_unsafe_client_testing_config(); GUARD(s2n_connection_set_config(client_conn, client_config)); /* Part 1.1 setup server's keypair and the give the client the certificate */ char *cert_chain; char *private_key; char *client_chain; EXPECT_NOT_NULL(cert_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(private_key = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(client_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_CERT_CHAIN, cert_chain, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_KEY, private_key, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_LEAF_CERT, client_chain, S2N_MAX_TEST_PEM_SIZE)); struct s2n_cert_chain_and_key *chain_and_key; EXPECT_NOT_NULL(chain_and_key = s2n_cert_chain_and_key_new()); EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain, private_key)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); GUARD(s2n_set_signature_hash_pair_from_preference_list(server_conn, &server_conn->handshake_params.client_sig_hash_algs, &server_conn->secure.conn_hash_alg, &server_conn->secure.conn_sig_alg)); DEFER_CLEANUP(struct s2n_stuffer certificate_in = {{0}}, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, S2N_MAX_TEST_PEM_SIZE)); DEFER_CLEANUP(struct s2n_stuffer certificate_out = {{0}}, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, S2N_MAX_TEST_PEM_SIZE)); struct s2n_blob temp_blob; temp_blob.data = (uint8_t *) client_chain; temp_blob.size = strlen(client_chain) + 1; EXPECT_SUCCESS(s2n_stuffer_write(&certificate_in, &temp_blob)); EXPECT_SUCCESS(s2n_stuffer_certificate_from_pem(&certificate_in, &certificate_out)); temp_blob.size = s2n_stuffer_data_available(&certificate_out); temp_blob.data = s2n_stuffer_raw_read(&certificate_out, temp_blob.size); s2n_cert_type cert_type; EXPECT_SUCCESS(s2n_asn1der_to_public_key_and_type(&client_conn->secure.server_public_key, &cert_type, &temp_blob)); server_conn->handshake_params.our_chain_and_key = chain_and_key; EXPECT_SUCCESS(setup_connection(server_conn)); EXPECT_SUCCESS(setup_connection(client_conn)); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Read the seed from the RSP_FILE and create the DRBG for the test. Since the seed is the same (and prediction * resistance is off) all calls to generate random data will return the same sequence. Thus the server always * generates the same ECDHE point and KEM public key, the client does the same. */ FILE *kat_file = fopen(RSP_FILE_NAME, "r"); EXPECT_NOT_NULL(kat_file); EXPECT_SUCCESS(s2n_alloc(&kat_entropy_blob, 48)); EXPECT_SUCCESS(ReadHex(kat_file, kat_entropy_blob.data, 48, "seed = ")); struct s2n_drbg drbg = {.entropy_generator = &s2n_entropy_generator}; s2n_stack_blob(personalization_string, 32, 32); EXPECT_SUCCESS(s2n_drbg_instantiate(&drbg, &personalization_string, S2N_DANGEROUS_AES_256_CTR_NO_DF_NO_PR)); EXPECT_SUCCESS(s2n_set_private_drbg_for_test(drbg)); #endif /* Part 2 server sends key first */ EXPECT_SUCCESS(s2n_server_key_send(server_conn)); /* Part 2.1 verify the results as best we can */ EXPECT_EQUAL(server_conn->handshake.io.write_cursor, SERVER_KEY_MESSAGE_LENGTH); struct s2n_blob server_key_message = {.size = SERVER_KEY_MESSAGE_LENGTH, .data = s2n_stuffer_raw_read(&server_conn->handshake.io, SERVER_KEY_MESSAGE_LENGTH)}; #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Part 2.1.1 if we're running in known answer mode check the server's key exchange message matches the expected value */ uint8_t expected_server_key_message[SERVER_KEY_MESSAGE_LENGTH]; EXPECT_SUCCESS(ReadHex(kat_file, expected_server_key_message, SERVER_KEY_MESSAGE_LENGTH, "expected_server_key_exchange = ")); EXPECT_BYTEARRAY_EQUAL(expected_server_key_message, server_key_message.data, SERVER_KEY_MESSAGE_LENGTH); #endif /* Part 2.2 copy server's message to the client's stuffer */ s2n_stuffer_write(&client_conn->handshake.io, &server_key_message); /* Part 3 client recvs the server's key and sends the client key exchange message */ EXPECT_SUCCESS(s2n_server_key_recv(client_conn)); EXPECT_SUCCESS(s2n_client_key_send(client_conn)); /* Part 3.1 verify the results as best we can */ EXPECT_EQUAL(client_conn->handshake.io.write_cursor - client_conn->handshake.io.read_cursor, CLIENT_KEY_MESSAGE_LENGTH); struct s2n_blob client_key_message = {.size = CLIENT_KEY_MESSAGE_LENGTH, .data = s2n_stuffer_raw_read(&client_conn->handshake.io, CLIENT_KEY_MESSAGE_LENGTH)}; #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Part 3.1.1 if we're running in known answer mode check the client's key exchange message matches the expected value */ uint8_t expected_client_key_message[CLIENT_KEY_MESSAGE_LENGTH]; EXPECT_SUCCESS(ReadHex(kat_file, expected_client_key_message, CLIENT_KEY_MESSAGE_LENGTH, "expected_client_key_exchange = ")); EXPECT_BYTEARRAY_EQUAL(expected_client_key_message, client_key_message.data, CLIENT_KEY_MESSAGE_LENGTH); #endif /* Part 3.2 copy the client's message back to the server's stuffer */ s2n_stuffer_write(&server_conn->handshake.io, &client_key_message); /* Part 4 server receives the client's message */ EXPECT_SUCCESS(s2n_client_key_recv(server_conn)); /* Part 4.1 verify results as best we can, the client and server should at least have the same master secret */ EXPECT_BYTEARRAY_EQUAL(server_conn->secure.master_secret, client_conn->secure.master_secret, S2N_TLS_SECRET_LEN); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Part 4.1.1 if we're running in known answer mode check that both the client and server got the expected master secret * from the RSP_FILE */ uint8_t expected_master_secret[S2N_TLS_SECRET_LEN]; EXPECT_SUCCESS(ReadHex(kat_file, expected_master_secret, S2N_TLS_SECRET_LEN, "expected_master_secret = ")); EXPECT_BYTEARRAY_EQUAL(expected_master_secret, client_conn->secure.master_secret, S2N_TLS_SECRET_LEN); EXPECT_BYTEARRAY_EQUAL(expected_master_secret, server_conn->secure.master_secret, S2N_TLS_SECRET_LEN); #endif EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); free(cert_chain); free(client_chain); free(private_key); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Extra cleanup needed for the known answer test */ fclose(kat_file); #endif END_TEST(); }