int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, const uint8_t *context, size_t context_len, int use_context) { if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) { return 0; } /* Exporters may not be used in the middle of a renegotiation. */ if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) { return 0; } if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { return tls13_export_keying_material(ssl, out, out_len, label, label_len, context, context_len, use_context); } size_t seed_len = 2 * SSL3_RANDOM_SIZE; if (use_context) { if (context_len >= 1u << 16) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return 0; } seed_len += 2 + context_len; } uint8_t *seed = OPENSSL_malloc(seed_len); if (seed == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_memcpy(seed, ssl->s3->client_random, SSL3_RANDOM_SIZE); OPENSSL_memcpy(seed + SSL3_RANDOM_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE); if (use_context) { seed[2 * SSL3_RANDOM_SIZE] = (uint8_t)(context_len >> 8); seed[2 * SSL3_RANDOM_SIZE + 1] = (uint8_t)context_len; OPENSSL_memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); } const EVP_MD *digest = ssl_get_handshake_digest( SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl)); if (digest == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } int ret = tls1_prf(digest, out, out_len, SSL_get_session(ssl)->master_key, SSL_get_session(ssl)->master_key_length, label, label_len, seed, seed_len, NULL, 0); OPENSSL_free(seed); return ret; }
int ssl_private_key_supports_signature_algorithm(SSL *ssl, uint16_t signature_algorithm) { const EVP_MD *md; if (is_rsa_pkcs1(&md, signature_algorithm) && ssl3_protocol_version(ssl) < TLS1_3_VERSION) { return ssl_private_key_type(ssl) == NID_rsaEncryption; } int curve; if (is_ecdsa(&curve, &md, signature_algorithm)) { int type = ssl_private_key_type(ssl); if (!ssl_is_ecdsa_key_type(type)) { return 0; } /* Prior to TLS 1.3, ECDSA curves did not match the signature algorithm. */ if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) { return 1; } return curve != NID_undef && type == curve; } if (is_rsa_pss(&md, signature_algorithm)) { if (ssl_private_key_type(ssl) != NID_rsaEncryption) { return 0; } /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the * hash in TLS. Reasonable RSA key sizes are large enough for the largest * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check * the size to fall back to another algorithm. */ if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) { return 0; } /* RSA-PSS is only supported by message-based private keys. */ if (ssl->cert->key_method != NULL && ssl->cert->key_method->sign == NULL) { return 0; } return 1; } return 0; }
static int ssl_verify_ecdsa(SSL *ssl, const uint8_t *signature, size_t signature_len, int curve, const EVP_MD *md, EVP_PKEY *pkey, const uint8_t *in, size_t in_len) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); if (ec_key == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* In TLS 1.3, the curve is also specified by the signature algorithm. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) && EVP_DigestVerifyUpdate(&md_ctx, in, in_len) && EVP_DigestVerifyFinal(&md_ctx, signature, signature_len); EVP_MD_CTX_cleanup(&md_ctx); return ret; }
static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, int curve, const EVP_MD *md, const uint8_t *in, size_t in_len) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey); if (ec_key == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* In TLS 1.3, the curve is also specified by the signature algorithm. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) && EVP_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
int tls1_change_cipher_state(SSL *ssl, int which) { /* Ensure the key block is set up. */ if (!tls1_setup_key_block(ssl)) { return 0; } /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we * need to update the read cipherspec. Otherwise we have just written one. */ const char is_read = (which & SSL3_CC_READ) != 0; /* use_client_keys is true if we wish to use the keys for the "client write" * direction. This is the case if we're a client sending a ChangeCipherSpec, * or a server reading a client's ChangeCipherSpec. */ const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE || which == SSL3_CHANGE_CIPHER_SERVER_READ; size_t mac_secret_len = ssl->s3->tmp.new_mac_secret_len; size_t key_len = ssl->s3->tmp.new_key_len; size_t iv_len = ssl->s3->tmp.new_fixed_iv_len; assert((mac_secret_len + key_len + iv_len) * 2 == ssl->s3->tmp.key_block_length); const uint8_t *key_data = ssl->s3->tmp.key_block; const uint8_t *client_write_mac_secret = key_data; key_data += mac_secret_len; const uint8_t *server_write_mac_secret = key_data; key_data += mac_secret_len; const uint8_t *client_write_key = key_data; key_data += key_len; const uint8_t *server_write_key = key_data; key_data += key_len; const uint8_t *client_write_iv = key_data; key_data += iv_len; const uint8_t *server_write_iv = key_data; key_data += iv_len; const uint8_t *mac_secret, *key, *iv; if (use_client_keys) { mac_secret = client_write_mac_secret; key = client_write_key; iv = client_write_iv; } else { mac_secret = server_write_mac_secret; key = server_write_key; iv = server_write_iv; } SSL_AEAD_CTX *aead_ctx = SSL_AEAD_CTX_new(is_read ? evp_aead_open : evp_aead_seal, ssl3_protocol_version(ssl), ssl->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv, iv_len); if (aead_ctx == NULL) { return 0; } if (is_read) { return ssl->method->set_read_state(ssl, aead_ctx); } return ssl->method->set_write_state(ssl, aead_ctx); }
int ssl3_cert_verify_hash(SSL *ssl, const EVP_MD **out_md, uint8_t *out, size_t *out_len, uint16_t signature_algorithm) { assert(ssl3_protocol_version(ssl) == SSL3_VERSION); if (signature_algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { if (ssl3_handshake_mac(ssl, NID_md5, NULL, 0, out) == 0 || ssl3_handshake_mac(ssl, NID_sha1, NULL, 0, out + MD5_DIGEST_LENGTH) == 0) { return 0; } *out_md = EVP_md5_sha1(); *out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; } else if (signature_algorithm == SSL_SIGN_ECDSA_SHA1) { if (ssl3_handshake_mac(ssl, NID_sha1, NULL, 0, out) == 0) { return 0; } *out_md = EVP_sha1(); *out_len = SHA_DIGEST_LENGTH; } else { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } return 1; }
int ssl_private_key_supports_signature_algorithm(SSL *ssl, uint16_t signature_algorithm) { const EVP_MD *md; if (is_rsa_pkcs1(&md, signature_algorithm)) { return ssl_private_key_type(ssl) == EVP_PKEY_RSA; } int curve; if (is_ecdsa(&curve, &md, signature_algorithm)) { if (ssl_private_key_type(ssl) != EVP_PKEY_EC) { return 0; } /* For non-custom keys, also check the curve matches. Custom private keys * must instead configure the signature algorithms accordingly. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && ssl->cert->key_method == NULL) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey); if (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve) { return 0; } } return 1; } if (is_rsa_pss(&md, signature_algorithm)) { if (ssl3_protocol_version(ssl) < TLS1_3_VERSION || ssl_private_key_type(ssl) != EVP_PKEY_RSA) { return 0; } /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the * hash in TLS. Reasonable RSA key sizes are large enough for the largest * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check * the size to fall back to another algorithm. */ if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) { return 0; } return 1; } return 0; }
/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and * handshake macs if required. */ uint32_t ssl_get_algorithm_prf(const SSL *ssl) { uint32_t algorithm_prf = ssl->s3->tmp.new_cipher->algorithm_prf; if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT && ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { return SSL_HANDSHAKE_MAC_SHA256; } return algorithm_prf; }
static int tls1_setup_key_block(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; if (hs->key_block_len != 0) { return 1; } SSL_SESSION *session = ssl->session; if (hs->new_session != NULL) { session = hs->new_session; } const EVP_AEAD *aead = NULL; size_t mac_secret_len, fixed_iv_len; if (session->cipher == NULL || !ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, session->cipher, ssl3_protocol_version(ssl), SSL_is_dtls(ssl))) { OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return 0; } size_t key_len = EVP_AEAD_key_length(aead); if (mac_secret_len > 0) { /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the * key length reported by |EVP_AEAD_key_length| will include the MAC key * bytes and initial implicit IV. */ if (key_len < mac_secret_len + fixed_iv_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } key_len -= mac_secret_len + fixed_iv_len; } assert(mac_secret_len < 256); assert(key_len < 256); assert(fixed_iv_len < 256); ssl->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; ssl->s3->tmp.new_key_len = (uint8_t)key_len; ssl->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; size_t key_block_len = SSL_get_key_block_len(ssl); uint8_t *keyblock = OPENSSL_malloc(key_block_len); if (keyblock == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } if (!SSL_generate_key_block(ssl, keyblock, key_block_len)) { OPENSSL_free(keyblock); return 0; } assert(key_block_len < 256); hs->key_block_len = (uint8_t)key_block_len; hs->key_block = keyblock; return 1; }
enum ssl_private_key_result_t ssl_private_key_sign( SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, uint16_t signature_algorithm, const uint8_t *in, size_t in_len) { if (ssl->cert->key_method != NULL) { if (ssl->cert->key_method->sign != NULL) { return ssl->cert->key_method->sign(ssl, out, out_len, max_out, signature_algorithm, in, in_len); } /* TODO(davidben): Remove support for |sign_digest|-only * |SSL_PRIVATE_KEY_METHOD|s. */ const EVP_MD *md; int curve; if (!is_rsa_pkcs1(&md, signature_algorithm) && !is_ecdsa(&curve, &md, signature_algorithm)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY); return ssl_private_key_failure; } uint8_t hash[EVP_MAX_MD_SIZE]; unsigned hash_len; if (!EVP_Digest(in, in_len, hash, &hash_len, md, NULL)) { return ssl_private_key_failure; } return ssl->cert->key_method->sign_digest(ssl, out, out_len, max_out, md, hash, hash_len); } const EVP_MD *md; if (is_rsa_pkcs1(&md, signature_algorithm) && ssl3_protocol_version(ssl) < TLS1_3_VERSION) { return ssl_sign_rsa_pkcs1(ssl, out, out_len, max_out, md, in, in_len) ? ssl_private_key_success : ssl_private_key_failure; } int curve; if (is_ecdsa(&curve, &md, signature_algorithm)) { return ssl_sign_ecdsa(ssl, out, out_len, max_out, curve, md, in, in_len) ? ssl_private_key_success : ssl_private_key_failure; } if (is_rsa_pss(&md, signature_algorithm)) { return ssl_sign_rsa_pss(ssl, out, out_len, max_out, md, in, in_len) ? ssl_private_key_success : ssl_private_key_failure; } OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return ssl_private_key_failure; }
int ssl3_read_app_data(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len, int peek) { assert(!SSL_in_init(ssl)); assert(ssl->s3->initial_handshake_complete); *out_got_handshake = 0; SSL3_RECORD *rr = &ssl->s3->rrec; for (;;) { /* A previous iteration may have read a partial handshake message. Do not * allow more app data in that case. */ int has_hs_data = ssl->init_buf != NULL && ssl->init_buf->length > 0; /* Get new packet if necessary. */ if (rr->length == 0 && !has_hs_data) { int ret = ssl3_get_record(ssl); if (ret <= 0) { return ret; } } if (has_hs_data || rr->type == SSL3_RT_HANDSHAKE) { /* Post-handshake data prior to TLS 1.3 is always renegotiation, which we * never accept as a server. Otherwise |ssl3_get_message| will send * |SSL_R_EXCESSIVE_MESSAGE_SIZE|. */ if (ssl->server && ssl3_protocol_version(ssl) < TLS1_3_VERSION) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); return -1; } /* Parse post-handshake handshake messages. */ int ret = ssl3_get_message(ssl, -1, ssl_dont_hash_message); if (ret <= 0) { return ret; } *out_got_handshake = 1; return -1; } if (rr->type != SSL3_RT_APPLICATION_DATA) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); return -1; } if (rr->length != 0) { return consume_record(ssl, buf, len, peek); } /* Discard empty records and loop again. */ } }
int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { if (ssl3_protocol_version(ssl) == SSL3_VERSION) { return ssl3_prf(out, out_len, SSL_get_session(ssl)->master_key, SSL_get_session(ssl)->master_key_length, TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE, ssl->s3->client_random, SSL3_RANDOM_SIZE); } const EVP_MD *digest = ssl_get_handshake_digest( SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl)); if (digest == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } return tls1_prf(digest, out, out_len, SSL_get_session(ssl)->master_key, SSL_get_session(ssl)->master_key_length, TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE, ssl->s3->client_random, SSL3_RANDOM_SIZE); }
enum ssl_private_key_result_t ssl_private_key_sign( SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, uint16_t signature_algorithm, const uint8_t *in, size_t in_len) { if (ssl->cert->key_method != NULL) { /* For now, custom private keys can only handle pre-TLS-1.3 signature * algorithms. * * TODO(davidben): Switch SSL_PRIVATE_KEY_METHOD to message-based APIs. */ const EVP_MD *md; int curve; if (!is_rsa_pkcs1(&md, signature_algorithm) && !is_ecdsa(&curve, &md, signature_algorithm)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY); return ssl_private_key_failure; } uint8_t hash[EVP_MAX_MD_SIZE]; unsigned hash_len; if (!EVP_Digest(in, in_len, hash, &hash_len, md, NULL)) { return ssl_private_key_failure; } return ssl->cert->key_method->sign(ssl, out, out_len, max_out, md, hash, hash_len); } const EVP_MD *md; if (is_rsa_pkcs1(&md, signature_algorithm)) { return ssl_sign_rsa_pkcs1(ssl, out, out_len, max_out, md, in, in_len) ? ssl_private_key_success : ssl_private_key_failure; } int curve; if (is_ecdsa(&curve, &md, signature_algorithm)) { return ssl_sign_ecdsa(ssl, out, out_len, max_out, curve, md, in, in_len) ? ssl_private_key_success : ssl_private_key_failure; } if (is_rsa_pss(&md, signature_algorithm) && ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { return ssl_sign_rsa_pss(ssl, out, out_len, max_out, md, in, in_len) ? ssl_private_key_success : ssl_private_key_failure; } OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return ssl_private_key_failure; }
static const SSL_CIPHER *choose_tls13_cipher( const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) { if (client_hello->cipher_suites_len % 2 != 0) { return NULL; } CBS cipher_suites; CBS_init(&cipher_suites, client_hello->cipher_suites, client_hello->cipher_suites_len); const int aes_is_fine = EVP_has_aes_hardware(); const uint16_t version = ssl3_protocol_version(ssl); const SSL_CIPHER *best = NULL; while (CBS_len(&cipher_suites) > 0) { uint16_t cipher_suite; if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { return NULL; } /* Limit to TLS 1.3 ciphers we know about. */ const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite); if (candidate == NULL || SSL_CIPHER_get_min_version(candidate) > version || SSL_CIPHER_get_max_version(candidate) < version) { continue; } /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer * ChaCha20 if we do not have AES hardware. */ if (aes_is_fine) { return candidate; } if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) { return candidate; } if (best == NULL) { best = candidate; } } return best; }
int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, const uint8_t *context, size_t context_len, int use_context) { if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) { return 0; } if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { return tls13_export_keying_material(ssl, out, out_len, label, label_len, context, context_len, use_context); } size_t seed_len = 2 * SSL3_RANDOM_SIZE; if (use_context) { if (context_len >= 1u << 16) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return 0; } seed_len += 2 + context_len; } uint8_t *seed = OPENSSL_malloc(seed_len); if (seed == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(seed, ssl->s3->client_random, SSL3_RANDOM_SIZE); memcpy(seed + SSL3_RANDOM_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE); if (use_context) { seed[2 * SSL3_RANDOM_SIZE] = (uint8_t)(context_len >> 8); seed[2 * SSL3_RANDOM_SIZE + 1] = (uint8_t)context_len; memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); } int ret = ssl->s3->enc_method->prf(ssl, out, out_len, SSL_get_session(ssl)->master_key, SSL_get_session(ssl)->master_key_length, label, label_len, seed, seed_len, NULL, 0); OPENSSL_free(seed); return ret; }
static int ssl3_can_renegotiate(SSL *ssl) { if (ssl->server || ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { return 0; } switch (ssl->renegotiate_mode) { case ssl_renegotiate_never: return 0; case ssl_renegotiate_once: return ssl->s3->total_renegotiations == 0; case ssl_renegotiate_freely: return 1; case ssl_renegotiate_ignore: return 1; } assert(0); return 0; }
int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, const CRYPTO_BUFFER *leaf) { SSL *const ssl = hs->ssl; assert(ssl3_protocol_version(ssl) < TLS1_3_VERSION); /* Check the certificate's type matches the cipher. */ if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE); return 0; } /* Check key usages for all key types but RSA. This is needed to distinguish * ECDH certificates, which we do not support, from ECDSA certificates. In * principle, we should check RSA key usages based on cipher, but this breaks * buggy antivirus deployments. Other key types are always used for signing. * * TODO(davidben): Get more recent data on RSA key usages. */ if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) { CBS leaf_cbs; CBS_init(&leaf_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf)); if (!ssl_cert_check_digital_signature_key_usage(&leaf_cbs)) { return 0; } } if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { /* Check the key's group and point format are acceptable. */ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); uint16_t group_id; if (!ssl_nid_to_group_id( &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) || !tls1_check_group_id(ssl, group_id) || EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT); return 0; } } return 1; }
int ssl3_cert_verify_hash(SSL *ssl, uint8_t *out, size_t *out_len, const EVP_MD **out_md, int pkey_type) { /* For TLS v1.2 send signature algorithm and signature using * agreed digest and cached handshake records. Otherwise, use * SHA1 or MD5 + SHA1 depending on key type. */ if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) { EVP_MD_CTX mctx; unsigned len; EVP_MD_CTX_init(&mctx); if (!EVP_DigestInit_ex(&mctx, *out_md, NULL) || !EVP_DigestUpdate(&mctx, ssl->s3->handshake_buffer->data, ssl->s3->handshake_buffer->length) || !EVP_DigestFinal(&mctx, out, &len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); EVP_MD_CTX_cleanup(&mctx); return 0; } *out_len = len; } else if (pkey_type == EVP_PKEY_RSA) { if (ssl->s3->enc_method->cert_verify_mac(ssl, NID_md5, out) == 0 || ssl->s3->enc_method->cert_verify_mac(ssl, NID_sha1, out + MD5_DIGEST_LENGTH) == 0) { return 0; } *out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; *out_md = EVP_md5_sha1(); } else if (pkey_type == EVP_PKEY_EC) { if (ssl->s3->enc_method->cert_verify_mac(ssl, NID_sha1, out) == 0) { return 0; } *out_len = SHA_DIGEST_LENGTH; *out_md = EVP_sha1(); } else { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } return 1; }
int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, const uint8_t *premaster, size_t premaster_len) { const SSL *ssl = hs->ssl; if (hs->extended_master_secret) { uint8_t digests[EVP_MAX_MD_SIZE]; size_t digests_len; if (!SSL_TRANSCRIPT_get_hash(&hs->transcript, digests, &digests_len) || !tls1_prf(SSL_TRANSCRIPT_md(&hs->transcript), out, SSL3_MASTER_SECRET_SIZE, premaster, premaster_len, TLS_MD_EXTENDED_MASTER_SECRET_CONST, TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests, digests_len, NULL, 0)) { return 0; } } else { if (ssl3_protocol_version(ssl) == SSL3_VERSION) { if (!ssl3_prf(out, SSL3_MASTER_SECRET_SIZE, premaster, premaster_len, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, ssl->s3->client_random, SSL3_RANDOM_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE)) { return 0; } } else { if (!tls1_prf(SSL_TRANSCRIPT_md(&hs->transcript), out, SSL3_MASTER_SECRET_SIZE, premaster, premaster_len, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, ssl->s3->client_random, SSL3_RANDOM_SIZE, ssl->s3->server_random, SSL3_RANDOM_SIZE)) { return 0; } } } return SSL3_MASTER_SECRET_SIZE; }
int ssl_public_key_verify(SSL *ssl, const uint8_t *signature, size_t signature_len, uint16_t signature_algorithm, EVP_PKEY *pkey, const uint8_t *in, size_t in_len) { const EVP_MD *md; if (is_rsa_pkcs1(&md, signature_algorithm) && ssl3_protocol_version(ssl) < TLS1_3_VERSION) { return ssl_verify_rsa_pkcs1(ssl, signature, signature_len, md, pkey, in, in_len); } int curve; if (is_ecdsa(&curve, &md, signature_algorithm)) { return ssl_verify_ecdsa(ssl, signature, signature_len, curve, md, pkey, in, in_len); } if (is_rsa_pss(&md, signature_algorithm)) { return ssl_verify_rsa_pss(ssl, signature, signature_len, md, pkey, in, in_len); } OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; }
static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) { if (!tls13_check_message_type(ssl, SSL3_MT_SERVER_HELLO)) { return ssl_hs_error; } CBS cbs, server_random, extensions; uint16_t server_wire_version; uint16_t cipher_suite; CBS_init(&cbs, ssl->init_msg, ssl->init_num); if (!CBS_get_u16(&cbs, &server_wire_version) || !CBS_get_bytes(&cbs, &server_random, SSL3_RANDOM_SIZE) || !CBS_get_u16(&cbs, &cipher_suite) || !CBS_get_u16_length_prefixed(&cbs, &extensions) || CBS_len(&cbs) != 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return ssl_hs_error; } if (server_wire_version != ssl->version) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); return ssl_hs_error; } /* Parse out the extensions. */ int have_key_share = 0; CBS key_share; while (CBS_len(&extensions) != 0) { uint16_t type; CBS extension; if (!CBS_get_u16(&extensions, &type) || !CBS_get_u16_length_prefixed(&extensions, &extension)) { OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } switch (type) { case TLSEXT_TYPE_key_share: if (have_key_share) { OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return ssl_hs_error; } key_share = extension; have_key_share = 1; break; default: OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); return ssl_hs_error; } } assert(ssl->s3->have_version); memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE); ssl->hit = 0; if (!ssl_get_new_session(ssl, 0)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); if (cipher == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return ssl_hs_error; } /* Check if the cipher is disabled. */ if ((cipher->algorithm_mkey & ssl->cert->mask_k) || (cipher->algorithm_auth & ssl->cert->mask_a) || SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) || SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) || !sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return ssl_hs_error; } ssl->session->cipher = cipher; ssl->s3->tmp.new_cipher = cipher; /* The PRF hash is now known. Set up the key schedule. */ static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; size_t hash_len = EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl))); if (!tls13_init_key_schedule(ssl, kZeroes, hash_len)) { return ssl_hs_error; } /* Resolve PSK and incorporate it into the secret. */ if (cipher->algorithm_auth == SSL_aPSK) { /* TODO(davidben): Support PSK. */ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return ssl_hs_error; } else if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) { return ssl_hs_error; } /* Resolve ECDHE and incorporate it into the secret. */ if (cipher->algorithm_mkey == SSL_kECDHE) { if (!have_key_share) { OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); return ssl_hs_error; } uint8_t *dhe_secret; size_t dhe_secret_len; uint8_t alert = SSL_AD_DECODE_ERROR; if (!ext_key_share_parse_serverhello(ssl, &dhe_secret, &dhe_secret_len, &alert, &key_share)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); return ssl_hs_error; } int ok = tls13_advance_key_schedule(ssl, dhe_secret, dhe_secret_len); OPENSSL_free(dhe_secret); if (!ok) { return ssl_hs_error; } } else { if (have_key_share) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); return ssl_hs_error; } if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) { return ssl_hs_error; } } /* If there was no HelloRetryRequest, the version negotiation logic has * already hashed the message. */ if (ssl->s3->hs->retry_group != 0 && !ssl->method->hash_current_message(ssl)) { return ssl_hs_error; } if (!tls13_set_handshake_traffic(ssl)) { return ssl_hs_error; } hs->state = state_process_encrypted_extensions; return ssl_hs_read_message; }
int tls13_set_traffic_key(SSL *ssl, enum tls_record_type_t type, enum evp_aead_direction_t direction, const uint8_t *traffic_secret, size_t traffic_secret_len) { if (traffic_secret_len > 0xff) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return 0; } const char *phase; switch (type) { case type_early_handshake: phase = "early handshake key expansion, "; break; case type_early_data: phase = "early application data key expansion, "; break; case type_handshake: phase = "handshake key expansion, "; break; case type_data: phase = "application data key expansion, "; break; default: return 0; } size_t phase_len = strlen(phase); const char *purpose = "client write key"; if ((ssl->server && direction == evp_aead_seal) || (!ssl->server && direction == evp_aead_open)) { purpose = "server write key"; } size_t purpose_len = strlen(purpose); /* The longest label has length 38 (type_early_data) + 16 (either purpose * value). */ uint8_t label[38 + 16]; size_t label_len = phase_len + purpose_len; if (label_len > sizeof(label)) { assert(0); return 0; } memcpy(label, phase, phase_len); memcpy(label + phase_len, purpose, purpose_len); /* Look up cipher suite properties. */ const EVP_AEAD *aead; const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)); size_t mac_secret_len, fixed_iv_len; if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, ssl->session->cipher, ssl3_protocol_version(ssl))) { return 0; } /* Derive the key. */ size_t key_len = EVP_AEAD_key_length(aead); uint8_t key[EVP_AEAD_MAX_KEY_LENGTH]; if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len, label, label_len, NULL, 0, key_len)) { return 0; } /* The IV's label ends in "iv" instead of "key". */ if (label_len < 3) { assert(0); return 0; } label_len--; label[label_len - 2] = 'i'; label[label_len - 1] = 'v'; /* Derive the IV. */ size_t iv_len = EVP_AEAD_nonce_length(aead); uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH]; if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len, label, label_len, NULL, 0, iv_len)) { return 0; } SSL_AEAD_CTX *traffic_aead = SSL_AEAD_CTX_new(direction, ssl3_protocol_version(ssl), ssl->session->cipher, key, key_len, NULL, 0, iv, iv_len); if (traffic_aead == NULL) { return 0; } if (direction == evp_aead_open) { if (!ssl->method->set_read_state(ssl, traffic_aead)) { return 0; } } else { if (!ssl->method->set_write_state(ssl, traffic_aead)) { return 0; } } /* Save the traffic secret. */ if (direction == evp_aead_open) { memcpy(ssl->s3->read_traffic_secret, traffic_secret, traffic_secret_len); ssl->s3->read_traffic_secret_len = traffic_secret_len; } else { memcpy(ssl->s3->write_traffic_secret, traffic_secret, traffic_secret_len); ssl->s3->write_traffic_secret_len = traffic_secret_len; } return 1; }
const SSL_CIPHER *ssl3_choose_cipher( SSL *ssl, const struct ssl_early_callback_ctx *client_hello, const struct ssl_cipher_preference_list_st *server_pref) { const SSL_CIPHER *c, *ret = NULL; STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow; int ok; size_t cipher_index; uint32_t alg_k, alg_a, mask_k, mask_a; /* in_group_flags will either be NULL, or will point to an array of bytes * which indicate equal-preference groups in the |prio| stack. See the * comment about |in_group_flags| in the |ssl_cipher_preference_list_st| * struct. */ const uint8_t *in_group_flags; /* group_min contains the minimal index so far found in a group, or -1 if no * such value exists yet. */ int group_min = -1; STACK_OF(SSL_CIPHER) *clnt = ssl_parse_client_cipher_list(client_hello); if (clnt == NULL) { return NULL; } if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { prio = srvr; in_group_flags = server_pref->in_group_flags; allow = clnt; } else { prio = clnt; in_group_flags = NULL; allow = srvr; } ssl_get_compatible_server_ciphers(ssl, &mask_k, &mask_a); for (size_t i = 0; i < sk_SSL_CIPHER_num(prio); i++) { c = sk_SSL_CIPHER_value(prio, i); ok = 1; /* Check the TLS version. */ if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) || SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl)) { ok = 0; } alg_k = c->algorithm_mkey; alg_a = c->algorithm_auth; ok = ok && (alg_k & mask_k) && (alg_a & mask_a); if (ok && sk_SSL_CIPHER_find(allow, &cipher_index, c)) { if (in_group_flags != NULL && in_group_flags[i] == 1) { /* This element of |prio| is in a group. Update the minimum index found * so far and continue looking. */ if (group_min == -1 || (size_t)group_min > cipher_index) { group_min = cipher_index; } } else { if (group_min != -1 && (size_t)group_min < cipher_index) { cipher_index = group_min; } ret = sk_SSL_CIPHER_value(allow, cipher_index); break; } } if (in_group_flags != NULL && in_group_flags[i] == 0 && group_min != -1) { /* We are about to leave a group, but we found a match in it, so that's * our answer. */ ret = sk_SSL_CIPHER_value(allow, group_min); break; } } sk_SSL_CIPHER_free(clnt); return ret; }
/* Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: * * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) * - SSL3_RT_APPLICATION_DATA (when ssl3_read_app_data calls us) * * If we don't have stored data to work from, read a SSL/TLS record first * (possibly multiple records if we still don't have anything to return). * * This function must handle any surprises the peer may have for us, such as * Alert records (e.g. close_notify) or renegotiation requests. */ int ssl3_read_bytes(SSL *ssl, int type, uint8_t *buf, int len, int peek) { int al, i, ret; unsigned int n; SSL3_RECORD *rr; if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) || (peek && type != SSL3_RT_APPLICATION_DATA)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } start: /* ssl->s3->rrec.type - is the type of record * ssl->s3->rrec.data - data * ssl->s3->rrec.off - offset into 'data' for next read * ssl->s3->rrec.length - number of bytes. */ rr = &ssl->s3->rrec; /* get new packet if necessary */ if (rr->length == 0) { ret = ssl3_get_record(ssl); if (ret <= 0) { return ret; } } /* we now have a packet which can be read and processed */ if (type == rr->type) { /* Discard empty records. */ if (rr->length == 0) { goto start; } if (len <= 0) { return len; } if ((unsigned int)len > rr->length) { n = rr->length; } else { n = (unsigned int)len; } memcpy(buf, rr->data, n); if (!peek) { rr->length -= n; rr->data += n; if (rr->length == 0) { /* The record has been consumed, so we may now clear the buffer. */ ssl_read_buffer_discard(ssl); } } return n; } /* Process unexpected records. */ if (type == SSL3_RT_APPLICATION_DATA && rr->type == SSL3_RT_HANDSHAKE) { if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) { /* TODO(svaldez): Handle TLS 1.3 post-handshake messages. For now, * silently drop all handshake records. */ rr->length = 0; goto start; } /* If peer renegotiations are disabled, all out-of-order handshake records * are fatal. Renegotiations as a server are never supported. */ if (ssl->server || !ssl3_can_renegotiate(ssl)) { al = SSL_AD_NO_RENEGOTIATION; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); goto f_err; } /* This must be a HelloRequest, possibly fragmented over multiple records. * Consume data from the handshake protocol until it is complete. */ static const uint8_t kHelloRequest[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0}; while (ssl->s3->hello_request_len < sizeof(kHelloRequest)) { if (rr->length == 0) { /* Get a new record. */ goto start; } if (rr->data[0] != kHelloRequest[ssl->s3->hello_request_len]) { al = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST); goto f_err; } rr->data++; rr->length--; ssl->s3->hello_request_len++; } ssl->s3->hello_request_len = 0; ssl_do_msg_callback(ssl, 0 /* read */, ssl->version, SSL3_RT_HANDSHAKE, kHelloRequest, sizeof(kHelloRequest)); if (ssl->renegotiate_mode == ssl_renegotiate_ignore) { goto start; } /* Renegotiation is only supported at quiescent points in the application * protocol, namely in HTTPS, just before reading the HTTP response. Require * the record-layer be idle and avoid complexities of sending a handshake * record while an application_data record is being written. */ if (ssl_write_buffer_is_pending(ssl)) { al = SSL_AD_NO_RENEGOTIATION; OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); goto f_err; } /* Begin a new handshake. */ ssl->s3->total_renegotiations++; ssl->state = SSL_ST_CONNECT; i = ssl->handshake_func(ssl); if (i < 0) { return i; } if (i == 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); return -1; } /* The handshake completed synchronously. Continue reading records. */ goto start; } al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); f_err: ssl3_send_alert(ssl, SSL3_AL_FATAL, al); return -1; }
int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server) { SSL *const ssl = hs->ssl; if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) { OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED); return 0; } SSL_SESSION *session = ssl_session_new(ssl->ctx->x509_method); if (session == NULL) { return 0; } session->is_server = is_server; session->ssl_version = ssl->version; /* Fill in the time from the |SSL_CTX|'s clock. */ struct OPENSSL_timeval now; ssl_get_current_time(ssl, &now); session->time = now.tv_sec; uint16_t version = ssl3_protocol_version(ssl); if (version >= TLS1_3_VERSION) { /* TLS 1.3 uses tickets as authenticators, so we are willing to use them for * longer. */ session->timeout = ssl->session_ctx->session_psk_dhe_timeout; session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT; } else { /* TLS 1.2 resumption does not incorporate new key material, so we use a * much shorter timeout. */ session->timeout = ssl->session_ctx->session_timeout; session->auth_timeout = ssl->session_ctx->session_timeout; } if (is_server) { if (hs->ticket_expected || version >= TLS1_3_VERSION) { /* Don't set session IDs for sessions resumed with tickets. This will keep * them out of the session cache. */ session->session_id_length = 0; } else { session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; if (!RAND_bytes(session->session_id, session->session_id_length)) { goto err; } } } else { session->session_id_length = 0; } if (ssl->cert->sid_ctx_length > sizeof(session->sid_ctx)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } OPENSSL_memcpy(session->sid_ctx, ssl->cert->sid_ctx, ssl->cert->sid_ctx_length); session->sid_ctx_length = ssl->cert->sid_ctx_length; /* The session is marked not resumable until it is completely filled in. */ session->not_resumable = 1; session->verify_result = X509_V_ERR_INVALID_CALL; SSL_SESSION_free(hs->new_session); hs->new_session = session; ssl_set_session(ssl, NULL); return 1; err: SSL_SESSION_free(session); return 0; }