Esempio n. 1
0
int s2n_server_key_recv(struct s2n_connection *conn)
{
    struct s2n_hash_state *signature_hash = &conn->secure.signature_hash;
    const struct s2n_kex *key_exchange = conn->secure.cipher_suite->key_exchange_alg;
    struct s2n_stuffer *in = &conn->handshake.io;
    struct s2n_blob data_to_verify = {0};

    /* Read the KEX data */
    union s2n_kex_raw_server_data kex_data = {{{0}}};
    GUARD(s2n_kex_server_key_recv_read_data(key_exchange, conn, &data_to_verify, &kex_data));

    /* Add common signature data */
    if (conn->actual_protocol_version == S2N_TLS12) {
        s2n_hash_algorithm hash_algorithm;
        s2n_signature_algorithm signature_algorithm;
        GUARD(s2n_get_signature_hash_pair_if_supported(in, &hash_algorithm, &signature_algorithm));
        GUARD(s2n_hash_init(signature_hash, hash_algorithm));
    } else {
        GUARD(s2n_hash_init(signature_hash, conn->secure.conn_hash_alg));
    }
    GUARD(s2n_hash_update(signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
    GUARD(s2n_hash_update(signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));

    /* Add KEX specific data */
    GUARD(s2n_hash_update(signature_hash, data_to_verify.data, data_to_verify.size));

    /* Verify the signature */
    uint16_t signature_length;
    GUARD(s2n_stuffer_read_uint16(in, &signature_length));

    struct s2n_blob signature = {.size = signature_length, .data = s2n_stuffer_raw_read(in, signature_length)};
    notnull_check(signature.data);
    gt_check(signature_length, 0);

    S2N_ERROR_IF(s2n_pkey_verify(&conn->secure.server_public_key, signature_hash, &signature) < 0, S2N_ERR_BAD_MESSAGE);

    /* We don't need the key any more, so free it */
    GUARD(s2n_pkey_free(&conn->secure.server_public_key));

    /* Parse the KEX data into whatever form needed and save it to the connection object */
    GUARD(s2n_kex_server_key_recv_parse_data(key_exchange, conn, &kex_data));

    return 0;
}

int s2n_ecdhe_server_key_recv_read_data(struct s2n_connection *conn, struct s2n_blob *data_to_verify, union s2n_kex_raw_server_data *raw_server_data)
{
    struct s2n_stuffer *in = &conn->handshake.io;

    GUARD(s2n_ecc_read_ecc_params(in, data_to_verify, &raw_server_data->ecdhe_data));
    return 0;
}

int s2n_ecdhe_server_key_recv_parse_data(struct s2n_connection *conn, union s2n_kex_raw_server_data *raw_server_data)
{
    GUARD(s2n_ecc_parse_ecc_params(&conn->secure.server_ecc_params, &raw_server_data->ecdhe_data));
    return 0;
}
Esempio n. 2
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();
}
static int s2n_ecdhe_server_key_recv(struct s2n_connection *conn)
{
    struct s2n_hash_state signature_hash;
    struct s2n_stuffer *in = &conn->handshake.io;
    struct s2n_blob ecdhparams;
    struct s2n_blob signature;
    uint16_t signature_length;

    /* Read server ECDH params and calculate their hash */
    GUARD(s2n_ecc_read_ecc_params(&conn->secure.server_ecc_params, in, &ecdhparams));

    GUARD(s2n_hash_init(&signature_hash, conn->secure.signature_digest_alg));

    if (conn->actual_protocol_version == S2N_TLS12) {
        uint8_t hash_algorithm;
        uint8_t signature_algorithm;

        GUARD(s2n_stuffer_read_uint8(in, &hash_algorithm));
        GUARD(s2n_stuffer_read_uint8(in, &signature_algorithm));

        if (signature_algorithm != TLS_SIGNATURE_ALGORITHM_RSA) {
            S2N_ERROR(S2N_ERR_BAD_MESSAGE);
        }

        switch(hash_algorithm) {
            case TLS_HASH_ALGORITHM_MD5:
                GUARD(s2n_hash_init(&signature_hash, S2N_HASH_MD5));
                break;
            case TLS_HASH_ALGORITHM_SHA1:
                GUARD(s2n_hash_init(&signature_hash, S2N_HASH_SHA1));
                break;
            case TLS_HASH_ALGORITHM_SHA224:
                GUARD(s2n_hash_init(&signature_hash, S2N_HASH_SHA224));
                break;
            case TLS_HASH_ALGORITHM_SHA256:
                GUARD(s2n_hash_init(&signature_hash, S2N_HASH_SHA256));
                break;
            case TLS_HASH_ALGORITHM_SHA384:
                GUARD(s2n_hash_init(&signature_hash, S2N_HASH_SHA384));
                break;
            case TLS_HASH_ALGORITHM_SHA512:
                GUARD(s2n_hash_init(&signature_hash, S2N_HASH_SHA512));
                break;
            default:
                S2N_ERROR(S2N_ERR_BAD_MESSAGE);
        }
    }

    GUARD(s2n_hash_update(&signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN));
    GUARD(s2n_hash_update(&signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN));
    GUARD(s2n_hash_update(&signature_hash, ecdhparams.data, ecdhparams.size));

    /* Verify the signature */
    GUARD(s2n_stuffer_read_uint16(in, &signature_length));
    signature.size = signature_length;
    signature.data = s2n_stuffer_raw_read(in, signature.size);
    notnull_check(signature.data);

    gt_check(signature_length, 0);

    if (s2n_rsa_verify(&conn->secure.server_rsa_public_key, &signature_hash, &signature) < 0) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }

    /* We don't need the key any more, so free it */
    GUARD(s2n_rsa_public_key_free(&conn->secure.server_rsa_public_key));

    return 0;
}