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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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); }
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; }
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); }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }