/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* https://www.openssl.org/source/license.html
*/
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * ECC cipher suite support in OpenSSL originally developed by
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
-
#include <limits.h>
#include <string.h>
#include <stdio.h>
if (!ssl3_init_finished_mac(s))
return 0;
+ /* Reset any extension flags */
+ memset(s->ext.extflags, 0, sizeof(s->ext.extflags));
+
if (s->server) {
STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s);
int i, ver_min, ver_max, ok = 0;
}
if (SSL_IS_FIRST_HANDSHAKE(s)) {
s->ctx->stats.sess_accept++;
+ } else if ((s->options & SSL_OP_NO_RENEGOTIATION)) {
+ /* Renegotiation is disabled */
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ return 0;
} else if (!s->s3->send_connection_binding &&
!(s->options &
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
goto err;
}
pkey = s->s3->tmp.cert->privatekey;
- md = ssl_md(lu->hash_idx);
- if (pkey == NULL || md == NULL) {
+ if (pkey == NULL || !tls1_lookup_md(lu, &md)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
goto err;
}
- if (EVP_DigestSignInit(mctx, &pctx, md, NULL, pkey) <= 0
- || EVP_DigestSignUpdate(mctx, hdata, hdatalen) <= 0) {
+ if (EVP_DigestSignInit(mctx, &pctx, md, NULL, pkey) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
goto err;
}
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
goto err;
}
- } else if (s->version == SSL3_VERSION) {
- if (!EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
- (int)s->session->master_key_length,
- s->session->master_key)) {
+ }
+ if (s->version == SSL3_VERSION) {
+ if (EVP_DigestSignUpdate(mctx, hdata, hdatalen) <= 0
+ || !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+ (int)s->session->master_key_length,
+ s->session->master_key)
+ || EVP_DigestSignFinal(mctx, sig, &siglen) <= 0) {
+
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
goto err;
}
- }
-
- if (EVP_DigestSignFinal(mctx, sig, &siglen) <= 0) {
+ } else if (EVP_DigestSign(mctx, sig, &siglen, hdata, hdatalen) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
goto err;
}
peer = s->session->peer;
pkey = X509_get0_pubkey(peer);
- if (pkey == NULL) {
- al = SSL_AD_INTERNAL_ERROR;
+ if (pkey == NULL)
goto f_err;
- }
type = X509_certificate_type(peer, pkey);
goto f_err;
}
+ if (SSL_USE_SIGALGS(s)) {
+ int rv;
+ unsigned int sigalg;
+
+ if (!PACKET_get_net_2(pkt, &sigalg)) {
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+ rv = tls12_check_peer_sigalg(s, sigalg, pkey);
+ if (rv == -1) {
+ goto f_err;
+ } else if (rv == 0) {
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+#ifdef SSL_DEBUG
+ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+#endif
+ } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+
+ if (!tls1_lookup_md(s->s3->tmp.peer_sigalg, &md)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+
/* Check for broken implementations of GOST ciphersuites */
/*
- * If key is GOST and n is exactly 64, it is bare signature without
- * length field (CryptoPro implementations at least till CSP 4.0)
+ * If key is GOST and len is exactly 64 or 128, it is signature without
+ * length field (CryptoPro implementations at least till TLS 1.2)
*/
#ifndef OPENSSL_NO_GOST
- if (PACKET_remaining(pkt) == 64
- && EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) {
- len = 64;
+ if (!SSL_USE_SIGALGS(s)
+ && ((PACKET_remaining(pkt) == 64
+ && (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001
+ || EVP_PKEY_id(pkey) == NID_id_GostR3410_2012_256))
+ || (PACKET_remaining(pkt) == 128
+ && EVP_PKEY_id(pkey) == NID_id_GostR3410_2012_512))) {
+ len = PACKET_remaining(pkt);
} else
#endif
- {
- if (SSL_USE_SIGALGS(s)) {
- int rv;
- unsigned int sigalg;
-
- if (!PACKET_get_net_2(pkt, &sigalg)) {
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
- rv = tls12_check_peer_sigalg(s, sigalg, pkey);
- if (rv == -1) {
- goto f_err;
- } else if (rv == 0) {
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
-#ifdef SSL_DEBUG
- fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
-#endif
- } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
-
- md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx);
-
- 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 (!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;
}
+
j = EVP_PKEY_size(pkey);
if (((int)len > j) || ((int)PACKET_remaining(pkt) > j)
|| (PACKET_remaining(pkt) == 0)) {
#ifdef SSL_DEBUG
fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md));
#endif
- if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, pkey) <= 0
- || EVP_DigestVerifyUpdate(mctx, hdata, hdatalen) <= 0) {
+ if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, pkey) <= 0) {
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
goto f_err;
}
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
goto f_err;
}
- } else if (s->version == SSL3_VERSION
- && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
- (int)s->session->master_key_length,
- s->session->master_key)) {
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
- goto f_err;
}
-
- if (EVP_DigestVerifyFinal(mctx, data, len) <= 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
- goto f_err;
+ if (s->version == SSL3_VERSION) {
+ if (EVP_DigestVerifyUpdate(mctx, hdata, hdatalen) <= 0
+ || !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+ (int)s->session->master_key_length,
+ s->session->master_key)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+ goto f_err;
+ }
+ if (EVP_DigestVerifyFinal(mctx, data, len) <= 0) {
+ al = SSL_AD_DECRYPT_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
+ goto f_err;
+ }
+ } else {
+ j = EVP_DigestVerify(mctx, data, len, hdata, hdatalen);
+ if (j <= 0) {
+ al = SSL_AD_DECRYPT_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
+ goto f_err;
+ }
}
ret = MSG_PROCESS_CONTINUE_READING;
&& (!s->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {
SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, SSL_R_CANNOT_CHANGE_CIPHER);
- goto err;
+ /*
+ * This is a fatal error, which leaves
+ * enc_write_ctx in an inconsistent state
+ * and thus ssl3_send_alert may crash.
+ */
+ return 0;
}
if (s->server) {
*/
if (!SSL_IS_TLS13(s) && !ssl_log_secret(s, MASTER_SECRET_LABEL,
s->session->master_key,
- s->session->master_key_length))
- return 0;
+ s->session->master_key_length)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
/*
* Copy the finished so we can use it for renegotiation checks
*/
+ if (!ossl_assert(finish_md_len <= EVP_MAX_MD_SIZE)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
if (!s->server) {
- OPENSSL_assert(finish_md_len <= EVP_MAX_MD_SIZE);
memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md,
finish_md_len);
s->s3->previous_client_finished_len = finish_md_len;
} else {
- OPENSSL_assert(finish_md_len <= EVP_MAX_MD_SIZE);
memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md,
finish_md_len);
s->s3->previous_server_finished_len = finish_md_len;
}
if (!PACKET_get_1(pkt, &updatetype)
- || PACKET_remaining(pkt) != 0
- || (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
- && updatetype != SSL_KEY_UPDATE_REQUESTED)) {
+ || PACKET_remaining(pkt) != 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_BAD_KEY_UPDATE);
goto err;
}
+ /*
+ * There are only two defined key update types. Fail if we get a value we
+ * didn't recognise.
+ */
+ if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
+ && updatetype != SSL_KEY_UPDATE_REQUESTED) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_BAD_KEY_UPDATE);
+ goto err;
+ }
+
/*
* If we get a request for us to update our sending keys too then, we need
* to additionally send a KeyUpdate message. However that message should
&& remain != DTLS1_CCS_HEADER_LENGTH + 1)
|| (s->version != DTLS1_BAD_VER
&& remain != DTLS1_CCS_HEADER_LENGTH - 1)) {
- al = SSL_AD_ILLEGAL_PARAMETER;
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC,
SSL_R_BAD_CHANGE_CIPHER_SPEC);
goto f_err;
}
} else {
if (remain != 0) {
- al = SSL_AD_ILLEGAL_PARAMETER;
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC,
SSL_R_BAD_CHANGE_CIPHER_SPEC);
goto f_err;
/*
* Copy the finished so we can use it for renegotiation checks
*/
+ if (!ossl_assert(md_len <= EVP_MAX_MD_SIZE)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_FINISHED, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
if (s->server) {
- OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md,
md_len);
s->s3->previous_client_finished_len = md_len;
} else {
- OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md,
md_len);
s->s3->previous_server_finished_len = md_len;
BUF_MEM_free(s->init_buf);
s->init_buf = NULL;
}
- ssl_free_wbio_buffer(s);
+ if (!ssl_free_wbio_buffer(s))
+ return WORK_ERROR;
s->init_num = 0;
}
return 1;
}
-int ssl_cert_type(const X509 *x, const EVP_PKEY *pk)
-{
- if (pk == NULL && (pk = X509_get0_pubkey(x)) == NULL)
- return -1;
-
- switch (EVP_PKEY_id(pk)) {
- default:
- return -1;
- case EVP_PKEY_RSA:
- return SSL_PKEY_RSA;
- case EVP_PKEY_DSA:
- return SSL_PKEY_DSA_SIGN;
-#ifndef OPENSSL_NO_EC
- case EVP_PKEY_EC:
- return SSL_PKEY_ECC;
-#endif
-#ifndef OPENSSL_NO_GOST
- case NID_id_GostR3410_2001:
- return SSL_PKEY_GOST01;
- case NID_id_GostR3410_2012_256:
- return SSL_PKEY_GOST12_256;
- case NID_id_GostR3410_2012_512:
- return SSL_PKEY_GOST12_512;
-#endif
- }
-}
-
int ssl_verify_alarm_type(long type)
{
int al;
* Fall through if we are TLSv1.3 already (this means we must be after
* a HelloRetryRequest
*/
+ /* fall thru */
case TLS_ANY_VERSION:
table = tls_version_table;
break;
return 0;
for (i = 0; i < num_groups; i++, groups += 2) {
- unsigned int share_id = (groups[0] << 8) | (groups[1]);
-
- if (group_id == share_id
+ if (group_id == GET_GROUP_ID(groups, 0)
&& (!checkallow
|| tls_curve_allowed(s, groups, SSL_SECOP_CURVE_CHECK))) {
return 1;
return 1;
}
+
+/* Create a buffer containing data to be signed for server key exchange */
+size_t construct_key_exchange_tbs(const SSL *s, unsigned char **ptbs,
+ const void *param, size_t paramlen)
+{
+ size_t tbslen = 2 * SSL3_RANDOM_SIZE + paramlen;
+ unsigned char *tbs = OPENSSL_malloc(tbslen);
+
+ if (tbs == NULL)
+ return 0;
+ memcpy(tbs, s->s3->client_random, SSL3_RANDOM_SIZE);
+ memcpy(tbs + SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE);
+
+ memcpy(tbs + SSL3_RANDOM_SIZE * 2, param, paramlen);
+
+ *ptbs = tbs;
+ return tbslen;
+}