int main(int argc, char **argv)
{
    struct s2n_stuffer dhparams_in, dhparams_out;
    struct s2n_dh_params dh_params;
    struct s2n_blob b;

    BEGIN_TEST();

    EXPECT_EQUAL(s2n_get_private_random_bytes_used(), 0);

    /* Parse the DH params */
    b.data = dhparams;
    b.size = sizeof(dhparams);
    EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_in, sizeof(dhparams)));
    EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_out, sizeof(dhparams)));
    EXPECT_SUCCESS(s2n_stuffer_write(&dhparams_in, &b));
    EXPECT_SUCCESS(s2n_stuffer_dhparams_from_pem(&dhparams_in, &dhparams_out));
    b.size = s2n_stuffer_data_available(&dhparams_out);
    b.data = s2n_stuffer_raw_read(&dhparams_out, b.size);
    EXPECT_SUCCESS(s2n_pkcs3_to_dh_params(&dh_params, &b));

    EXPECT_SUCCESS(s2n_dh_generate_ephemeral_key(&dh_params));
    
    /* Verify that our DRBG is called and that over-riding works */
    EXPECT_NOT_EQUAL(s2n_get_private_random_bytes_used(), 0);

    EXPECT_SUCCESS(s2n_dh_params_free(&dh_params));
    EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_out));
    EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_in));

    END_TEST();
}
Example #2
0
int s2n_connection_free(struct s2n_connection *conn)
{
    struct s2n_blob blob;

    GUARD(s2n_connection_free_keys(conn));

    GUARD(s2n_stuffer_free(&conn->in));
    GUARD(s2n_stuffer_free(&conn->out));
    GUARD(s2n_stuffer_free(&conn->handshake.io));

    blob.data = (uint8_t *) conn;
    blob.size = sizeof(struct s2n_connection);

    GUARD(s2n_free(&blob));
    return 0;
}
int main(int argc, char **argv)
{
    uint8_t u8; uint16_t u16; uint32_t u32;
    
    uint32_t stuffer_size = nondet_uint32();
	__CPROVER_assume(stuffer_size > 0);
	
	uint32_t entropy_size = nondet_uint32();
	__CPROVER_assume(entropy_size > 0);
	
	uint8_t entropy[entropy_size];
    struct s2n_stuffer stuffer;
	
    GUARD(s2n_stuffer_alloc(&stuffer, stuffer_size));

    struct s2n_blob in = {.data = entropy,.size = entropy_size};
    GUARD(s2n_stuffer_write(&stuffer, &in));

	GUARD(s2n_stuffer_wipe(&stuffer));
	while(nondet_bool()) {
        GUARD(s2n_stuffer_write_uint8(&stuffer, nondet_uint64()));
    }

    while(nondet_bool()) {
        GUARD(s2n_stuffer_read_uint8(&stuffer, &u8));
    }

    GUARD(s2n_stuffer_wipe(&stuffer));
    while(nondet_bool()) {
        GUARD(s2n_stuffer_write_uint16(&stuffer, nondet_uint64()));
    }

    while(nondet_bool()) {
        GUARD(s2n_stuffer_read_uint16(&stuffer, &u16));
    }

    GUARD(s2n_stuffer_wipe(&stuffer));
    while(nondet_bool()) {
        GUARD(s2n_stuffer_write_uint24(&stuffer, nondet_uint64()));
    }

    while(nondet_bool()) {
        GUARD(s2n_stuffer_read_uint24(&stuffer, &u32));
    }

    GUARD(s2n_stuffer_wipe(&stuffer));
    while(nondet_bool()) {
        GUARD(s2n_stuffer_write_uint32(&stuffer, nondet_uint64()));
    }

    while(nondet_bool()) {
        GUARD(s2n_stuffer_read_uint32(&stuffer, &u32));
    }

    GUARD(s2n_stuffer_free(&stuffer));
}
Example #4
0
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();
}
Example #5
0
int main(int argc, char **argv)
{
    uint8_t data[256] = { 0 };
    struct s2n_drbg drbg = {{ 0 }};
    struct s2n_blob blob = {.data = data, .size = 64 };
    struct s2n_timer timer;
    uint64_t drbg_nanoseconds;
    uint64_t urandom_nanoseconds;
    struct s2n_stuffer nist_reference_personalization_strings;
    struct s2n_stuffer nist_reference_returned_bits;
    struct s2n_stuffer nist_reference_values;
    struct s2n_config *config;

    BEGIN_TEST();

    EXPECT_NOT_NULL(config = s2n_config_new())

    /* Open /dev/urandom */
    EXPECT_TRUE(entropy_fd = open("/dev/urandom", O_RDONLY));

    /* Convert the hex entropy data into binary */
    EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_entropy, nist_reference_entropy_hex));
    EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_personalization_strings, nist_reference_personalization_strings_hex));
    EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_returned_bits, nist_reference_returned_bits_hex));
    EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_values, nist_reference_values_hex));

    /* Check everything against the NIST vectors */
    for (int i = 0; i < 14; i++) {
        uint8_t ps[32];
        struct s2n_drbg nist_drbg = { .entropy_generator = nist_fake_urandom_data };
        struct s2n_blob personalization_string = {.data = ps, .size = 32};
        /* Read the next personalization string */
        EXPECT_SUCCESS(s2n_stuffer_read(&nist_reference_personalization_strings, &personalization_string));

        /* Instantiate the DRBG */
        EXPECT_SUCCESS(s2n_drbg_instantiate(&nist_drbg, &personalization_string));

        uint8_t nist_v[16];

        GUARD(s2n_stuffer_read_bytes(&nist_reference_values, nist_v, sizeof(nist_v)));
        EXPECT_TRUE(memcmp(nist_v, nist_drbg.v, sizeof(nist_drbg.v)) == 0);

        /* Generate 512 bits (FIRST CALL) */
        uint8_t out[64];
        struct s2n_blob generated = {.data = out, .size = 64 };
        EXPECT_SUCCESS(s2n_drbg_generate(&nist_drbg, &generated));

        GUARD(s2n_stuffer_read_bytes(&nist_reference_values, nist_v, sizeof(nist_v)));
        EXPECT_TRUE(memcmp(nist_v, nist_drbg.v, sizeof(nist_drbg.v)) == 0);

        /* Generate another 512 bits (SECOND CALL) */
        EXPECT_SUCCESS(s2n_drbg_generate(&nist_drbg, &generated));

        GUARD(s2n_stuffer_read_bytes(&nist_reference_values, nist_v, sizeof(nist_v)));
        EXPECT_TRUE(memcmp(nist_v, nist_drbg.v, sizeof(nist_drbg.v)) == 0);

        uint8_t nist_returned_bits[64];
        GUARD(s2n_stuffer_read_bytes(&nist_reference_returned_bits, nist_returned_bits, sizeof(nist_returned_bits)));
        EXPECT_TRUE(memcmp(nist_returned_bits, out, sizeof(nist_returned_bits)) == 0);

        EXPECT_SUCCESS(s2n_drbg_wipe(&nist_drbg));
    }

    EXPECT_SUCCESS(s2n_drbg_instantiate(&drbg, &blob));

    /* Use the DRBG for 32MB of data */
    EXPECT_SUCCESS(s2n_timer_start(config, &timer));
    for (int i = 0; i < 500000; i++) {
        EXPECT_SUCCESS(s2n_drbg_generate(&drbg, &blob));
    }
    EXPECT_SUCCESS(s2n_timer_reset(config, &timer, &drbg_nanoseconds));

    /* Use urandom for 32MB of data */
    EXPECT_SUCCESS(s2n_timer_start(config, &timer));
    for (int i = 0; i < 500000; i++) {
        EXPECT_SUCCESS(s2n_get_urandom_data(&blob));
    }
    EXPECT_SUCCESS(s2n_timer_reset(config, &timer, &urandom_nanoseconds));

    /* Confirm that the DRBG is faster than urandom */
    EXPECT_TRUE(drbg_nanoseconds < urandom_nanoseconds);

    /* NOTE: s2n_random_test also includes monobit tests for this DRBG */

    /* the DRBG state is 128 bytes, test that we can get more than that */
    blob.size = 129;
    for (int i = 0; i < 10; i++) {
        EXPECT_SUCCESS(s2n_drbg_generate(&drbg, &blob));
    }

    EXPECT_SUCCESS(s2n_drbg_wipe(&drbg));

    EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_entropy));
    EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_personalization_strings));
    EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_returned_bits));
    EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_values));

    END_TEST();
}
Example #6
0
int s2n_config_free_cert_chain_and_key(struct s2n_config *config)
{
    struct s2n_blob b = {
        .data = (uint8_t *) config->cert_and_key_pairs,
        .size = sizeof(struct s2n_cert_chain_and_key)
    };

    /* If there were cert and key pairs set, walk the chain and free the certs */
    if (config->cert_and_key_pairs) {
        struct s2n_cert_chain *node = config->cert_and_key_pairs->head;
        while (node) {
            struct s2n_blob n = {
                .data = (uint8_t *)node,
                .size = sizeof(struct s2n_cert_chain)
            };
            /* Free the cert */
            GUARD(s2n_free(&node->cert));
            /* Advance to next */
            node = node->next;
            /* Free the node */
            GUARD(s2n_free(&n));
        }
        GUARD(s2n_rsa_private_key_free(&config->cert_and_key_pairs->private_key));
        GUARD(s2n_free(&config->cert_and_key_pairs->ocsp_status));
    }

    GUARD(s2n_free(&b));
    return 0;
}

