-/* ssl/statem/statem_srvr.c -*- mode:C; c-file-style: "eay" -*- */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* 1: Success (transition allowed)
* 0: Error (transition not allowed)
*/
-int server_read_transition(SSL *s, int mt)
+int ossl_statem_server_read_transition(SSL *s, int mt)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case TLS_ST_BEFORE:
* 1: Yes
* 0: No
*/
-static inline int send_server_key_exchange(SSL *s)
+static int send_server_key_exchange(SSL *s)
{
unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
/*
- * only send a ServerKeyExchange if DH, fortezza or RSA but we have a
+ * only send a ServerKeyExchange if DH or fortezza but we have a
* sign only certificate PSK: may send PSK identity hints For
* ECC ciphersuites, we send a serverKeyExchange message only if
* the cipher suite is either ECDH-anon or ECDHE. In other cases,
* the server certificate contains the server's public key for
* key exchange.
*/
- if ( (alg_k & SSL_kDHE)
- || (alg_k & SSL_kECDHE)
- || ((alg_k & SSL_kRSA)
- && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
- || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
- && EVP_PKEY_size(s->cert->pkeys
- [SSL_PKEY_RSA_ENC].privatekey) *
- 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
- )
- )
- )
+ if (alg_k & (SSL_kDHE|SSL_kECDHE)
/*
* PSK: send ServerKeyExchange if PSK identity hint if
* provided
* 1: Yes
* 0: No
*/
-static inline int send_certificate_request(SSL *s)
+static int send_certificate_request(SSL *s)
{
if (
/* don't request cert unless asked for it: */
* With normal PSK Certificates and Certificate Requests
* are omitted
*/
- && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) {
+ && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)) {
return 1;
}
* server_write_transition() works out what handshake state to move to next
* when the server is writing messages to be sent to the client.
*/
-enum WRITE_TRAN server_write_transition(SSL *s)
+WRITE_TRAN ossl_statem_server_write_transition(SSL *s)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case TLS_ST_BEFORE:
* Perform any pre work that needs to be done prior to sending a message from
* the server to the client.
*/
-enum WORK_STATE server_pre_work(SSL *s, enum WORK_STATE wst)
+WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case TLS_ST_SW_HELLO_REQ:
* Perform any work that needs to be done after sending a message from the
* server to the client.
*/
-enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst)
+WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
s->init_num = 0;
* Add new shared key for SCTP-Auth, will be ignored if no
* SCTP used.
*/
- snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
- DTLS1_SCTP_AUTH_LABEL);
+ memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
+ sizeof(DTLS1_SCTP_AUTH_LABEL));
if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
* 1: Success
* 0: Error
*/
-int server_construct_message(SSL *s)
+int ossl_statem_server_construct_message(SSL *s)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
* Returns the maximum allowed length for the current message that we are
* reading. Excludes the message header.
*/
-unsigned long server_max_message_size(SSL *s)
+unsigned long ossl_statem_server_max_message_size(SSL *s)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case TLS_ST_SR_CLNT_HELLO:
/*
* Process a message that the server has received from the client.
*/
-enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt)
+MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case TLS_ST_SR_CLNT_HELLO:
* Perform any further processing required following the receipt of a message
* from the client
*/
-enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst)
+WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst)
{
- STATEM *st = &s->statem;
+ OSSL_STATEM *st = &s->statem;
switch(st->hand_state) {
case TLS_ST_SR_CLNT_HELLO:
s->rwstate = SSL_READING;
BIO_clear_retry_flags(SSL_get_rbio(s));
BIO_set_retry_read(SSL_get_rbio(s));
- statem_set_sctp_read_sock(s, 1);
+ ossl_statem_set_sctp_read_sock(s, 1);
return WORK_MORE_A;
} else {
- ossl_ossl_statem_set_sctp_read_sock(s, 0);
+ ossl_statem_set_sctp_read_sock(s, 0);
}
#endif
return WORK_FINISHED_CONTINUE;
-
- case TLS_ST_SR_FINISHED:
- if (s->hit)
- return tls_finish_handshake(s, wst);
- else
- return WORK_FINISHED_STOP;
default:
break;
}
s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
&(s->d1->cookie_len)) == 0 ||
s->d1->cookie_len > 255) {
- SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,
+ SSLerr(SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST,
SSL_R_COOKIE_GEN_CALLBACK_FAILURE);
ossl_statem_set_error(s);
return 0;
return 1;
}
-enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
+MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
{
int i, al = SSL_AD_INTERNAL_ERROR;
unsigned int j, complen = 0;
unsigned long id;
- SSL_CIPHER *c;
+ const SSL_CIPHER *c;
#ifndef OPENSSL_NO_COMP
SSL_COMP *comp = NULL;
#endif
STACK_OF(SSL_CIPHER) *ciphers = NULL;
- int protverr = 1;
+ int protverr;
/* |cookie| will only be initialized for DTLS. */
PACKET session_id, cipher_suites, compression, extensions, cookie;
int is_v2_record;
}
}
- /* Do SSL/TLS version negotiation if applicable */
+ /*
+ * Do SSL/TLS version negotiation if applicable. For DTLS we just check
+ * versions are potentially compatible. Version negotiation comes later.
+ */
if (!SSL_IS_DTLS(s)) {
- if (s->version != TLS_ANY_VERSION) {
- if (s->client_version >= s->version) {
- protverr = 0;
- }
- } else if (s->client_version >= SSL3_VERSION) {
- switch(s->client_version) {
- default:
- case TLS1_2_VERSION:
- if(!(s->options & SSL_OP_NO_TLSv1_2)) {
- s->version = TLS1_2_VERSION;
- s->method = TLSv1_2_server_method();
- protverr = 0;
- break;
- }
- /* Deliberately fall through */
- case TLS1_1_VERSION:
- if(!(s->options & SSL_OP_NO_TLSv1_1)) {
- s->version = TLS1_1_VERSION;
- s->method = TLSv1_1_server_method();
- protverr = 0;
- break;
- }
- /* Deliberately fall through */
- case TLS1_VERSION:
- if(!(s->options & SSL_OP_NO_TLSv1)) {
- s->version = TLS1_VERSION;
- s->method = TLSv1_server_method();
- protverr = 0;
- break;
- }
- /* Deliberately fall through */
- case SSL3_VERSION:
-#ifndef OPENSSL_NO_SSL3
- if(!(s->options & SSL_OP_NO_SSLv3)) {
- s->version = SSL3_VERSION;
- s->method = SSLv3_server_method();
- protverr = 0;
- break;
- }
-#else
- break;
-#endif
- }
- }
- } else if (s->client_version <= s->version
- || s->method->version == DTLS_ANY_VERSION) {
- /*
- * For DTLS we just check versions are potentially compatible. Version
- * negotiation comes later.
- */
+ protverr = ssl_choose_server_version(s);
+ } else if (s->method->version != DTLS_ANY_VERSION &&
+ DTLS_VERSION_LT(s->client_version, s->version)) {
+ protverr = SSL_R_VERSION_TOO_LOW;
+ } else {
protverr = 0;
}
if (protverr) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr);
if ((!s->enc_write_ctx && !s->write_hash)) {
/*
* similar to ssl3_get_record, send alert using remote version
goto f_err;
}
+ if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+
if (!PACKET_get_sub_packet(pkt, &cipher_suites, cipher_len)
|| !PACKET_get_sub_packet(pkt, &session_id, session_id_len)
|| !PACKET_get_sub_packet(pkt, &challenge, challenge_len)
/* No extensions. */
|| PACKET_remaining(pkt) != 0) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+ SSL_R_RECORD_LENGTH_MISMATCH);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
if (!PACKET_copy_bytes(&challenge,
s->s3->client_random + SSL3_RANDOM_SIZE -
challenge_len, challenge_len)) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
if (!PACKET_copy_bytes(pkt, s->s3->client_random, SSL3_RANDOM_SIZE)
|| !PACKET_get_length_prefixed_1(pkt, &session_id)) {
al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+
+ if (PACKET_remaining(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
if (SSL_IS_DTLS(s)) {
if (!PACKET_get_length_prefixed_1(pkt, &cookie)) {
al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
/*
if (!PACKET_get_length_prefixed_2(pkt, &cipher_suites)
|| !PACKET_get_length_prefixed_1(pkt, &compression)) {
al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
/* Could be empty. */
if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookie),
PACKET_remaining(&cookie)) == 0) {
al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
SSL_R_COOKIE_MISMATCH);
goto f_err;
/* else cookie verification succeeded */
} else if (!PACKET_equal(&cookie, s->d1->cookie,
s->d1->cookie_len)) {
al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
goto f_err;
}
s->d1->cookie_verified = 1;
}
if (s->method->version == DTLS_ANY_VERSION) {
- /* Select version to use */
- if (s->client_version <= DTLS1_2_VERSION &&
- !(s->options & SSL_OP_NO_DTLSv1_2)) {
- s->version = DTLS1_2_VERSION;
- s->method = DTLSv1_2_server_method();
- } else if (tls1_suiteb(s)) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
- SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
- s->version = s->client_version;
- al = SSL_AD_PROTOCOL_VERSION;
- goto f_err;
- } else if (s->client_version <= DTLS1_VERSION &&
- !(s->options & SSL_OP_NO_DTLSv1)) {
- s->version = DTLS1_VERSION;
- s->method = DTLSv1_server_method();
- } else {
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
- SSL_R_WRONG_VERSION_NUMBER);
+ protverr = ssl_choose_server_version(s);
+ if (protverr != 0) {
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr);
s->version = s->client_version;
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
* to reuse it
*/
al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
SSL_R_REQUIRED_CIPHER_MISSING);
goto f_err;
}
if (j >= complen) {
/* no compress */
al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
goto f_err;
}
/* TLS extensions */
if (s->version >= SSL3_VERSION) {
if (!ssl_parse_clienthello_tlsext(s, &extensions)) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
goto err;
}
}
}
if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) {
- SSL_CIPHER *pref_cipher = NULL;
+ const SSL_CIPHER *pref_cipher = NULL;
s->session->master_key_length = sizeof(s->session->master_key);
if (s->tls_session_secret_cb(s, s->session->master_key,
}
-enum WORK_STATE tls_post_process_client_hello(SSL *s, enum WORK_STATE wst)
+WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
{
- int al;
- SSL_CIPHER *cipher;
+ int al = SSL_AD_HANDSHAKE_FAILURE;
+ const SSL_CIPHER *cipher;
if (wst == WORK_MORE_A) {
if (!s->hit) {
cipher = ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
if (cipher == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
s->s3->tmp.new_cipher = s->session->cipher;
}
- if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) {
- if (!ssl3_digest_cached_records(s, 0))
+ if (!(s->verify_mode & SSL_VERIFY_PEER)) {
+ if (!ssl3_digest_cached_records(s, 0)) {
+ al = SSL_AD_INTERNAL_ERROR;
goto f_err;
+ }
}
/*-
/* Handles TLS extensions that we couldn't check earlier */
if (s->version >= SSL3_VERSION) {
if (ssl_check_clienthello_tlsext_late(s) <= 0) {
- SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+ SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_CLIENTHELLO_TLSEXT);
goto f_err;
}
}
int tls_construct_server_key_exchange(SSL *s)
{
-#ifndef OPENSSL_NO_RSA
- unsigned char *q;
- int j, num;
- RSA *rsa;
- unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
- unsigned int u;
-#endif
#ifndef OPENSSL_NO_DH
- DH *dh = NULL, *dhp;
+ EVP_PKEY *pkdh = NULL;
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY *ecdh = NULL, *ecdhp;
unsigned char *encodedPoint = NULL;
int encodedlen = 0;
int curve_id = 0;
- BN_CTX *bn_ctx = NULL;
#endif
EVP_PKEY *pkey;
const EVP_MD *md = NULL;
int al, i;
unsigned long type;
int n;
- CERT *cert;
BIGNUM *r[4];
int nr[4], kn;
BUF_MEM *buf;
- EVP_MD_CTX md_ctx;
+ EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
- EVP_MD_CTX_init(&md_ctx);
+ if (md_ctx == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
type = s->s3->tmp.new_cipher->algorithm_mkey;
- cert = s->cert;
buf = s->init_buf;
if (type & (SSL_kPSK | SSL_kRSAPSK)) {
} else
#endif /* !OPENSSL_NO_PSK */
-#ifndef OPENSSL_NO_RSA
- if (type & SSL_kRSA) {
- rsa = cert->rsa_tmp;
- if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) {
- rsa = s->cert->rsa_tmp_cb(s,
- SSL_C_IS_EXPORT(s->s3->
- tmp.new_cipher),
- SSL_C_EXPORT_PKEYLENGTH(s->s3->
- tmp.new_cipher));
- if (rsa == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
+#ifndef OPENSSL_NO_DH
+ if (type & (SSL_kDHE | SSL_kDHEPSK)) {
+ CERT *cert = s->cert;
+
+ EVP_PKEY *pkdhp = NULL;
+ DH *dh;
+
+ if (s->cert->dh_tmp_auto) {
+ DH *dhp = ssl_get_auto_dh(s);
+ pkdh = EVP_PKEY_new();
+ if (pkdh == NULL || dhp == NULL) {
+ DH_free(dhp);
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
- SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
+ ERR_R_INTERNAL_ERROR);
goto f_err;
}
- RSA_up_ref(rsa);
- cert->rsa_tmp = rsa;
- }
- if (rsa == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
- SSL_R_MISSING_TMP_RSA_KEY);
- goto f_err;
+ EVP_PKEY_assign_DH(pkdh, dhp);
+ pkdhp = pkdh;
+ } else {
+ pkdhp = cert->dh_tmp;
}
- r[0] = rsa->n;
- r[1] = rsa->e;
- s->s3->tmp.use_rsa_tmp = 1;
- } else
-#endif
-#ifndef OPENSSL_NO_DH
- if (type & (SSL_kDHE | SSL_kDHEPSK)) {
- if (s->cert->dh_tmp_auto) {
- dhp = ssl_get_auto_dh(s);
- if (dhp == NULL) {
+ if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) {
+ DH *dhp = s->cert->dh_tmp_cb(s, 0, 1024);
+ pkdh = ssl_dh_to_pkey(dhp);
+ if (pkdh == NULL) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto f_err;
}
- } else
- dhp = cert->dh_tmp;
- if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
- dhp = s->cert->dh_tmp_cb(s,
- SSL_C_IS_EXPORT(s->s3->
- tmp.new_cipher),
- SSL_C_EXPORT_PKEYLENGTH(s->s3->
- tmp.new_cipher));
- if (dhp == NULL) {
+ pkdhp = pkdh;
+ }
+ if (pkdhp == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
}
if (!ssl_security(s, SSL_SECOP_TMP_DH,
- DH_security_bits(dhp), 0, dhp)) {
+ EVP_PKEY_security_bits(pkdhp), 0, pkdhp)) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_DH_KEY_TOO_SMALL);
goto f_err;
}
- if (s->s3->tmp.dh != NULL) {
+ if (s->s3->tmp.pkey != NULL) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto err;
}
- if (s->cert->dh_tmp_auto)
- dh = dhp;
- else if ((dh = DHparams_dup(dhp)) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
+ s->s3->tmp.pkey = ssl_generate_pkey(pkdhp, NID_undef);
+
+ if (s->s3->tmp.pkey == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EVP_LIB);
goto err;
}
- s->s3->tmp.dh = dh;
- if ((dhp->pub_key == NULL ||
- dhp->priv_key == NULL ||
- (s->options & SSL_OP_SINGLE_DH_USE))) {
- if (!DH_generate_key(dh)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
- goto err;
- }
- } else {
- dh->pub_key = BN_dup(dhp->pub_key);
- dh->priv_key = BN_dup(dhp->priv_key);
- if ((dh->pub_key == NULL) || (dh->priv_key == NULL)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
- goto err;
- }
- }
+ dh = EVP_PKEY_get0_DH(s->s3->tmp.pkey);
+
+ EVP_PKEY_free(pkdh);
+ pkdh = NULL;
+
r[0] = dh->p;
r[1] = dh->g;
r[2] = dh->pub_key;
#endif
#ifndef OPENSSL_NO_EC
if (type & (SSL_kECDHE | SSL_kECDHEPSK)) {
- const EC_GROUP *group;
-
- ecdhp = cert->ecdh_tmp;
- if (s->cert->ecdh_tmp_auto) {
- /* Get NID of appropriate shared curve */
- int nid = tls1_shared_curve(s, -2);
- if (nid != NID_undef)
- ecdhp = EC_KEY_new_by_curve_name(nid);
- } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) {
- ecdhp = s->cert->ecdh_tmp_cb(s,
- SSL_C_IS_EXPORT(s->s3->
- tmp.new_cipher),
- SSL_C_EXPORT_PKEYLENGTH(s->
- s3->tmp.new_cipher));
- }
- if (ecdhp == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
- SSL_R_MISSING_TMP_ECDH_KEY);
- goto f_err;
- }
+ int nid;
- if (s->s3->tmp.ecdh != NULL) {
+ if (s->s3->tmp.pkey != NULL) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto err;
}
- /* Duplicate the ECDH structure. */
- if (ecdhp == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
- if (s->cert->ecdh_tmp_auto)
- ecdh = ecdhp;
- else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
-
- s->s3->tmp.ecdh = ecdh;
- if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
- (EC_KEY_get0_private_key(ecdh) == NULL) ||
- (s->options & SSL_OP_SINGLE_ECDH_USE)) {
- if (!EC_KEY_generate_key(ecdh)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
- ERR_R_ECDH_LIB);
- goto err;
- }
- }
-
- if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
- (EC_KEY_get0_public_key(ecdh) == NULL) ||
- (EC_KEY_get0_private_key(ecdh) == NULL)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
-
- if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
- (EC_GROUP_get_degree(group) > 163)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
- SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
- goto err;
- }
-
- /*
- * XXX: For now, we only support ephemeral ECDH keys over named
- * (not generic) curves. For supported named curves, curve_id is
- * non-zero.
- */
- if ((curve_id =
- tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
- == 0) {
+ /* Get NID of appropriate shared curve */
+ nid = tls1_shared_curve(s, -2);
+ curve_id = tls1_ec_nid2curve_id(nid);
+ if (curve_id == 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
goto err;
}
-
- /*
- * Encode the public key. First check the size of encoding and
- * allocate memory accordingly.
- */
- encodedlen = EC_POINT_point2oct(group,
- EC_KEY_get0_public_key(ecdh),
- POINT_CONVERSION_UNCOMPRESSED,
- NULL, 0, NULL);
-
- encodedPoint = (unsigned char *)
- OPENSSL_malloc(encodedlen * sizeof(unsigned char));
- bn_ctx = BN_CTX_new();
- if ((encodedPoint == NULL) || (bn_ctx == NULL)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
- ERR_R_MALLOC_FAILURE);
- goto err;
+ s->s3->tmp.pkey = ssl_generate_pkey(NULL, nid);
+ /* Generate a new key for this curve */
+ if (s->s3->tmp.pkey == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto f_err;
}
- encodedlen = EC_POINT_point2oct(group,
- EC_KEY_get0_public_key(ecdh),
- POINT_CONVERSION_UNCOMPRESSED,
- encodedPoint, encodedlen, bn_ctx);
+ /* Encode the public key. */
+ encodedlen = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(s->s3->tmp.pkey),
+ POINT_CONVERSION_UNCOMPRESSED,
+ &encodedPoint, NULL);
if (encodedlen == 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EC_LIB);
goto err;
}
- BN_CTX_free(bn_ctx);
- bn_ctx = NULL;
-
/*
- * XXX: For now, we only support named (not generic) curves in
- * ECDH ephemeral key exchanges. In this situation, we need four
- * additional bytes to encode the entire ServerECDHParams
- * structure.
+ * We only support named (not generic) curves in ECDH ephemeral key
+ * exchanges. In this situation, we need four additional bytes to
+ * encode the entire ServerECDHParams structure.
*/
n += 4 + encodedlen;
* n is the length of the params, they start at &(d[4]) and p
* points to the space at the end.
*/
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) {
- q = md_buf;
- j = 0;
- for (num = 2; num > 0; num--) {
- EVP_MD_CTX_set_flags(&md_ctx,
- EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- EVP_DigestInit_ex(&md_ctx, (num == 2)
- ? s->ctx->md5 : s->ctx->sha1, NULL);
- EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, d, n);
- EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
- q += i;
- j += i;
- }
- if (RSA_sign(NID_md5_sha1, md_buf, j,
- &(p[2]), &u, pkey->pkey.rsa) <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_RSA);
- goto err;
- }
- s2n(u, p);
- n += u + 2;
- } else
-#endif
if (md) {
/* send signature algorithm */
if (SSL_USE_SIGALGS(s)) {
#ifdef SSL_DEBUG
fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
#endif
- EVP_SignInit_ex(&md_ctx, md, NULL);
- EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx, d, n);
- if (!EVP_SignFinal(&md_ctx, &(p[2]),
- (unsigned int *)&i, pkey)) {
+ if (EVP_SignInit_ex(md_ctx, md, NULL) <= 0
+ || EVP_SignUpdate(md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_SignUpdate(md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_SignUpdate(md_ctx, d, n) <= 0
+ || EVP_SignFinal(md_ctx, &(p[2]),
+ (unsigned int *)&i, pkey) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
- goto err;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
}
s2n(i, p);
n += i + 2;
goto f_err;
}
- EVP_MD_CTX_cleanup(&md_ctx);
+ EVP_MD_CTX_free(md_ctx);
return 1;
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
+#ifndef OPENSSL_NO_DH
+ EVP_PKEY_free(pkdh);
+#endif
#ifndef OPENSSL_NO_EC
OPENSSL_free(encodedPoint);
- BN_CTX_free(bn_ctx);
#endif
- EVP_MD_CTX_cleanup(&md_ctx);
+ EVP_MD_CTX_free(md_ctx);
ossl_statem_set_error(s);
return 0;
}
return 0;
}
-enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
+MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
{
int al;
unsigned int i;
unsigned long alg_k;
#ifndef OPENSSL_NO_RSA
RSA *rsa = NULL;
- EVP_PKEY *pkey = NULL;
#endif
-#ifndef OPENSSL_NO_DH
- BIGNUM *pub = NULL;
- DH *dh_srvr, *dh_clnt = NULL;
-#endif
-#ifndef OPENSSL_NO_EC
- EC_KEY *srvr_ecdh = NULL;
- EVP_PKEY *clnt_pub_pkey = NULL;
- EC_POINT *clnt_ecpoint = NULL;
- BN_CTX *bn_ctx = NULL;
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+ EVP_PKEY *ckey = NULL;
#endif
PACKET enc_premaster;
unsigned char *data, *rsa_decrypt = NULL;
}
if (!PACKET_strndup(&psk_identity, &s->session->psk_identity)) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
}
OPENSSL_free(s->s3->tmp.psk);
- s->s3->tmp.psk = BUF_memdup(psk, psklen);
+ s->s3->tmp.psk = OPENSSL_memdup(psk, psklen);
OPENSSL_cleanse(psk, psklen);
if (s->s3->tmp.psk == NULL) {
size_t j;
/* FIX THIS UP EAY EAY EAY EAY */
- if (s->s3->tmp.use_rsa_tmp) {
- if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
- rsa = s->cert->rsa_tmp;
- /*
- * Don't do a callback because rsa_tmp should be sent already
- */
- if (rsa == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_MISSING_TMP_RSA_PKEY);
- goto f_err;
-
- }
- } else {
- pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
- if ((pkey == NULL) ||
- (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_MISSING_RSA_CERTIFICATE);
- goto f_err;
- }
- rsa = pkey->pkey.rsa;
+ rsa = EVP_PKEY_get0_RSA(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey);
+ if (rsa == NULL) {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+ SSL_R_MISSING_RSA_CERTIFICATE);
+ goto f_err;
}
/* SSLv3 and pre-standard DTLS omit the length bytes. */
if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) {
enc_premaster = *pkt;
} else {
- PACKET orig = *pkt;
if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster)
|| PACKET_remaining(pkt) != 0) {
- /* Try SSLv3 behaviour for TLS. */
- if (s->options & SSL_OP_TLS_D5_BUG) {
- enc_premaster = orig;
- } else {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+ SSL_R_LENGTH_MISMATCH);
+ goto f_err;
}
}
*/
if (RSA_size(rsa) < SSL_MAX_MASTER_KEY_LENGTH) {
al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
RSA_R_KEY_SIZE_TOO_SMALL);
goto f_err;
}
rsa_decrypt = OPENSSL_malloc(RSA_size(rsa));
if (rsa_decrypt == NULL) {
al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
}
} else
#endif
#ifndef OPENSSL_NO_DH
- if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd | SSL_kDHEPSK)) {
- int idx = -1;
+ if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
EVP_PKEY *skey = NULL;
- PACKET bookmark = *pkt;
- unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8];
+ DH *cdh;
if (!PACKET_get_net_2(pkt, &i)) {
if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
i = 0;
}
if (PACKET_remaining(pkt) != i) {
- if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
- goto err;
- } else {
- *pkt = bookmark;
- i = PACKET_remaining(pkt);
- }
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+ SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+ goto err;
}
- if (alg_k & SSL_kDHr)
- idx = SSL_PKEY_DH_RSA;
- else if (alg_k & SSL_kDHd)
- idx = SSL_PKEY_DH_DSA;
- if (idx >= 0) {
- skey = s->cert->pkeys[idx].privatekey;
- if ((skey == NULL) ||
- (skey->type != EVP_PKEY_DH) || (skey->pkey.dh == NULL)) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_MISSING_RSA_CERTIFICATE);
- goto f_err;
- }
- dh_srvr = skey->pkey.dh;
- } else if (s->s3->tmp.dh == NULL) {
+ skey = s->s3->tmp.pkey;
+ if (skey == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
- } else
- dh_srvr = s->s3->tmp.dh;
+ }
if (PACKET_remaining(pkt) == 0L) {
- /* Get pubkey from cert */
- EVP_PKEY *clkey = X509_get_pubkey(s->session->peer);
- if (clkey) {
- if (EVP_PKEY_cmp_parameters(clkey, skey) == 1)
- dh_clnt = EVP_PKEY_get1_DH(clkey);
- }
- if (dh_clnt == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_MISSING_TMP_DH_KEY);
- goto f_err;
- }
- EVP_PKEY_free(clkey);
- pub = dh_clnt->pub_key;
- } else {
- if (!PACKET_get_bytes(pkt, &data, i)) {
- /* We already checked we have enough data */
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
- pub = BN_bin2bn(data, i, NULL);
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+ SSL_R_MISSING_TMP_DH_KEY);
+ goto f_err;
}
- if (pub == NULL) {
+ if (!PACKET_get_bytes(pkt, &data, i)) {
+ /* We already checked we have enough data */
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ ckey = EVP_PKEY_new();
+ if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) == 0) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
goto err;
}
-
- i = DH_compute_key(shared, pub, dh_srvr);
-
- if (i <= 0) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
- BN_clear_free(pub);
+ cdh = EVP_PKEY_get0_DH(ckey);
+ cdh->pub_key = BN_bin2bn(data, i, NULL);
+ if (cdh->pub_key == NULL) {
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
goto err;
}
- DH_free(s->s3->tmp.dh);
- s->s3->tmp.dh = NULL;
- if (dh_clnt)
- DH_free(dh_clnt);
- else
- BN_clear_free(pub);
- pub = NULL;
- if (!ssl_generate_master_secret(s, shared, i, 0)) {
+ if (ssl_derive(s, skey, ckey) == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto f_err;
}
- if (dh_clnt) {
- s->statem.no_cert_verify = 1;
- return MSG_PROCESS_CONTINUE_PROCESSING;
- }
+
+ EVP_PKEY_free(ckey);
+ ckey = NULL;
+
} else
#endif
#ifndef OPENSSL_NO_EC
if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe | SSL_kECDHEPSK)) {
- int field_size = 0;
- const EC_KEY *tkey;
- const EC_GROUP *group;
- const BIGNUM *priv_key;
- unsigned char *shared;
-
- /* initialize structures for server's ECDH key pair */
- if ((srvr_ecdh = EC_KEY_new()) == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ EVP_PKEY *skey = NULL;
/* Let's get server private key and group information */
if (alg_k & (SSL_kECDHr | SSL_kECDHe)) {
/* use the certificate */
- tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
+ skey = s->cert->pkeys[SSL_PKEY_ECC].privatekey;
} else {
/*
* use the ephermeral values we saved when generating the
* ServerKeyExchange msg.
*/
- tkey = s->s3->tmp.ecdh;
- }
-
- group = EC_KEY_get0_group(tkey);
- priv_key = EC_KEY_get0_private_key(tkey);
-
- if (!EC_KEY_set_group(srvr_ecdh, group) ||
- !EC_KEY_set_private_key(srvr_ecdh, priv_key)) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
- }
-
- /* Let's get client's public key */
- if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
- goto err;
+ skey = s->s3->tmp.pkey;
}
if (PACKET_remaining(pkt) == 0L) {
- /* Client Publickey was in Client Certificate */
-
- if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_MISSING_TMP_ECDH_KEY);
- goto f_err;
- }
- if (((clnt_pub_pkey = X509_get_pubkey(s->session->peer))
- == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) {
- /*
- * XXX: For now, we do not support client authentication
- * using ECDH certificates so this branch (n == 0L) of the
- * code is never executed. When that support is added, we
- * ought to ensure the key received in the certificate is
- * authorized for key agreement. ECDH_compute_key implicitly
- * checks that the two ECDH shares are for the same group.
- */
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
- goto f_err;
- }
-
- if (EC_POINT_copy(clnt_ecpoint,
- EC_KEY_get0_public_key(clnt_pub_pkey->
- pkey.ec)) == 0) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
- }
- s->statem.no_cert_verify = 1;
+ /* We don't support ECDH client auth */
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+ SSL_R_MISSING_TMP_ECDH_KEY);
+ goto f_err;
} else {
/*
* Get client's public key from encoded point in the
* ClientKeyExchange message.
*/
- if ((bn_ctx = BN_CTX_new()) == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
/* Get encoded point length */
if (!PACKET_get_1(pkt, &i)) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
goto err;
}
- if (EC_POINT_oct2point(group, clnt_ecpoint, data, i, bn_ctx) == 0) {
+ ckey = EVP_PKEY_new();
+ if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) {
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto err;
+ }
+ if (EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(ckey), data, i,
+ NULL) == 0) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
goto err;
}
}
- /* Compute the shared pre-master secret */
- field_size = EC_GROUP_get_degree(group);
- if (field_size <= 0) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
- shared = OPENSSL_malloc((field_size + 7) / 8);
- if (shared == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- i = ECDH_compute_key(shared, (field_size + 7) / 8, clnt_ecpoint,
- srvr_ecdh, NULL);
- if (i <= 0) {
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- OPENSSL_free(shared);
- goto err;
- }
-
- EVP_PKEY_free(clnt_pub_pkey);
- EC_POINT_free(clnt_ecpoint);
- EC_KEY_free(srvr_ecdh);
- BN_CTX_free(bn_ctx);
- EC_KEY_free(s->s3->tmp.ecdh);
- s->s3->tmp.ecdh = NULL;
-
- if (!ssl_generate_master_secret(s, shared, i, 1)) {
+ if (ssl_derive(s, skey, ckey) == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto f_err;
}
+
+ EVP_PKEY_free(ckey);
+ ckey = NULL;
+
return MSG_PROCESS_CONTINUE_PROCESSING;
} else
#endif
goto f_err;
}
OPENSSL_free(s->session->srp_username);
- s->session->srp_username = BUF_strdup(s->srp_ctx.login);
+ s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login);
if (s->session->srp_username == NULL) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto err;
}
} else
#endif /* OPENSSL_NO_SRP */
+#ifndef OPENSSL_NO_GOST
if (alg_k & SSL_kGOST) {
EVP_PKEY_CTX *pkey_ctx;
EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
/* Get our certificate private key */
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- if (alg_a & SSL_aGOST01)
+ if (alg_a & SSL_aGOST12) {
+ /*
+ * New GOST ciphersuites have SSL_aGOST01 bit too
+ */
+ pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey;
+ if (pk == NULL) {
+ pk = s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey;
+ }
+ if (pk == NULL) {
+ pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+ }
+ } else if (alg_a & SSL_aGOST01) {
pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+ }
pkey_ctx = EVP_PKEY_CTX_new(pk, NULL);
- EVP_PKEY_decrypt_init(pkey_ctx);
+ if (pkey_ctx == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+ if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
/*
* If client certificate is present and is of the same type, maybe
* use it for key exchange. Don't mind errors from
* EVP_PKEY_derive_set_peer, because it is completely valid to use a
* client certificate for authorization only.
*/
- client_pub_pkey = X509_get_pubkey(s->session->peer);
+ client_pub_pkey = X509_get0_pubkey(s->session->peer);
if (client_pub_pkey) {
if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
ERR_clear_error();
if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto gerr;
}
if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag,
&Tclass, sess_key_len) != V_ASN1_CONSTRUCTED
|| Ttag != V_ASN1_SEQUENCE
|| Tclass != V_ASN1_UNIVERSAL) {
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto gerr;
inlen = Tlen;
if (EVP_PKEY_decrypt
(pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) {
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto gerr;
sizeof(premaster_secret), 0)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto gerr;
}
/* Check if pubkey from client certificate was used */
if (EVP_PKEY_CTX_ctrl
(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
s->statem.no_cert_verify = 1;
- EVP_PKEY_free(client_pub_pkey);
EVP_PKEY_CTX_free(pkey_ctx);
return MSG_PROCESS_CONTINUE_PROCESSING;
gerr:
- EVP_PKEY_free(client_pub_pkey);
EVP_PKEY_CTX_free(pkey_ctx);
- goto err;
- } else {
+ goto f_err;
+ } else
+#endif
+ {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE);
goto f_err;
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_EC) || defined(OPENSSL_NO_SRP)
err:
#endif
-#ifndef OPENSSL_NO_EC
- EVP_PKEY_free(clnt_pub_pkey);
- EC_POINT_free(clnt_ecpoint);
- EC_KEY_free(srvr_ecdh);
- BN_CTX_free(bn_ctx);
- OPENSSL_free(rsa_decrypt);
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+ EVP_PKEY_free(ckey);
#endif
+ OPENSSL_free(rsa_decrypt);
#ifndef OPENSSL_NO_PSK
OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
s->s3->tmp.psk = NULL;
return MSG_PROCESS_ERROR;
}
-enum WORK_STATE tls_post_process_client_key_exchange(SSL *s,
- enum WORK_STATE wst)
+WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
{
#ifndef OPENSSL_NO_SCTP
if (wst == WORK_MORE_A) {
* Add new shared key for SCTP-Auth, will be ignored if no SCTP
* used.
*/
- snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
- DTLS1_SCTP_AUTH_LABEL);
+ memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
+ sizeof(DTLS1_SCTP_AUTH_LABEL));
if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
s->rwstate = SSL_READING;
BIO_clear_retry_flags(SSL_get_rbio(s));
BIO_set_retry_read(SSL_get_rbio(s));
- statem_set_sctp_read_sock(s, 1);
+ ossl_statem_set_sctp_read_sock(s, 1);
return WORK_MORE_B;
} else {
ossl_statem_set_sctp_read_sock(s, 0);
if (s->statem.no_cert_verify) {
/* No certificate verify so we no longer need the handshake_buffer */
BIO_free(s->s3->handshake_buffer);
+ s->s3->handshake_buffer = NULL;
return WORK_FINISHED_CONTINUE;
- } else if (SSL_USE_SIGALGS(s)) {
+ } else {
if (!s->session->peer) {
/* No peer certificate so we no longer need the handshake_buffer */
BIO_free(s->s3->handshake_buffer);
ossl_statem_set_error(s);
return WORK_ERROR;
}
- } else {
- int offset = 0;
- int dgst_num;
-
- /*
- * We need to get hashes here so if there is a client cert,
- * it can be verified FIXME - digest processing for
- * CertificateVerify should be generalized. But it is next
- * step
- */
- if (!ssl3_digest_cached_records(s, 0)) {
- ossl_statem_set_error(s);
- return WORK_ERROR;
- }
- for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) {
- if (s->s3->handshake_dgst[dgst_num]) {
- int dgst_size;
-
- s->method->ssl3_enc->cert_verify_mac(s,
- EVP_MD_CTX_type
- (s->
- s3->handshake_dgst
- [dgst_num]),
- &(s->s3->
- tmp.cert_verify_md
- [offset]));
- dgst_size =
- EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
- if (dgst_size < 0) {
- ossl_statem_set_error(s);
- return WORK_ERROR;
- }
- offset += dgst_size;
- }
- }
}
return WORK_FINISHED_CONTINUE;
}
-enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
+MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
{
EVP_PKEY *pkey = NULL;
unsigned char *sig, *data;
int al, ret = MSG_PROCESS_ERROR;
- int type = 0, i, j;
+ int type = 0, j;
unsigned int len;
X509 *peer;
const EVP_MD *md = NULL;
- EVP_MD_CTX mctx;
- EVP_MD_CTX_init(&mctx);
+ long hdatalen = 0;
+ void *hdata;
+
+ EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+
+ if (mctx == NULL) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
peer = s->session->peer;
- pkey = X509_get_pubkey(peer);
+ pkey = X509_get0_pubkey(peer);
type = X509_certificate_type(peer, pkey);
if (!(type & EVP_PKT_SIGN)) {
/* Check for broken implementations of GOST ciphersuites */
/*
* If key is GOST and n is exactly 64, it is bare signature without
- * length field
+ * length field (CryptoPro implementations at least till CSP 4.0)
*/
- if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) {
+#ifndef OPENSSL_NO_GOST
+ if (PACKET_remaining(pkt) == 64
+ && EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) {
len = 64;
- } else {
+ } else
+#endif
+ {
if (SSL_USE_SIGALGS(s)) {
int rv;
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
+ } else {
+ /* Use default digest for this key type */
+ int idx = ssl_cert_type(NULL, pkey);
+ if (idx >= 0)
+ md = s->s3->tmp.md[idx];
+ if (md == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
}
+
if (!PACKET_get_net_2(pkt, &len)) {
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
- if (SSL_USE_SIGALGS(s)) {
- long hdatalen = 0;
- void *hdata;
- hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
+ hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+ if (hdatalen <= 0) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
#ifdef SSL_DEBUG
- fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
- EVP_MD_name(md));
+ fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md));
#endif
- if (!EVP_VerifyInit_ex(&mctx, md, NULL)
- || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) {
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
+ if (!EVP_VerifyInit_ex(mctx, md, NULL)
+ || !EVP_VerifyUpdate(mctx, hdata, hdatalen)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
- if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
- goto f_err;
- }
- } else
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA) {
- i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
- MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len,
- pkey->pkey.rsa);
- if (i < 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT);
- goto f_err;
- }
- if (i == 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE);
- goto f_err;
- }
- } else
-#endif
-#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA) {
- j = DSA_verify(pkey->save_type,
- &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa);
- if (j <= 0) {
- /* bad signature */
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE);
- goto f_err;
- }
- } else
-#endif
-#ifndef OPENSSL_NO_EC
- if (pkey->type == EVP_PKEY_EC) {
- j = ECDSA_verify(pkey->save_type,
- &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec);
- if (j <= 0) {
- /* bad signature */
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
- goto f_err;
- }
- } else
+#ifndef OPENSSL_NO_GOST
+ {
+ int pktype = EVP_PKEY_id(pkey);
+ if (pktype == NID_id_GostR3410_2001
+ || pktype == NID_id_GostR3410_2012_256
+ || pktype == NID_id_GostR3410_2012_512)
+ BUF_reverse(data, NULL, len);
+ }
#endif
- if (pkey->type == NID_id_GostR3410_2001) {
- unsigned char signature[64];
- int idx;
- EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
- EVP_PKEY_verify_init(pctx);
- if (len != 64) {
- fprintf(stderr, "GOST signature length is %d", len);
- }
- for (idx = 0; idx < 64; idx++) {
- signature[63 - idx] = data[idx];
- }
- j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md,
- 32);
- EVP_PKEY_CTX_free(pctx);
- if (j <= 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
- goto f_err;
- }
- } else {
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
- al = SSL_AD_UNSUPPORTED_CERTIFICATE;
+
+ if (s->version == SSL3_VERSION
+ && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+ s->session->master_key_length,
+ s->session->master_key)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+
+ if (EVP_VerifyFinal(mctx, data, len, pkey) <= 0) {
+ al = SSL_AD_DECRYPT_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
goto f_err;
}
}
BIO_free(s->s3->handshake_buffer);
s->s3->handshake_buffer = NULL;
- EVP_MD_CTX_cleanup(&mctx);
- EVP_PKEY_free(pkey);
+ EVP_MD_CTX_free(mctx);
return ret;
}
-enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
+MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
{
- int i, al, ret = MSG_PROCESS_ERROR;
+ int i, al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR;
X509 *x = NULL;
unsigned long l, llen;
const unsigned char *certstart;
}
/* No client certificate so digest cached records */
if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, 0)) {
- al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
- pkey = X509_get_pubkey(sk_X509_value(sk, 0));
+ pkey = X509_get0_pubkey(sk_X509_value(sk, 0));
if (pkey == NULL) {
al = SSL3_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
SSL_R_UNKNOWN_CERTIFICATE_TYPE);
goto f_err;
}
- EVP_PKEY_free(pkey);
}
X509_free(s->session->peer);
int tls_construct_new_session_ticket(SSL *s)
{
unsigned char *senc = NULL;
- EVP_CIPHER_CTX ctx;
- HMAC_CTX hctx;
+ EVP_CIPHER_CTX *ctx;
+ HMAC_CTX *hctx = NULL;
unsigned char *p, *macstart;
const unsigned char *const_p;
int len, slen_full, slen;
return 0;
}
senc = OPENSSL_malloc(slen_full);
- if (!senc) {
+ if (senc == NULL) {
ossl_statem_set_error(s);
return 0;
}
- EVP_CIPHER_CTX_init(&ctx);
- HMAC_CTX_init(&hctx);
+ ctx = EVP_CIPHER_CTX_new();
+ hctx = HMAC_CTX_new();
p = senc;
if (!i2d_SSL_SESSION(s->session, &p))
* all the work otherwise use generated values from parent ctx.
*/
if (tctx->tlsext_ticket_key_cb) {
- if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
- &hctx, 1) < 0)
+ if (tctx->tlsext_ticket_key_cb(s, key_name, iv, ctx, hctx, 1) < 0)
goto err;
} else {
if (RAND_bytes(iv, 16) <= 0)
goto err;
- if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ if (!EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL,
tctx->tlsext_tick_aes_key, iv))
goto err;
- if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+ if (!HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, 16,
EVP_sha256(), NULL))
goto err;
memcpy(key_name, tctx->tlsext_tick_key_name, 16);
memcpy(p, key_name, 16);
p += 16;
/* output IV */
- memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
- p += EVP_CIPHER_CTX_iv_length(&ctx);
+ memcpy(p, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ p += EVP_CIPHER_CTX_iv_length(ctx);
/* Encrypt session data */
- if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen))
+ if (!EVP_EncryptUpdate(ctx, p, &len, senc, slen))
goto err;
p += len;
- if (!EVP_EncryptFinal(&ctx, p, &len))
+ if (!EVP_EncryptFinal(ctx, p, &len))
goto err;
p += len;
- if (!HMAC_Update(&hctx, macstart, p - macstart))
+ if (!HMAC_Update(hctx, macstart, p - macstart))
goto err;
- if (!HMAC_Final(&hctx, p, &hlen))
+ if (!HMAC_Final(hctx, p, &hlen))
goto err;
- EVP_CIPHER_CTX_cleanup(&ctx);
- HMAC_CTX_cleanup(&hctx);
+ EVP_CIPHER_CTX_free(ctx);
+ HMAC_CTX_free(hctx);
+ ctx = NULL;
+ hctx = NULL;
p += hlen;
/* Now write out lengths: p points to end of data written */
return 1;
err:
OPENSSL_free(senc);
- EVP_CIPHER_CTX_cleanup(&ctx);
- HMAC_CTX_cleanup(&hctx);
+ EVP_CIPHER_CTX_free(ctx);
+ HMAC_CTX_free(hctx);
ossl_statem_set_error(s);
return 0;
}
* tls_process_next_proto reads a Next Protocol Negotiation handshake message.
* It sets the next_proto member in s if found
*/
-enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt)
+MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt)
{
PACKET next_proto, padding;
size_t next_proto_len;
* version. Fail if the current version is an unexpected
* downgrade.
*/
- if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) {
+ if (!ssl_check_version_downgrade(s)) {
SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
SSL_R_INAPPROPRIATE_FALLBACK);
*al = SSL_AD_INAPPROPRIATE_FALLBACK;