Beispiel #1
0
static int s2n_check_p_g_dh_params(struct s2n_dh_params *dh_params)
{
    notnull_check(dh_params);
    notnull_check(dh_params->dh);

    const BIGNUM *p = s2n_get_p_dh_param(dh_params);
    const BIGNUM *g = s2n_get_g_dh_param(dh_params);

    notnull_check(g);
    notnull_check(p);

    if (DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    if (BN_is_zero(g)) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    if (BN_is_zero(p)) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    return 0;
}
Beispiel #2
0
int s2n_shutdown(struct s2n_connection *conn, s2n_blocked_status * more)
{
    notnull_check(conn);
    notnull_check(more);

    /* Treat this call as a no-op if already wiped */
    if (conn->send == NULL && conn->recv == NULL) {
        return 0;
    }

    uint64_t elapsed;
    GUARD(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
    S2N_ERROR_IF(elapsed < conn->delay, S2N_ERR_SHUTDOWN_PAUSED);

    /* Queue our close notify, once. Use warning level so clients don't give up */
    GUARD(s2n_queue_writer_close_alert_warning(conn));

    /* Write it */
    GUARD(s2n_flush(conn, more));

    /* Assume caller isn't interested in pending incoming data */
    if (conn->in_status == PLAINTEXT) {
        GUARD(s2n_stuffer_wipe(&conn->header_in));
        GUARD(s2n_stuffer_wipe(&conn->in));
        conn->in_status = ENCRYPTED;
    }

    /* Fails with S2N_ERR_SHUTDOWN_RECORD_TYPE or S2N_ERR_ALERT on receipt of anything but a close_notify */
    GUARD(s2n_recv_close_notify(conn, more));

    return 0;
}
Beispiel #3
0
int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key)
{
    uint16_t Yc_length;
    struct s2n_blob Yc;
    int shared_key_size;
    BIGNUM *pub_key;

    GUARD(s2n_check_all_dh_params(server_dh_params));

    GUARD(s2n_stuffer_read_uint16(Yc_in, &Yc_length));
    Yc.size = Yc_length;
    Yc.data = s2n_stuffer_raw_read(Yc_in, Yc.size);
    notnull_check(Yc.data);

    pub_key = BN_bin2bn((const unsigned char *)Yc.data, Yc.size, NULL);
    notnull_check(pub_key);
    GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh)));

    shared_key_size = DH_compute_key(shared_key->data, pub_key, server_dh_params->dh);
    if (shared_key_size <= 0) {
        BN_free(pub_key);
        S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
    }

    shared_key->size = shared_key_size;

    BN_free(pub_key);

    return 0;
}
Beispiel #4
0
int s2n_kem_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_kem_raw_server_params *kem_data = &raw_server_data->kem_data;
    struct s2n_stuffer *in = &conn->handshake.io;
    const struct s2n_kem *kem = conn->secure.s2n_kem_keys.negotiated_kem;
    kem_public_key_size key_length;

    /* Keep a copy to the start of the whole structure for the signature check */
    data_to_verify->data = s2n_stuffer_raw_read(in, 0);
    notnull_check(data_to_verify->data);

    /* the server sends the KEM ID again and this must match what was agreed upon during server hello */
    kem_extension_size kem_id;
    GUARD(s2n_stuffer_read_uint8(in, &kem_id));
    eq_check(kem_id, kem->kem_extension_id);

    GUARD(s2n_stuffer_read_uint16(in, &key_length));
    S2N_ERROR_IF(key_length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
    S2N_ERROR_IF(key_length != conn->secure.s2n_kem_keys.negotiated_kem->public_key_length, S2N_ERR_BAD_MESSAGE);

    kem_data->raw_public_key.data = s2n_stuffer_raw_read(in, key_length);
    notnull_check(kem_data->raw_public_key.data);
    kem_data->raw_public_key.size = key_length;

    data_to_verify->size = sizeof(kem_extension_size) + sizeof(kem_public_key_size) + key_length;

    return 0;
}
Beispiel #5
0
int s2n_rsa_public_encrypted_size(struct s2n_rsa_public_key *key)
{
    notnull_check(key->rsa);
    notnull_check(key->rsa->n);

    return RSA_size(key->rsa);
}
int s2n_x509_trust_store_add_pem(struct s2n_x509_trust_store *store, const char *pem)
{
    notnull_check(store);
    notnull_check(pem);

    if (!store->trust_store) {
        store->trust_store = X509_STORE_new();
    }

    DEFER_CLEANUP(struct s2n_stuffer pem_in_stuffer = {{0}}, s2n_stuffer_free);
    DEFER_CLEANUP(struct s2n_stuffer der_out_stuffer = {{0}}, s2n_stuffer_free);

    GUARD(s2n_stuffer_alloc_ro_from_string(&pem_in_stuffer, pem));
    GUARD(s2n_stuffer_growable_alloc(&der_out_stuffer, 2048));

    do {
        DEFER_CLEANUP(struct s2n_blob next_cert = {0}, s2n_free);

        GUARD(s2n_stuffer_certificate_from_pem(&pem_in_stuffer, &der_out_stuffer));
        GUARD(s2n_alloc(&next_cert, s2n_stuffer_data_available(&der_out_stuffer)));
        GUARD(s2n_stuffer_read(&der_out_stuffer, &next_cert));

        const uint8_t *data = next_cert.data;
        DEFER_CLEANUP(X509 *ca_cert = d2i_X509(NULL, &data, next_cert.size), X509_free_pointer);
        S2N_ERROR_IF(ca_cert == NULL, S2N_ERR_DECODE_CERTIFICATE);

        GUARD_OSSL(X509_STORE_add_cert(store->trust_store, ca_cert), S2N_ERR_DECODE_CERTIFICATE);
    } while (s2n_stuffer_data_available(&pem_in_stuffer));

    return 0;
}
Beispiel #7
0
int s2n_dhe_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;
    struct s2n_dhe_raw_server_points *dhe_data = &raw_server_data->dhe_data;

    uint16_t p_length;
    uint16_t g_length;
    uint16_t Ys_length;

    /* Keep a copy to the start of the whole structure for the signature check */
    data_to_verify->data = s2n_stuffer_raw_read(in, 0);
    notnull_check(data_to_verify->data);

    /* Read each of the three elements in */
    GUARD(s2n_stuffer_read_uint16(in, &p_length));
    dhe_data->p.size = p_length;
    dhe_data->p.data = s2n_stuffer_raw_read(in, p_length);
    notnull_check(dhe_data->p.data);

    GUARD(s2n_stuffer_read_uint16(in, &g_length));
    dhe_data->g.size = g_length;
    dhe_data->g.data = s2n_stuffer_raw_read(in, g_length);
    notnull_check(dhe_data->g.data);

    GUARD(s2n_stuffer_read_uint16(in, &Ys_length));
    dhe_data->Ys.size = Ys_length;
    dhe_data->Ys.data = s2n_stuffer_raw_read(in, Ys_length);
    notnull_check(dhe_data->Ys.data);

    /* Now we know the total size of the structure */
    data_to_verify->size = 2 + p_length + 2 + g_length + 2 + Ys_length;

    return 0;
}
Beispiel #8
0
static int s2n_rsa_modulus_check(RSA *rsa)
{
    /* RSA was made opaque starting in Openssl 1.1.0 */
    #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
        notnull_check(rsa->n);
    #else
        const BIGNUM *n = NULL;
        /* RSA still owns the memory for n */
        RSA_get0_key(rsa, &n, NULL, NULL);
        notnull_check(n);
    #endif

    return 0;
}
Beispiel #9
0
int s2n_kem_generate_keypair(struct s2n_kem_keypair *kem_keys)
{
    notnull_check(kem_keys);
    const struct s2n_kem *kem = kem_keys->negotiated_kem;
    notnull_check(kem->generate_keypair);

    eq_check(kem_keys->public_key.size, kem->public_key_length);
    notnull_check(kem_keys->public_key.data);

    /* The private key is needed for client_key_recv and must be saved */
    GUARD(s2n_alloc(&kem_keys->private_key, kem->private_key_length));

    GUARD(kem->generate_keypair(kem_keys->public_key.data, kem_keys->private_key.data));
    return 0;
}
Beispiel #10
0
int s2n_rsa_private_encrypted_size(struct s2n_rsa_private_key *key)
{
    notnull_check(key->rsa);
    GUARD(s2n_rsa_modulus_check(key->rsa));

    return RSA_size(key->rsa);
}
Beispiel #11
0
static int s2n_evp_hmac_p_hash_digest_init(struct s2n_prf_working_space *ws)
{
    notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.md);
    notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
    notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
 
    /* Ignore the MD5 check when in FIPS mode to comply with the TLS 1.0 RFC */
    if (s2n_is_in_fips_mode()) {
        GUARD(s2n_digest_allow_md5_for_fips(&ws->tls.p_hash.evp_hmac.evp_digest));
    }

    GUARD_OSSL(EVP_DigestSignInit(ws->tls.p_hash.evp_hmac.evp_digest.ctx, NULL, ws->tls.p_hash.evp_hmac.evp_digest.md, NULL, ws->tls.p_hash.evp_hmac.mac_key),
           S2N_ERR_P_HASH_INIT_FAILED);

    return 0;
}
Beispiel #12
0
static int s2n_evp_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
{
    /* Initialize the message digest */
    switch (alg) {
    case S2N_HMAC_SSLv3_MD5:
    case S2N_HMAC_MD5:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_md5();
        break;
    case S2N_HMAC_SSLv3_SHA1:
    case S2N_HMAC_SHA1:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha1();
        break;
    case S2N_HMAC_SHA224:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha224();
        break;
    case S2N_HMAC_SHA256:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha256();
        break;
    case S2N_HMAC_SHA384:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha384();
        break;
    case S2N_HMAC_SHA512:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha512();
        break;
    default:
        S2N_ERROR(S2N_ERR_P_HASH_INVALID_ALGORITHM);
    }

    /* Initialize the mac key using the provided secret */
    notnull_check(ws->tls.p_hash.evp_hmac.mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret->data, secret->size));

    /* Initialize the message digest context with the above message digest and mac key */
    return s2n_evp_hmac_p_hash_digest_init(ws);
}
Beispiel #13
0
int s2n_server_extensions_recv(struct s2n_connection *conn, struct s2n_blob *extensions)
{
    struct s2n_stuffer in;

    GUARD(s2n_stuffer_init(&in, extensions));
    GUARD(s2n_stuffer_write(&in, extensions));

    while (s2n_stuffer_data_available(&in)) {
        struct s2n_blob ext;
        uint16_t extension_type, extension_size;
        struct s2n_stuffer extension;

        GUARD(s2n_stuffer_read_uint16(&in, &extension_type));
        GUARD(s2n_stuffer_read_uint16(&in, &extension_size));

        ext.size = extension_size;
        ext.data = s2n_stuffer_raw_read(&in, ext.size);
        notnull_check(ext.data);

        GUARD(s2n_stuffer_init(&extension, &ext));
        GUARD(s2n_stuffer_write(&extension, &ext));

        switch (extension_type) {
        case TLS_EXTENSION_ALPN:
            GUARD(s2n_recv_server_alpn(conn, &extension));
            break;
        case TLS_EXTENSION_STATUS_REQUEST:
            GUARD(s2n_recv_server_status_request(conn, &extension));
            break;
        }
    }

    return 0;
}
Beispiel #14
0
int s2n_ecdsa_der_signature_size(const struct s2n_pkey *pkey)
{
    const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
    notnull_check(ecdsa_key->ec_key);

    return ECDSA_size(ecdsa_key->ec_key);
}
Beispiel #15
0
static int s2n_evp_hmac_p_hash_free(struct s2n_prf_working_space *ws)
{
    notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
    S2N_EVP_MD_CTX_FREE(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
    ws->tls.p_hash.evp_hmac.evp_digest.ctx = NULL;

    return 0;
}
Beispiel #16
0
int s2n_dh_params_free(struct s2n_dh_params *dh_params)
{
    notnull_check(dh_params);
    DH_free(dh_params->dh);
    dh_params->dh = NULL;

    return 0;
}
Beispiel #17
0
/* See http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html 2.5 */
int s2n_sslv2_client_hello_recv(struct s2n_connection *conn)
{
    struct s2n_stuffer *in = &conn->handshake.io;
    uint16_t session_id_length;
    uint16_t cipher_suites_length;
    uint16_t challenge_length;
    uint8_t *cipher_suites;

    if (conn->client_protocol_version < conn->config->cipher_preferences->minimum_protocol_version || conn->client_protocol_version > conn->server_protocol_version) {
        GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }
    conn->actual_protocol_version = MIN(conn->client_protocol_version, conn->server_protocol_version);
    conn->client_hello_version = S2N_SSLv2;

    /* We start 5 bytes into the record */
    GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));

    if (cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }

    GUARD(s2n_stuffer_read_uint16(in, &session_id_length));

    GUARD(s2n_stuffer_read_uint16(in, &challenge_length));

    if (challenge_length > S2N_TLS_RANDOM_DATA_LEN) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }

    cipher_suites = s2n_stuffer_raw_read(in, cipher_suites_length);
    notnull_check(cipher_suites);
    GUARD(s2n_set_cipher_as_sslv2_server(conn, cipher_suites, cipher_suites_length / S2N_SSLv2_CIPHER_SUITE_LEN));

    if (session_id_length > s2n_stuffer_data_available(in)) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }
    if (session_id_length > 0 && session_id_length <= S2N_TLS_SESSION_ID_MAX_LEN) {
        GUARD(s2n_stuffer_read_bytes(in, conn->session_id, session_id_length));
        conn->session_id_len = (uint8_t) session_id_length;
    } else {
        GUARD(s2n_stuffer_skip_read(in, session_id_length));
    }

    struct s2n_blob b;
    b.data = conn->secure.client_random;
    b.size = S2N_TLS_RANDOM_DATA_LEN;

    b.data += S2N_TLS_RANDOM_DATA_LEN - challenge_length;
    b.size -= S2N_TLS_RANDOM_DATA_LEN - challenge_length;

    GUARD(s2n_stuffer_read(in, &b));

    conn->server->chosen_cert_chain = conn->config->cert_and_key_pairs;
    GUARD(s2n_conn_set_handshake_type(conn));

    return 0;
}
Beispiel #18
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;
}
Beispiel #19
0
int s2n_config_set_cache_delete_callback(struct s2n_config *config, int (*cache_delete)(void *, const void *key, uint64_t key_size), void *data)
{
    notnull_check(cache_delete);

    config->cache_delete = cache_delete;
    config->cache_delete_data = data;

    return 0;
}
Beispiel #20
0
int s2n_config_set_cache_retrieve_callback(struct s2n_config *config, int (*cache_retrieve)(void *, const void *key, uint64_t key_size, void *value, uint64_t *value_size), void *data)
{
    notnull_check(cache_retrieve);

    config->cache_retrieve = cache_retrieve;
    config->cache_retrieve_data = data;

    return 0;
}
Beispiel #21
0
int s2n_kem_decapsulate(const struct s2n_kem_keypair *kem_keys, struct s2n_blob *shared_secret,
                        const struct s2n_blob *ciphertext)
{
    notnull_check(kem_keys);
    const struct s2n_kem *kem = kem_keys->negotiated_kem;
    notnull_check(kem->decapsulate);

    eq_check(kem_keys->private_key.size, kem->private_key_length);
    notnull_check(kem_keys->private_key.data);

    eq_check(ciphertext->size, kem->ciphertext_length);
    notnull_check(ciphertext->data);

    GUARD(s2n_alloc(shared_secret, kem_keys->negotiated_kem->shared_secret_key_length));

    GUARD(kem->decapsulate(shared_secret->data, ciphertext->data, kem_keys->private_key.data));
    return 0;
}
Beispiel #22
0
int s2n_client_extensions_recv(struct s2n_connection *conn, struct s2n_blob *extensions)
{
    struct s2n_stuffer in;

    GUARD(s2n_stuffer_init(&in, extensions));
    GUARD(s2n_stuffer_write(&in, extensions));

    while (s2n_stuffer_data_available(&in)) {
        struct s2n_blob ext;
        uint16_t extension_type, extension_size;
        struct s2n_stuffer extension;

        GUARD(s2n_stuffer_read_uint16(&in, &extension_type));
        GUARD(s2n_stuffer_read_uint16(&in, &extension_size));

        ext.size = extension_size;
        lte_check(extension_size, s2n_stuffer_data_available(&in));
        ext.data = s2n_stuffer_raw_read(&in, ext.size);
        notnull_check(ext.data);

        GUARD(s2n_stuffer_init(&extension, &ext));
        GUARD(s2n_stuffer_write(&extension, &ext));

        switch (extension_type) {
        case TLS_EXTENSION_SERVER_NAME:
            GUARD(s2n_recv_client_server_name(conn, &extension));
            break;
        case TLS_EXTENSION_SIGNATURE_ALGORITHMS:
            GUARD(s2n_recv_client_signature_algorithms(conn, &extension, &conn->secure.conn_hash_alg, &conn->secure.conn_sig_alg));
            break;
        case TLS_EXTENSION_ALPN:
            GUARD(s2n_recv_client_alpn(conn, &extension));
            break;
        case TLS_EXTENSION_STATUS_REQUEST:
            GUARD(s2n_recv_client_status_request(conn, &extension));
            break;
        case TLS_EXTENSION_ELLIPTIC_CURVES:
            GUARD(s2n_recv_client_elliptic_curves(conn, &extension));
            break;
        case TLS_EXTENSION_EC_POINT_FORMATS:
            GUARD(s2n_recv_client_ec_point_formats(conn, &extension));
            break;
        case TLS_EXTENSION_RENEGOTIATION_INFO:
            GUARD(s2n_recv_client_renegotiation_info(conn, &extension));
            break;
        case TLS_EXTENSION_SCT_LIST:
            GUARD(s2n_recv_client_sct_list(conn, &extension));
            break;
        case TLS_EXTENSION_MAX_FRAG_LEN:
            GUARD(s2n_recv_client_max_frag_len(conn, &extension));
            break;
        }
    }

    return 0;
}
Beispiel #23
0
int s2n_x509_validator_set_max_chain_depth(struct s2n_x509_validator *validator, uint16_t max_depth) {
    notnull_check(validator);

    if (max_depth > 0) {
        validator->max_chain_depth = max_depth;
        return 0;
    }

    return -1;
}
Beispiel #24
0
int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *out, struct s2n_blob *output)
{
    GUARD(s2n_check_all_dh_params(server_dh_params));

    const BIGNUM *bn_p = s2n_get_p_dh_param(server_dh_params);
    const BIGNUM *bn_g = s2n_get_g_dh_param(server_dh_params);
    const BIGNUM *bn_Ys = s2n_get_Ys_dh_param(server_dh_params);

    uint16_t p_size = BN_num_bytes(bn_p);
    uint16_t g_size = BN_num_bytes(bn_g);
    uint16_t Ys_size = BN_num_bytes(bn_Ys);
    uint8_t *p;
    uint8_t *g;
    uint8_t *Ys;

    output->data = s2n_stuffer_raw_write(out, 0);
    notnull_check(output->data);

    GUARD(s2n_stuffer_write_uint16(out, p_size));
    p = s2n_stuffer_raw_write(out, p_size);
    notnull_check(p);
    if (BN_bn2bin(bn_p, p) != p_size) {
        S2N_ERROR(S2N_ERR_DH_SERIALIZING);
    }

    GUARD(s2n_stuffer_write_uint16(out, g_size));
    g = s2n_stuffer_raw_write(out, g_size);
    notnull_check(g);
    if (BN_bn2bin(bn_g, g) != g_size) {
        S2N_ERROR(S2N_ERR_DH_SERIALIZING);
    }

    GUARD(s2n_stuffer_write_uint16(out, Ys_size));
    Ys = s2n_stuffer_raw_write(out, Ys_size);
    notnull_check(Ys);
    if (BN_bn2bin(bn_Ys, Ys) != Ys_size) {
        S2N_ERROR(S2N_ERR_DH_SERIALIZING);
    }

    output->size = p_size + 2 + g_size + 2 + Ys_size + 2;

    return 0;
}
Beispiel #25
0
int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t *data, uint32_t size)
{
    GUARD(s2n_stuffer_skip_read(stuffer, size));

    void *ptr = stuffer->blob.data + stuffer->read_cursor - size;
    notnull_check(ptr);

    memcpy_check(data, ptr, size);

    return 0;
}
Beispiel #26
0
static int s2n_check_pub_key_dh_params(struct s2n_dh_params *dh_params)
{
    const BIGNUM *pub_key = s2n_get_Ys_dh_param(dh_params);

    notnull_check(pub_key);

    if (BN_is_zero(pub_key)) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    return 0;
}
Beispiel #27
0
static int s2n_evp_hmac_p_hash_cleanup(struct s2n_prf_working_space *ws)
{
    /* Prepare the workspace md_ctx for the next p_hash */
    GUARD(s2n_evp_hmac_p_hash_wipe(ws));

    /* Free mac key - PKEYs cannot be reused */
    notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
    EVP_PKEY_free(ws->tls.p_hash.evp_hmac.mac_key);
    ws->tls.p_hash.evp_hmac.mac_key = NULL;

    return 0;
}
Beispiel #28
0
int s2n_kem_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
{
    struct s2n_stuffer *out = &conn->handshake.io;
    const struct s2n_kem *kem = conn->secure.s2n_kem_keys.negotiated_kem;

    data_to_sign->data = s2n_stuffer_raw_write(out, 0);
    notnull_check(data_to_sign->data);

    GUARD(s2n_stuffer_write_uint8(out, kem->kem_extension_id));
    GUARD(s2n_stuffer_write_uint16(out, kem->public_key_length));

    /* The public key is not needed after this method, write it straight to the stuffer */
    struct s2n_blob *public_key = &conn->secure.s2n_kem_keys.public_key;
    public_key->data = s2n_stuffer_raw_write(out, kem->public_key_length);
    notnull_check(public_key->data);
    public_key->size = kem->public_key_length;

    GUARD(s2n_kem_generate_keypair(&conn->secure.s2n_kem_keys));

    data_to_sign->size = sizeof(kem_extension_size) + sizeof(kem_public_key_size) +  public_key->size;

    return 0;
}
Beispiel #29
0
int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN])
{
    /* See if the cipher is one we support */
    conn->secure.cipher_suite = s2n_cipher_suite_from_wire(wire);
    S2N_ERROR_IF(conn->secure.cipher_suite == NULL, S2N_ERR_CIPHER_NOT_SUPPORTED);

    /* For SSLv3 use SSLv3-specific ciphers */
    if (conn->actual_protocol_version == S2N_SSLv3) {
        conn->secure.cipher_suite = conn->secure.cipher_suite->sslv3_cipher_suite;
        notnull_check(conn->secure.cipher_suite);
    }

    return 0;
}
Beispiel #30
0
int s2n_x509_validator_init(struct s2n_x509_validator *validator, struct s2n_x509_trust_store *trust_store, uint8_t check_ocsp) {
    notnull_check(trust_store);
    validator->trust_store = trust_store;

    validator->skip_cert_validation = 0;
    validator->check_stapled_ocsp = check_ocsp;
    validator->max_chain_depth = DEFAULT_MAX_CHAIN_DEPTH;

    validator->cert_chain = NULL;
    if (validator->trust_store->trust_store) {
        validator->cert_chain = sk_X509_new_null();
    }

    return 0;
}