int s2n_config_free_dhparams(struct s2n_config *config)
{
    struct s2n_blob b = {
        .data = (uint8_t *) config->dhparams,
        .size = sizeof(struct s2n_dh_params)
    };

    if (config->dhparams) {
        GUARD(s2n_dh_params_free(config->dhparams));
    }

    GUARD(s2n_free(&b));
    return 0;
}

int s2n_config_free(struct s2n_config *config)
{
    struct s2n_blob b = {.data = (uint8_t *) config,.size = sizeof(struct s2n_config) };

    GUARD(s2n_config_free_cert_chain_and_key(config));
    GUARD(s2n_config_free_dhparams(config));
    GUARD(s2n_free(&config->application_protocols));

    GUARD(s2n_free(&b));
    return 0;
}

int s2n_config_set_cipher_preferences(struct s2n_config *config, const char *version)
{
    for (int i = 0; selection[i].version != NULL; i++) {
        if (!strcasecmp(version, selection[i].version)) {
            config->cipher_preferences = selection[i].preferences;
            return 0;
        }
    }

    s2n_errno = S2N_ERR_INVALID_CIPHER_PREFERENCES;
    return -1;
}

int s2n_config_set_protocol_preferences(struct s2n_config *config, const char * const *protocols, int protocol_count)
{
    struct s2n_stuffer protocol_stuffer;

    GUARD(s2n_free(&config->application_protocols));

    if (protocols == NULL || protocol_count == 0) {
        /* NULL value indicates no prference, so nothing to do */
        return 0;
    }

    GUARD(s2n_stuffer_growable_alloc(&protocol_stuffer, 256));
    for (int i = 0; i < protocol_count; i++) {
        size_t length = strlen(protocols[i]);
        uint8_t protocol[255];

        if (length > 255 || (s2n_stuffer_data_available(&protocol_stuffer) + length + 1) > 65535) {
            return S2N_ERR_APPLICATION_PROTOCOL_TOO_LONG;
        }
        memcpy_check(protocol, protocols[i], length);
        GUARD(s2n_stuffer_write_uint8(&protocol_stuffer, length));
        GUARD(s2n_stuffer_write_bytes(&protocol_stuffer, protocol, length));
    }

    uint32_t size = s2n_stuffer_data_available(&protocol_stuffer);
    /* config->application_protocols blob now owns this data */
    config->application_protocols.size = size;
    config->application_protocols.data = s2n_stuffer_raw_read(&protocol_stuffer, size);
    notnull_check(config->application_protocols.data);

    return 0;
}

int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type)
{
    config->status_request_type = type;

    return 0;
}

int s2n_config_add_cert_chain_and_key_with_status(struct s2n_config *config,
        char *cert_chain_pem, char *private_key_pem, const uint8_t *status, uint32_t length)
{
    struct s2n_stuffer chain_in_stuffer, cert_out_stuffer, key_in_stuffer, key_out_stuffer;
    struct s2n_blob key_blob;
    struct s2n_blob mem;

    /* Allocate the memory for the chain and key struct */
    GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert_chain_and_key)));
    config->cert_and_key_pairs = (struct s2n_cert_chain_and_key *)(void *)mem.data;
    config->cert_and_key_pairs->ocsp_status.data = NULL;
    config->cert_and_key_pairs->ocsp_status.size = 0;

    /* Put the private key pem in a stuffer */
    GUARD(s2n_stuffer_alloc_ro_from_string(&key_in_stuffer, private_key_pem));
    GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, strlen(private_key_pem)));

    /* Convert pem to asn1 and asn1 to the private key */
    GUARD(s2n_stuffer_rsa_private_key_from_pem(&key_in_stuffer, &key_out_stuffer));
    GUARD(s2n_stuffer_free(&key_in_stuffer));
    key_blob.size = s2n_stuffer_data_available(&key_out_stuffer);
    key_blob.data = s2n_stuffer_raw_read(&key_out_stuffer, key_blob.size);
    notnull_check(key_blob.data);
    GUARD(s2n_asn1der_to_rsa_private_key(&config->cert_and_key_pairs->private_key, &key_blob));
    GUARD(s2n_stuffer_free(&key_out_stuffer));

    /* Turn the chain into a stuffer */
    GUARD(s2n_stuffer_alloc_ro_from_string(&chain_in_stuffer, cert_chain_pem));
    GUARD(s2n_stuffer_growable_alloc(&cert_out_stuffer, 2048));

    struct s2n_cert_chain **insert = &config->cert_and_key_pairs->head;
    uint32_t chain_size = 0;
    do {
        struct s2n_cert_chain *new_node;

        if (s2n_stuffer_certificate_from_pem(&chain_in_stuffer, &cert_out_stuffer) < 0) {
            if (chain_size == 0) {
                S2N_ERROR(S2N_ERR_NO_CERTIFICATE_IN_PEM);
            }
            break;
        }

        GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert_chain)));
        new_node = (struct s2n_cert_chain *)(void *)mem.data;

        GUARD(s2n_alloc(&new_node->cert, s2n_stuffer_data_available(&cert_out_stuffer)));
        GUARD(s2n_stuffer_read(&cert_out_stuffer, &new_node->cert));

        /* Additional 3 bytes for the length field in the protocol */
        chain_size += new_node->cert.size + 3;
        new_node->next = NULL;
        *insert = new_node;
        insert = &new_node->next;
    } while (s2n_stuffer_data_available(&chain_in_stuffer));

    GUARD(s2n_stuffer_free(&chain_in_stuffer));
    GUARD(s2n_stuffer_free(&cert_out_stuffer));

    config->cert_and_key_pairs->chain_size = chain_size;

    if (status && length > 0) {
        GUARD(s2n_alloc(&config->cert_and_key_pairs->ocsp_status, length));
        memcpy_check(config->cert_and_key_pairs->ocsp_status.data, status, length);
    }

    return 0;
}

int s2n_config_add_cert_chain_and_key(struct s2n_config *config, char *cert_chain_pem, char *private_key_pem)
{
    GUARD(s2n_config_add_cert_chain_and_key_with_status(config, cert_chain_pem, private_key_pem, NULL, 0));

    return 0;
}

int s2n_config_add_dhparams(struct s2n_config *config, char *dhparams_pem)
{
    struct s2n_stuffer dhparams_in_stuffer, dhparams_out_stuffer;
    struct s2n_blob dhparams_blob;
    struct s2n_blob mem;

    /* Allocate the memory for the chain and key struct */
    GUARD(s2n_alloc(&mem, sizeof(struct s2n_dh_params)));
    config->dhparams = (struct s2n_dh_params *)(void *)mem.data;

    GUARD(s2n_stuffer_alloc_ro_from_string(&dhparams_in_stuffer, dhparams_pem));
    GUARD(s2n_stuffer_growable_alloc(&dhparams_out_stuffer, strlen(dhparams_pem)));

    /* Convert pem to asn1 and asn1 to the private key */
    GUARD(s2n_stuffer_dhparams_from_pem(&dhparams_in_stuffer, &dhparams_out_stuffer));

    GUARD(s2n_stuffer_free(&dhparams_in_stuffer));

    dhparams_blob.size = s2n_stuffer_data_available(&dhparams_out_stuffer);
    dhparams_blob.data = s2n_stuffer_raw_read(&dhparams_out_stuffer, dhparams_blob.size);
    notnull_check(dhparams_blob.data);

    GUARD(s2n_pkcs3_to_dh_params(config->dhparams, &dhparams_blob));

    GUARD(s2n_free(&dhparams_blob));

    return 0;
}
 
int s2n_config_set_nanoseconds_since_epoch_callback(struct s2n_config *config, int (*nanoseconds_since_epoch)(void *, uint64_t *), void * data)
{
    notnull_check(nanoseconds_since_epoch);

    config->nanoseconds_since_epoch = nanoseconds_since_epoch;
    config->data_for_nanoseconds_since_epoch = data;

    return 0;
}
Example #7
0
int main(int argc, char **argv)
{
    struct s2n_stuffer certificate_in, certificate_out;
    struct s2n_stuffer dhparams_in, dhparams_out;
    struct s2n_stuffer rsa_key_in, rsa_key_out;
    struct s2n_blob b;

    BEGIN_TEST();

    EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, sizeof(certificate)));
    EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, sizeof(certificate)));
    EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_in, sizeof(dhparams)));
    EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_out, sizeof(dhparams)));
    EXPECT_SUCCESS(s2n_stuffer_alloc(&rsa_key_in, sizeof(private_key)));
    EXPECT_SUCCESS(s2n_stuffer_alloc(&rsa_key_out, sizeof(private_key)));

    b.data = certificate;
    b.size = sizeof(certificate);
    EXPECT_SUCCESS(s2n_stuffer_write(&certificate_in, &b));

    b.data = private_key;
    b.size = sizeof(private_key);
    EXPECT_SUCCESS(s2n_stuffer_write(&rsa_key_in, &b));

    b.data = dhparams;
    b.size = sizeof(dhparams);
    EXPECT_SUCCESS(s2n_stuffer_write(&dhparams_in, &b));

    EXPECT_SUCCESS(s2n_stuffer_certificate_from_pem(&certificate_in, &certificate_out));
    EXPECT_SUCCESS(s2n_stuffer_rsa_private_key_from_pem(&rsa_key_in, &rsa_key_out));
    EXPECT_SUCCESS(s2n_stuffer_dhparams_from_pem(&dhparams_in, &dhparams_out));

    struct s2n_rsa_private_key priv_key;
    struct s2n_rsa_public_key pub_key;

    b.size = s2n_stuffer_data_available(&certificate_out);
    b.data = s2n_stuffer_raw_read(&certificate_out, b.size);
    EXPECT_SUCCESS(s2n_asn1der_to_rsa_public_key(&pub_key, &b));

    b.size = s2n_stuffer_data_available(&rsa_key_out);
    b.data = s2n_stuffer_raw_read(&rsa_key_out, b.size);
    EXPECT_SUCCESS(s2n_asn1der_to_rsa_private_key(&priv_key, &b));

    EXPECT_SUCCESS(s2n_rsa_keys_match(&pub_key, &priv_key));

    struct s2n_connection *conn;
    EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER));
    EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(conn->config, (char *)chain, (char *)private_key));

    struct s2n_dh_params dh_params;
    b.size = s2n_stuffer_data_available(&dhparams_out);
    b.data = s2n_stuffer_raw_read(&dhparams_out, b.size);
    EXPECT_SUCCESS(s2n_pkcs3_to_dh_params(&dh_params, &b));

    EXPECT_SUCCESS(s2n_config_add_dhparams(conn->config, (char *)dhparams));

    /* Try signing and verification with RSA */
    uint8_t inputpad[] = "Hello world!";
    struct s2n_blob signature;
    struct s2n_hash_state tls10_one, tls10_two, tls12_one, tls12_two;

    EXPECT_SUCCESS(s2n_hash_init(&tls10_one, S2N_HASH_MD5_SHA1));
    EXPECT_SUCCESS(s2n_hash_init(&tls10_two, S2N_HASH_MD5_SHA1));
    EXPECT_SUCCESS(s2n_hash_init(&tls12_one, S2N_HASH_SHA1));
    EXPECT_SUCCESS(s2n_hash_init(&tls12_two, S2N_HASH_SHA1));

    EXPECT_SUCCESS(s2n_alloc(&signature, s2n_rsa_public_encrypted_size(&pub_key)));

    EXPECT_SUCCESS(s2n_hash_update(&tls10_one, inputpad, sizeof(inputpad)));
    EXPECT_SUCCESS(s2n_hash_update(&tls10_two, inputpad, sizeof(inputpad)));
    EXPECT_SUCCESS(s2n_rsa_sign(&priv_key, &tls10_one, &signature));
    EXPECT_SUCCESS(s2n_rsa_verify(&pub_key, &tls10_two, &signature));

    EXPECT_SUCCESS(s2n_hash_update(&tls12_one, inputpad, sizeof(inputpad)));
    EXPECT_SUCCESS(s2n_hash_update(&tls12_two, inputpad, sizeof(inputpad)));
    EXPECT_SUCCESS(s2n_rsa_sign(&priv_key, &tls12_one, &signature));
    EXPECT_SUCCESS(s2n_rsa_verify(&pub_key, &tls12_two, &signature));

    EXPECT_SUCCESS(s2n_dh_params_free(&dh_params));
    EXPECT_SUCCESS(s2n_rsa_private_key_free(&priv_key));
    EXPECT_SUCCESS(s2n_rsa_public_key_free(&pub_key));
    EXPECT_SUCCESS(s2n_config_free_dhparams(conn->config));
    EXPECT_SUCCESS(s2n_config_free_cert_chain_and_key(conn->config));
    EXPECT_SUCCESS(s2n_connection_free(conn));
    EXPECT_SUCCESS(s2n_free(&signature));
    EXPECT_SUCCESS(s2n_stuffer_free(&certificate_in));
    EXPECT_SUCCESS(s2n_stuffer_free(&certificate_out));
    EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_in));
    EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_out));
    EXPECT_SUCCESS(s2n_stuffer_free(&rsa_key_in));
    EXPECT_SUCCESS(s2n_stuffer_free(&rsa_key_out));

    END_TEST();
}