aboutsummaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2015-12-03 17:24:16 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2015-12-03 17:24:16 +0000
commit7f3b396bf01ae727af21c432a52afb8e8ff5781b (patch)
tree8b12a96cca9b24a3d486b1a2e2bed6f3d1f3f2e9 /ssl
parentc07d7b3a386974c338492659291008bed07948e6 (diff)
downloadsrc-7f3b396bf01ae727af21c432a52afb8e8ff5781b.tar.gz
src-7f3b396bf01ae727af21c432a52afb8e8ff5781b.zip
Import OpenSSL 1.0.1q.vendor/openssl/1.0.1q
Notes
Notes: svn path=/vendor-crypto/openssl/dist-1.0.1/; revision=291709 svn path=/vendor-crypto/openssl/1.0.1q/; revision=291710; tag=vendor/openssl/1.0.1q
Diffstat (limited to 'ssl')
-rw-r--r--ssl/Makefile2
-rw-r--r--ssl/bio_ssl.c4
-rw-r--r--ssl/clienthellotest.c218
-rw-r--r--ssl/d1_both.c7
-rw-r--r--ssl/d1_clnt.c23
-rw-r--r--ssl/d1_srvr.c31
-rw-r--r--ssl/s23_clnt.c21
-rw-r--r--ssl/s3_cbc.c45
-rw-r--r--ssl/s3_clnt.c119
-rw-r--r--ssl/s3_enc.c108
-rw-r--r--ssl/s3_lib.c2
-rw-r--r--ssl/s3_srvr.c78
-rw-r--r--ssl/ssl.h4
-rw-r--r--ssl/ssl3.h2
-rw-r--r--ssl/ssl_asn1.c5
-rw-r--r--ssl/ssl_cert.c2
-rw-r--r--ssl/ssl_ciph.c11
-rw-r--r--ssl/ssl_err.c5
-rw-r--r--ssl/ssl_lib.c9
-rw-r--r--ssl/ssl_locl.h20
-rw-r--r--ssl/ssl_rsa.c23
-rw-r--r--ssl/ssl_sess.c4
-rw-r--r--ssl/ssltest.c1
-rw-r--r--ssl/t1_enc.c48
-rw-r--r--ssl/t1_lib.c57
-rw-r--r--ssl/tls1.h15
26 files changed, 641 insertions, 223 deletions
diff --git a/ssl/Makefile b/ssl/Makefile
index 29d9e4528fc5..ad14abb0b381 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -15,7 +15,7 @@ KRB5_INCLUDES=
CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile README ssl-lib.com install.com
-TEST=ssltest.c heartbeat_test.c
+TEST=ssltest.c heartbeat_test.c clienthellotest.c
APPS=
LIB=$(TOP)/libssl.a
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index a0c583e34215..d2d4d2ea2d2d 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -419,6 +419,10 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY);
b->retry_reason = b->next_bio->retry_reason;
break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_set_retry_special(b);
+ b->retry_reason = BIO_RR_SSL_X509_LOOKUP;
+ break;
default:
break;
}
diff --git a/ssl/clienthellotest.c b/ssl/clienthellotest.c
new file mode 100644
index 000000000000..a00a7ea02d6b
--- /dev/null
+++ b/ssl/clienthellotest.c
@@ -0,0 +1,218 @@
+/* Written by Matt Caswell for the OpenSSL Project */
+/* ====================================================================
+ * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+
+#define CLIENT_VERSION_LEN 2
+#define SESSION_ID_LEN_LEN 1
+#define CIPHERS_LEN_LEN 2
+#define COMPRESSION_LEN_LEN 1
+#define EXTENSIONS_LEN_LEN 2
+#define EXTENSION_TYPE_LEN 2
+#define EXTENSION_SIZE_LEN 2
+
+
+#define TOTAL_NUM_TESTS 2
+
+/*
+ * Test that explicitly setting ticket data results in it appearing in the
+ * ClientHello for TLS1.2
+ */
+#define TEST_SET_SESSION_TICK_DATA_TLS_1_2 0
+
+/*
+ * Test that explicitly setting ticket data results in it appearing in the
+ * ClientHello for a negotiated SSL/TLS version
+ */
+#define TEST_SET_SESSION_TICK_DATA_VER_NEG 1
+
+int main(int argc, char *argv[])
+{
+ SSL_CTX *ctx;
+ SSL *con;
+ BIO *rbio;
+ BIO *wbio;
+ BIO *err;
+ long len;
+ unsigned char *data;
+ unsigned char *dataend;
+ char *dummytick = "Hello World!";
+ unsigned int tmplen;
+ unsigned int type;
+ unsigned int size;
+ int testresult = 0;
+ int currtest = 0;
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ /*
+ * For each test set up an SSL_CTX and SSL and see what ClientHello gets
+ * produced when we try to connect
+ */
+ for (; currtest < TOTAL_NUM_TESTS; currtest++) {
+ testresult = 0;
+ if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2) {
+ ctx = SSL_CTX_new(TLSv1_2_method());
+ } else {
+ ctx = SSL_CTX_new(SSLv23_method());
+ }
+ con = SSL_new(ctx);
+
+ rbio = BIO_new(BIO_s_mem());
+ wbio = BIO_new(BIO_s_mem());
+ SSL_set_bio(con, rbio, wbio);
+ SSL_set_connect_state(con);
+
+ if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2
+ || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {
+ if (!SSL_set_session_ticket_ext(con, dummytick, strlen(dummytick)))
+ goto end;
+ }
+
+ if (SSL_connect(con) > 0) {
+ /* This shouldn't succeed because we don't have a server! */
+ goto end;
+ }
+
+ len = BIO_get_mem_data(wbio, (char **)&data);
+ dataend = data + len;
+
+ /* Skip the record header */
+ data += SSL3_RT_HEADER_LENGTH;
+ /* Skip the handshake message header */
+ data += SSL3_HM_HEADER_LENGTH;
+ /* Skip client version and random */
+ data += CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE;
+ if (data + SESSION_ID_LEN_LEN > dataend)
+ goto end;
+ /* Skip session id */
+ tmplen = *data;
+ data += SESSION_ID_LEN_LEN + tmplen;
+ if (data + CIPHERS_LEN_LEN > dataend)
+ goto end;
+ /* Skip ciphers */
+ tmplen = ((*data) << 8) | *(data + 1);
+ data += CIPHERS_LEN_LEN + tmplen;
+ if (data + COMPRESSION_LEN_LEN > dataend)
+ goto end;
+ /* Skip compression */
+ tmplen = *data;
+ data += COMPRESSION_LEN_LEN + tmplen;
+ if (data + EXTENSIONS_LEN_LEN > dataend)
+ goto end;
+ /* Extensions len */
+ tmplen = ((*data) << 8) | *(data + 1);
+ data += EXTENSIONS_LEN_LEN;
+ if (data + tmplen > dataend)
+ goto end;
+
+ /* Loop through all extensions */
+ while (tmplen > EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN) {
+ type = ((*data) << 8) | *(data + 1);
+ data += EXTENSION_TYPE_LEN;
+ size = ((*data) << 8) | *(data + 1);
+ data += EXTENSION_SIZE_LEN;
+ if (data + size > dataend)
+ goto end;
+
+ if (type == TLSEXT_TYPE_session_ticket) {
+ if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2
+ || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {
+ if (size == strlen(dummytick)
+ && memcmp(data, dummytick, size) == 0) {
+ /* Ticket data is as we expected */
+ testresult = 1;
+ } else {
+ printf("Received session ticket is not as expected\n");
+ }
+ break;
+ }
+ }
+
+ tmplen -= EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN + size;
+ data += size;
+ }
+
+ end:
+ SSL_free(con);
+ SSL_CTX_free(ctx);
+ if (!testresult) {
+ printf("ClientHello test: FAILED (Test %d)\n", currtest);
+ break;
+ }
+ }
+
+ ERR_free_strings();
+ ERR_remove_thread_state(NULL);
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ CRYPTO_mem_leaks(err);
+
+ return testresult?0:1;
+}
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 8dd8ea33ca79..d453c07c8e69 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -1490,9 +1490,12 @@ int dtls1_shutdown(SSL *s)
{
int ret;
#ifndef OPENSSL_NO_SCTP
- if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+ BIO *wbio;
+
+ wbio = SSL_get_wbio(s);
+ if (wbio != NULL && BIO_dgram_is_sctp(wbio) &&
!(s->shutdown & SSL_SENT_SHUTDOWN)) {
- ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+ ret = BIO_dgram_sctp_wait_for_dry(wbio);
if (ret < 0)
return -1;
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 377c1e61f75c..eb371a255f89 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -299,13 +299,12 @@ int dtls1_connect(SSL *s)
#endif
case SSL3_ST_CW_CLNT_HELLO_A:
- case SSL3_ST_CW_CLNT_HELLO_B:
-
s->shutdown = 0;
/* every DTLS ClientHello resets Finished MAC */
ssl3_init_finished_mac(s);
+ case SSL3_ST_CW_CLNT_HELLO_B:
dtls1_start_timer(s);
ret = dtls1_client_hello(s);
if (ret <= 0)
@@ -350,11 +349,15 @@ int dtls1_connect(SSL *s)
sizeof(DTLS1_SCTP_AUTH_LABEL),
DTLS1_SCTP_AUTH_LABEL);
- SSL_export_keying_material(s, sctpauthkey,
+ if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey),
labelbuffer,
sizeof(labelbuffer), NULL, 0,
- 0);
+ 0) <= 0) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
@@ -362,6 +365,10 @@ int dtls1_connect(SSL *s)
#endif
s->state = SSL3_ST_CR_FINISHED_A;
+ if (s->tlsext_ticket_expected) {
+ /* receive renewed session ticket */
+ s->state = SSL3_ST_CR_SESSION_TICKET_A;
+ }
} else
s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
}
@@ -484,9 +491,13 @@ int dtls1_connect(SSL *s)
snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
DTLS1_SCTP_AUTH_LABEL);
- SSL_export_keying_material(s, sctpauthkey,
+ if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
- sizeof(labelbuffer), NULL, 0, 0);
+ sizeof(labelbuffer), NULL, 0, 0) <= 0) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
sizeof(sctpauthkey), sctpauthkey);
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 41c7dc519f1b..f01b8a693f4e 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -267,6 +267,19 @@ int dtls1_accept(SSL *s)
ssl3_init_finished_mac(s);
s->state = SSL3_ST_SR_CLNT_HELLO_A;
s->ctx->stats.sess_accept++;
+ } else if (!s->s3->send_connection_binding &&
+ !(s->options &
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+ /*
+ * Server attempting to renegotiate with client that doesn't
+ * support secure renegotiation.
+ */
+ SSLerr(SSL_F_DTLS1_ACCEPT,
+ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
} else {
/*
* s->state == SSL_ST_RENEGOTIATE, we will just send a
@@ -405,9 +418,13 @@ int dtls1_accept(SSL *s)
snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
DTLS1_SCTP_AUTH_LABEL);
- SSL_export_keying_material(s, sctpauthkey,
- sizeof(sctpauthkey), labelbuffer,
- sizeof(labelbuffer), NULL, 0, 0);
+ if (SSL_export_keying_material(s, sctpauthkey,
+ sizeof(sctpauthkey), labelbuffer,
+ sizeof(labelbuffer), NULL, 0, 0) <= 0) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
sizeof(sctpauthkey), sctpauthkey);
@@ -628,9 +645,13 @@ int dtls1_accept(SSL *s)
snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
DTLS1_SCTP_AUTH_LABEL);
- SSL_export_keying_material(s, sctpauthkey,
+ if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
- sizeof(labelbuffer), NULL, 0, 0);
+ sizeof(labelbuffer), NULL, 0, 0) <= 0) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
sizeof(sctpauthkey), sctpauthkey);
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 3766567c8f80..2b2855dee4a9 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -373,12 +373,13 @@ static int ssl23_client_hello(SSL *s)
buf = (unsigned char *)s->init_buf->data;
if (s->state == SSL23_ST_CW_CLNT_HELLO_A) {
-#if 0
- /* don't reuse session-id's */
+ /*
+ * Since we're sending s23 client hello, we're not reusing a session, as
+ * we'd be using the method from the saved session instead
+ */
if (!ssl_get_new_session(s, 0)) {
- return (-1);
+ return -1;
}
-#endif
p = s->s3->client_random;
if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
@@ -439,9 +440,6 @@ static int ssl23_client_hello(SSL *s)
/*
* put in the session-id length (zero since there is no reuse)
*/
-#if 0
- s->session->session_id_length = 0;
-#endif
s2n(0, d);
if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
@@ -729,6 +727,8 @@ static int ssl23_get_server_hello(SSL *s)
goto err;
}
+ s->session->ssl_version = s->version;
+
/* ensure that TLS_MAX_VERSION is up-to-date */
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
@@ -784,13 +784,6 @@ static int ssl23_get_server_hello(SSL *s)
}
s->init_num = 0;
- /*
- * Since, if we are sending a ssl23 client hello, we are not reusing a
- * session-id
- */
- if (!ssl_get_new_session(s, 0))
- goto err;
-
return (SSL_connect(s));
err:
return (-1);
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 2fb71f277e9c..b3bff743495c 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -411,8 +411,9 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
* functions, above, we know that data_plus_mac_size is large enough to contain
* a padding byte and MAC. (If the padding was invalid, it might contain the
* padding too. )
+ * Returns 1 on success or 0 on error
*/
-void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
unsigned char *md_out,
size_t *md_out_size,
const unsigned char header[13],
@@ -455,7 +456,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
switch (EVP_MD_CTX_type(ctx)) {
case NID_md5:
- MD5_Init((MD5_CTX *)md_state.c);
+ if (MD5_Init((MD5_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_md5_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))MD5_Transform;
@@ -464,7 +466,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
length_is_big_endian = 0;
break;
case NID_sha1:
- SHA1_Init((SHA_CTX *)md_state.c);
+ if (SHA1_Init((SHA_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha1_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
@@ -472,14 +475,16 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
break;
#ifndef OPENSSL_NO_SHA256
case NID_sha224:
- SHA224_Init((SHA256_CTX *)md_state.c);
+ if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha256_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
md_size = 224 / 8;
break;
case NID_sha256:
- SHA256_Init((SHA256_CTX *)md_state.c);
+ if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha256_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
@@ -488,7 +493,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
#endif
#ifndef OPENSSL_NO_SHA512
case NID_sha384:
- SHA384_Init((SHA512_CTX *)md_state.c);
+ if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha512_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
@@ -497,7 +503,8 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
md_length_size = 16;
break;
case NID_sha512:
- SHA512_Init((SHA512_CTX *)md_state.c);
+ if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0)
+ return 0;
md_final_raw = tls1_sha512_final_raw;
md_transform =
(void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
@@ -514,7 +521,7 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
OPENSSL_assert(0);
if (md_out_size)
*md_out_size = -1;
- return;
+ return 0;
}
OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
@@ -652,7 +659,7 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
*/
if (header_length <= md_block_size) {
/* Should never happen */
- return;
+ return 0;
}
overhang = header_length - md_block_size;
md_transform(md_state.c, header);
@@ -733,26 +740,34 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
}
EVP_MD_CTX_init(&md_ctx);
- EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ );
+ if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0)
+ goto err;
if (is_sslv3) {
/* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
memset(hmac_pad, 0x5c, sslv3_pad_length);
- EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
- EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
- EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+ if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0
+ || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+ goto err;
} else {
/* Complete the HMAC in the standard manner. */
for (i = 0; i < md_block_size; i++)
hmac_pad[i] ^= 0x6a;
- EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
- EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+ if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0)
+ goto err;
}
EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
if (md_out_size)
*md_out_size = md_out_size_u;
EVP_MD_CTX_cleanup(&md_ctx);
+
+ return 1;
+err:
+ EVP_MD_CTX_cleanup(&md_ctx);
+ return 0;
}
#ifdef OPENSSL_FIPS
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 35ad1217a655..0578a9c4e564 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1624,6 +1624,12 @@ int ssl3_get_key_exchange(SSL *s)
}
p += i;
+ if (BN_is_zero(dh->p)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
+ goto f_err;
+ }
+
+
if (2 > n - param_len) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1644,6 +1650,11 @@ int ssl3_get_key_exchange(SSL *s)
}
p += i;
+ if (BN_is_zero(dh->g)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+ goto f_err;
+ }
+
if (2 > n - param_len) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1665,6 +1676,11 @@ int ssl3_get_key_exchange(SSL *s)
p += i;
n -= param_len;
+ if (BN_is_zero(dh->pub_key)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE);
+ goto f_err;
+ }
+
# ifndef OPENSSL_NO_RSA
if (alg_a & SSL_aRSA)
pkey =
@@ -1867,14 +1883,20 @@ int ssl3_get_key_exchange(SSL *s)
q = md_buf;
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, param, param_len);
- EVP_DigestFinal_ex(&md_ctx, q, &size);
+ if (EVP_DigestInit_ex(&md_ctx,
+ (num == 2) ? s->ctx->md5 : s->ctx->sha1,
+ NULL) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
q += size;
j += size;
}
@@ -1893,12 +1915,16 @@ int ssl3_get_key_exchange(SSL *s)
} else
#endif
{
- EVP_VerifyInit_ex(&md_ctx, md, NULL);
- EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx, param, param_len);
+ if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0
+ || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto f_err;
+ }
if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
@@ -2118,6 +2144,7 @@ int ssl3_get_new_session_ticket(SSL *s)
long n;
const unsigned char *p;
unsigned char *d;
+ unsigned long ticket_lifetime_hint;
n = s->method->ssl_get_message(s,
SSL3_ST_CR_SESSION_TICKET_A,
@@ -2136,6 +2163,19 @@ int ssl3_get_new_session_ticket(SSL *s)
p = d = (unsigned char *)s->init_msg;
+ n2l(p, ticket_lifetime_hint);
+ n2s(p, ticklen);
+ /* ticket_lifetime_hint + ticket_length + ticket */
+ if (ticklen + 6 != n) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+
+ /* Server is allowed to change its mind and send an empty ticket. */
+ if (ticklen == 0)
+ return 1;
+
if (s->session->session_id_length > 0) {
int i = s->session_ctx->session_cache_mode;
SSL_SESSION *new_sess;
@@ -2167,14 +2207,6 @@ int ssl3_get_new_session_ticket(SSL *s)
s->session = new_sess;
}
- n2l(p, s->session->tlsext_tick_lifetime_hint);
- n2s(p, ticklen);
- /* ticket_lifetime_hint + ticket_length + ticket */
- if (ticklen + 6 != n) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
if (s->session->tlsext_tick) {
OPENSSL_free(s->session->tlsext_tick);
s->session->tlsext_ticklen = 0;
@@ -2185,6 +2217,7 @@ int ssl3_get_new_session_ticket(SSL *s)
goto err;
}
memcpy(s->session->tlsext_tick, p, ticklen);
+ s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
s->session->tlsext_ticklen = ticklen;
/*
* There are two ways to detect a resumed ticket session. One is to set
@@ -2354,6 +2387,7 @@ int ssl3_send_client_key_exchange(SSL *s)
|| (pkey->pkey.rsa == NULL)) {
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
+ EVP_PKEY_free(pkey);
goto err;
}
rsa = pkey->pkey.rsa;
@@ -2801,6 +2835,11 @@ int ssl3_send_client_key_exchange(SSL *s)
pkey_ctx = EVP_PKEY_CTX_new(pub_key =
X509_get_pubkey(peer_cert), NULL);
+ if (pkey_ctx == NULL) {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
/*
* If we have send a certificate, and certificate key
*
@@ -2810,10 +2849,13 @@ int ssl3_send_client_key_exchange(SSL *s)
/* Otherwise, generate ephemeral key pair */
- EVP_PKEY_encrypt_init(pkey_ctx);
- /* Generate session key */
- if (RAND_bytes(premaster_secret, 32) <= 0) {
+ if (pkey_ctx == NULL
+ || EVP_PKEY_encrypt_init(pkey_ctx) <= 0
+ /* Generate session key */
+ || RAND_bytes(premaster_secret, 32) <= 0) {
EVP_PKEY_CTX_free(pkey_ctx);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
goto err;
}
/*
@@ -2834,13 +2876,18 @@ int ssl3_send_client_key_exchange(SSL *s)
* data
*/
ukm_hash = EVP_MD_CTX_create();
- EVP_DigestInit(ukm_hash,
- EVP_get_digestbynid(NID_id_GostR3411_94));
- EVP_DigestUpdate(ukm_hash, s->s3->client_random,
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(ukm_hash, s->s3->server_random,
- SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
+ if (EVP_DigestInit(ukm_hash,
+ EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0
+ || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
+ EVP_MD_CTX_destroy(ukm_hash);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
EVP_MD_CTX_destroy(ukm_hash);
if (EVP_PKEY_CTX_ctrl
(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
@@ -2856,7 +2903,7 @@ int ssl3_send_client_key_exchange(SSL *s)
*(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
msglen = 255;
if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32)
- < 0) {
+ <= 0) {
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
SSL_R_LIBRARY_BUG);
goto err;
@@ -3057,7 +3104,10 @@ int ssl3_send_client_verify(SSL *s)
pkey = s->cert->key->privatekey;
/* Create context from key and test if sha1 is allowed as digest */
pctx = EVP_PKEY_CTX_new(pkey, NULL);
- EVP_PKEY_sign_init(pctx);
+ if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
if (TLS1_get_version(s) < TLS1_2_VERSION)
s->method->ssl3_enc->cert_verify_mac(s,
@@ -3194,7 +3244,6 @@ int ssl3_send_client_certificate(SSL *s)
* If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
* return(-1); We then get retied later
*/
- i = 0;
i = ssl_do_client_cert_cb(s, &x509, &pkey);
if (i < 0) {
s->rwstate = SSL_X509_LOOKUP;
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 152f40db582b..85ebac8d849a 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -253,7 +253,10 @@ int ssl3_change_cipher_state(SSL *s, int which)
EVP_CIPHER_CTX_init(s->enc_read_ctx);
dd = s->enc_read_ctx;
- ssl_replace_hash(&s->read_hash, m);
+ if (ssl_replace_hash(&s->read_hash, m) == NULL) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
#ifndef OPENSSL_NO_COMP
/* COMPRESS */
if (s->expand != NULL) {
@@ -288,7 +291,10 @@ int ssl3_change_cipher_state(SSL *s, int which)
*/
EVP_CIPHER_CTX_init(s->enc_write_ctx);
dd = s->enc_write_ctx;
- ssl_replace_hash(&s->write_hash, m);
+ if (ssl_replace_hash(&s->write_hash, m) == NULL) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
#ifndef OPENSSL_NO_COMP
/* COMPRESS */
if (s->compress != NULL) {
@@ -674,19 +680,21 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
return 0;
npad = (48 / n) * n;
- if (sender != NULL)
- EVP_DigestUpdate(&ctx, sender, len);
- EVP_DigestUpdate(&ctx, s->session->master_key,
- s->session->master_key_length);
- EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
- EVP_DigestFinal_ex(&ctx, md_buf, &i);
-
- EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
- EVP_DigestUpdate(&ctx, s->session->master_key,
- s->session->master_key_length);
- EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
- EVP_DigestUpdate(&ctx, md_buf, i);
- EVP_DigestFinal_ex(&ctx, p, &ret);
+ if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
+ || EVP_DigestUpdate(&ctx, s->session->master_key,
+ s->session->master_key_length) <= 0
+ || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0
+ || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0
+
+ || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0
+ || EVP_DigestUpdate(&ctx, s->session->master_key,
+ s->session->master_key_length) <= 0
+ || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0
+ || EVP_DigestUpdate(&ctx, md_buf, i) <= 0
+ || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) {
+ SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ }
EVP_MD_CTX_cleanup(&ctx);
@@ -758,33 +766,36 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
header[j++] = rec->length & 0xff;
/* Final param == is SSLv3 */
- ssl3_cbc_digest_record(hash,
- md, &md_size,
- header, rec->input,
- rec->length + md_size, orig_len,
- mac_sec, md_size, 1);
+ if (ssl3_cbc_digest_record(hash,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, orig_len,
+ mac_sec, md_size, 1) <= 0)
+ return -1;
} else {
unsigned int md_size_u;
/* Chop the digest off the end :-) */
EVP_MD_CTX_init(&md_ctx);
- EVP_MD_CTX_copy_ex(&md_ctx, hash);
- EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
- EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad);
- EVP_DigestUpdate(&md_ctx, seq, 8);
rec_char = rec->type;
- EVP_DigestUpdate(&md_ctx, &rec_char, 1);
p = md;
s2n(rec->length, p);
- EVP_DigestUpdate(&md_ctx, md, 2);
- EVP_DigestUpdate(&md_ctx, rec->input, rec->length);
- EVP_DigestFinal_ex(&md_ctx, md, NULL);
-
- EVP_MD_CTX_copy_ex(&md_ctx, hash);
- EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
- EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad);
- EVP_DigestUpdate(&md_ctx, md, md_size);
- EVP_DigestFinal_ex(&md_ctx, md, &md_size_u);
+ if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0
+ || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0
+ || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0
+ || EVP_DigestUpdate(&md_ctx, md, 2) <= 0
+ || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0
+ || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
+ || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0
+ || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) {
+ EVP_MD_CTX_cleanup(&md_ctx);
+ return -1;
+ }
md_size = md_size_u;
EVP_MD_CTX_cleanup(&md_ctx);
@@ -826,17 +837,24 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
EVP_MD_CTX_init(&ctx);
for (i = 0; i < 3; i++) {
- EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
- EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
- EVP_DigestUpdate(&ctx, p, len);
- EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(&ctx, buf, &n);
-
- EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
- EVP_DigestUpdate(&ctx, p, len);
- EVP_DigestUpdate(&ctx, buf, n);
- EVP_DigestFinal_ex(&ctx, out, &n);
+ if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0
+ || EVP_DigestUpdate(&ctx, salt[i],
+ strlen((const char *)salt[i])) <= 0
+ || EVP_DigestUpdate(&ctx, p, len) <= 0
+ || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0
+
+ || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0
+ || EVP_DigestUpdate(&ctx, p, len) <= 0
+ || EVP_DigestUpdate(&ctx, buf, n) <= 0
+ || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) {
+ SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ break;
+ }
out += n;
ret += n;
}
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index de917d3f836f..f716d77c812b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2955,7 +2955,7 @@ int ssl3_new(SSL *s)
void ssl3_free(SSL *s)
{
- if (s == NULL)
+ if (s == NULL || s->s3 == NULL)
return;
#ifdef TLSEXT_TYPE_opaque_prf_input
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 3a5f71d745fa..fcfc2fb9698f 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -383,7 +383,6 @@ int ssl3_accept(SSL *s)
*/
if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret = -1;
s->state = SSL_ST_ERR;
goto end;
@@ -967,7 +966,7 @@ int ssl3_check_client_hello(SSL *s)
int ssl3_get_client_hello(SSL *s)
{
- int i, j, ok, al, ret = -1;
+ int i, j, ok, al, ret = -1, cookie_valid = 0;
unsigned int cookie_len;
long n;
unsigned long id;
@@ -1155,8 +1154,7 @@ int ssl3_get_client_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
goto f_err;
}
-
- ret = 2;
+ cookie_valid = 1;
}
p += cookie_len;
@@ -1264,7 +1262,7 @@ int ssl3_get_client_hello(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
/* TLS extensions */
if (s->version >= SSL3_VERSION) {
- if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) {
+ if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) {
/* 'al' set by ssl_parse_clienthello_tlsext */
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
goto f_err;
@@ -1492,8 +1490,7 @@ int ssl3_get_client_hello(SSL *s)
}
}
- if (ret < 0)
- ret = 1;
+ ret = cookie_valid ? 2 : 1;
if (0) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -1503,7 +1500,7 @@ int ssl3_get_client_hello(SSL *s)
if (ciphers != NULL)
sk_SSL_CIPHER_free(ciphers);
- return (ret);
+ return ret;
}
int ssl3_send_server_hello(SSL *s)
@@ -1987,14 +1984,22 @@ int ssl3_send_server_key_exchange(SSL *s)
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[4]), n);
- EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
+ if (EVP_DigestInit_ex(&md_ctx,
+ (num == 2) ? s->ctx->md5
+ : s->ctx->sha1,
+ NULL) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(&md_ctx, &(d[4]), n) <= 0
+ || EVP_DigestFinal_ex(&md_ctx, q,
+ (unsigned int *)&i) <= 0) {
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
+ ERR_LIB_EVP);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
q += i;
j += i;
}
@@ -2024,16 +2029,17 @@ int ssl3_send_server_key_exchange(SSL *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[4]), 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[4]), n) <= 0
+ || EVP_SignFinal(&md_ctx, &(p[2]),
+ (unsigned int *)&i, pkey) <= 0) {
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
- goto err;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
}
s2n(i, p);
n += i + 2;
@@ -2879,7 +2885,15 @@ int ssl3_get_client_key_exchange(SSL *s)
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_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+ if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ goto gerr;
+ }
/*
* If client certificate is present and is of the same type, maybe
* use it for key exchange. Don't mind errors from
@@ -3123,7 +3137,17 @@ int ssl3_get_cert_verify(SSL *s)
unsigned char signature[64];
int idx;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
- EVP_PKEY_verify_init(pctx);
+ if (pctx == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+ if (EVP_PKEY_verify_init(pctx) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
if (i != 64) {
fprintf(stderr, "GOST signature length is %d", i);
}
diff --git a/ssl/ssl.h b/ssl/ssl.h
index d2ab0c074c99..b8456c692bd9 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2313,6 +2313,7 @@ void ERR_load_SSL_strings(void);
# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292
# define SSL_F_SSL3_ENC 134
# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238
+# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388
# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
# define SSL_F_SSL3_GET_CERT_STATUS 289
# define SSL_F_SSL3_GET_CERT_VERIFY 136
@@ -2465,8 +2466,11 @@ void ERR_load_SSL_strings(void);
# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106
# define SSL_R_BAD_DECOMPRESSION 107
# define SSL_R_BAD_DH_G_LENGTH 108
+# define SSL_R_BAD_DH_G_VALUE 375
# define SSL_R_BAD_DH_PUB_KEY_LENGTH 109
+# define SSL_R_BAD_DH_PUB_KEY_VALUE 393
# define SSL_R_BAD_DH_P_LENGTH 110
+# define SSL_R_BAD_DH_P_VALUE 395
# define SSL_R_BAD_DIGEST_LENGTH 111
# define SSL_R_BAD_DSA_SIGNATURE 112
# define SSL_R_BAD_ECC_CERT 304
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index 2dd54626588a..e9b1170d7b0e 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -263,6 +263,8 @@ extern "C" {
# define SSL3_SESSION_ID_SIZE 32
# define SSL3_RT_HEADER_LENGTH 5
+# define SSL3_HM_HEADER_LENGTH 4
+
# ifndef SSL3_ALIGN_PAYLOAD
/*
* Some will argue that this increases memory footprint, but it's not
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 39d48eabf03b..35cc27c5e985 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -121,13 +121,16 @@ typedef struct ssl_session_asn1_st {
int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
{
#define LSIZE2 (sizeof(long)*2)
- int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v7 = 0, v8 = 0;
+ int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0;
unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2];
unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2];
#ifndef OPENSSL_NO_TLSEXT
int v6 = 0, v9 = 0, v10 = 0;
unsigned char ibuf6[LSIZE2];
#endif
+#ifndef OPENSSL_NO_PSK
+ int v7 = 0, v8 = 0;
+#endif
#ifndef OPENSSL_NO_COMP
unsigned char cbuf;
int v11 = 0;
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 5df2413f7190..9a4e10414967 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -206,6 +206,7 @@ CERT *ssl_cert_dup(CERT *cert)
memset(ret, 0, sizeof(CERT));
+ ret->references = 1;
ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
/*
* or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
@@ -282,7 +283,6 @@ CERT *ssl_cert_dup(CERT *cert)
* chain is held inside SSL_CTX
*/
- ret->references = 1;
/*
* Set digests to defaults. NB: we don't copy existing values as they
* will be set during handshake.
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index cac525e86009..cb559d987f60 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -356,10 +356,11 @@ static int get_optional_pkey_id(const char *pkey_name)
const EVP_PKEY_ASN1_METHOD *ameth;
int pkey_id = 0;
ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1);
- if (ameth) {
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+ if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+ ameth) > 0) {
+ return pkey_id;
}
- return pkey_id;
+ return 0;
}
#else
@@ -371,7 +372,9 @@ static int get_optional_pkey_id(const char *pkey_name)
int pkey_id = 0;
ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1);
if (ameth) {
- EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+ if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+ ameth) <= 0)
+ pkey_id = 0;
}
if (tmpeng)
ENGINE_finish(tmpeng);
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 88621b72500f..caa671a27078 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -162,6 +162,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"},
{ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"},
{ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"},
+ {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET),
+ "ssl3_generate_master_secret"},
{ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),
"SSL3_GET_CERTIFICATE_REQUEST"},
{ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"},
@@ -369,8 +371,11 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
"bad data returned by callback"},
{ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"},
{ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"},
+ {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"},
{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"},
+ {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"},
{ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"},
+ {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"},
{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"},
{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"},
{ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index e11746a69508..93d1cbe438e4 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -307,6 +307,7 @@ SSL *SSL_new(SSL_CTX *ctx)
s->options = ctx->options;
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
+ s->references = 1;
if (ctx->cert != NULL) {
/*
@@ -375,7 +376,6 @@ SSL *SSL_new(SSL_CTX *ctx)
if (!s->method->ssl_new(s))
goto err;
- s->references = 1;
s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
SSL_clear(s);
@@ -3283,8 +3283,11 @@ EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
{
ssl_clear_hash_ctx(hash);
*hash = EVP_MD_CTX_create();
- if (md)
- EVP_DigestInit_ex(*hash, md, NULL);
+ if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
+ EVP_MD_CTX_destroy(*hash);
+ *hash = NULL;
+ return NULL;
+ }
return *hash;
}
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index a7f3f8dad4aa..f5d9df6bc0e6 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1154,7 +1154,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
unsigned char *limit);
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
- unsigned char *d, int n, int *al);
+ unsigned char *limit, int *al);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
unsigned char *d, int n, int *al);
int ssl_prepare_clienthello_tlsext(SSL *s);
@@ -1218,15 +1218,15 @@ int tls1_cbc_remove_padding(const SSL *s,
SSL3_RECORD *rec,
unsigned block_size, unsigned mac_size);
char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
-void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
- unsigned char *md_out,
- size_t *md_out_size,
- const unsigned char header[13],
- const unsigned char *data,
- size_t data_plus_mac_size,
- size_t data_plus_mac_plus_padding_size,
- const unsigned char *mac_secret,
- unsigned mac_secret_length, char is_sslv3);
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+ unsigned char *md_out,
+ size_t *md_out_size,
+ const unsigned char header[13],
+ const unsigned char *data,
+ size_t data_plus_mac_size,
+ size_t data_plus_mac_plus_padding_size,
+ const unsigned char *mac_secret,
+ unsigned mac_secret_length, char is_sslv3);
void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
EVP_MD_CTX *mac_ctx, const unsigned char *data,
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index daf15dd97e1c..c91a998185b1 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -160,7 +160,10 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
}
RSA_up_ref(rsa);
- EVP_PKEY_assign_RSA(pkey, rsa);
+ if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+ RSA_free(rsa);
+ return 0;
+ }
ret = ssl_set_pkey(ssl->cert, pkey);
EVP_PKEY_free(pkey);
@@ -181,6 +184,15 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
if (c->pkeys[i].x509 != NULL) {
EVP_PKEY *pktmp;
pktmp = X509_get_pubkey(c->pkeys[i].x509);
+ if (pktmp == NULL) {
+ SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE);
+ EVP_PKEY_free(pktmp);
+ return 0;
+ }
+ /*
+ * The return code from EVP_PKEY_copy_parameters is deliberately
+ * ignored. Some EVP_PKEY types cannot do this.
+ */
EVP_PKEY_copy_parameters(pktmp, pkey);
EVP_PKEY_free(pktmp);
ERR_clear_error();
@@ -382,6 +394,10 @@ static int ssl_set_cert(CERT *c, X509 *x)
}
if (c->pkeys[i].privatekey != NULL) {
+ /*
+ * The return code from EVP_PKEY_copy_parameters is deliberately
+ * ignored. Some EVP_PKEY types cannot do this.
+ */
EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
ERR_clear_error();
@@ -502,7 +518,10 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
}
RSA_up_ref(rsa);
- EVP_PKEY_assign_RSA(pkey, rsa);
+ if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+ RSA_free(rsa);
+ return 0;
+ }
ret = ssl_set_pkey(ctx->cert, pkey);
EVP_PKEY_free(pkey);
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 1ad9dc79493c..de4c59e21fec 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -256,8 +256,8 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
dest->tlsext_ecpointformatlist = NULL;
dest->tlsext_ellipticcurvelist = NULL;
# endif
-#endif
dest->tlsext_tick = NULL;
+#endif
#ifndef OPENSSL_NO_SRP
dest->srp_username = NULL;
#endif
@@ -324,7 +324,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
goto err;
}
# endif
-#endif
if (ticket != 0) {
dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
@@ -334,6 +333,7 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
dest->tlsext_tick_lifetime_hint = 0;
dest->tlsext_ticklen = 0;
}
+#endif
#ifndef OPENSSL_NO_SRP
if (src->srp_username) {
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 6a0c293aa5ae..349ee1e03e86 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -142,6 +142,7 @@
/* Or gethostname won't be declared properly on Linux and GNU platforms. */
#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
#include <assert.h>
#include <errno.h>
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 8f45294e5579..985356d74b2a 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -385,6 +385,8 @@ int tls1_change_cipher_state(SSL *s, int which)
EVP_CIPHER_CTX_init(s->enc_read_ctx);
dd = s->enc_read_ctx;
mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
+ if (mac_ctx == NULL)
+ goto err;
#ifndef OPENSSL_NO_COMP
if (s->expand != NULL) {
COMP_CTX_free(s->expand);
@@ -423,11 +425,14 @@ int tls1_change_cipher_state(SSL *s, int which)
dd = s->enc_write_ctx;
if (SSL_IS_DTLS(s)) {
mac_ctx = EVP_MD_CTX_create();
- if (!mac_ctx)
+ if (mac_ctx == NULL)
goto err;
s->write_hash = mac_ctx;
- } else
+ } else {
mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
+ if (mac_ctx == NULL)
+ goto err;
+ }
#ifndef OPENSSL_NO_COMP
if (s->compress != NULL) {
COMP_CTX_free(s->compress);
@@ -500,7 +505,12 @@ int tls1_change_cipher_state(SSL *s, int which)
if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
mac_secret, *mac_secret_size);
- EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key);
+ if (mac_key == NULL
+ || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) {
+ EVP_PKEY_free(mac_key);
+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
EVP_PKEY_free(mac_key);
}
#ifdef TLS_DEBUG
@@ -913,8 +923,9 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
}
EVP_MD_CTX_init(&ctx);
- EVP_MD_CTX_copy_ex(&ctx, d);
- EVP_DigestFinal_ex(&ctx, out, &ret);
+ if (EVP_MD_CTX_copy_ex(&ctx, d) <=0
+ || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0)
+ ret = 0;
EVP_MD_CTX_cleanup(&ctx);
return ((int)ret);
}
@@ -1041,17 +1052,24 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
* are hashing because that gives an attacker a timing-oracle.
*/
/* Final param == not SSLv3 */
- ssl3_cbc_digest_record(mac_ctx,
- md, &md_size,
- header, rec->input,
- rec->length + md_size, orig_len,
- ssl->s3->read_mac_secret,
- ssl->s3->read_mac_secret_size, 0);
+ if (ssl3_cbc_digest_record(mac_ctx,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, orig_len,
+ ssl->s3->read_mac_secret,
+ ssl->s3->read_mac_secret_size, 0) <= 0) {
+ if (!stream_mac)
+ EVP_MD_CTX_cleanup(&hmac);
+ return -1;
+ }
} else {
- EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
- EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
- t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
- OPENSSL_assert(t > 0);
+ if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
+ || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
+ if (!stream_mac)
+ EVP_MD_CTX_cleanup(&hmac);
+ return -1;
+ }
#ifdef OPENSSL_FIPS
if (!send && FIPS_mode())
tls_fips_digest_extra(ssl->enc_read_ctx,
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index d70b93feadf0..27f1216c5761 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -913,7 +913,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
* 10.8..10.8.3 (which don't work).
*/
static void ssl_check_for_safari(SSL *s, const unsigned char *data,
- const unsigned char *d, int n)
+ const unsigned char *limit)
{
unsigned short type, size;
static const unsigned char kSafariExtensionsBlock[] = {
@@ -942,11 +942,11 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
0x02, 0x03, /* SHA-1/ECDSA */
};
- if (data >= (d + n - 2))
+ if (data >= (limit - 2))
return;
data += 2;
- if (data > (d + n - 4))
+ if (data > (limit - 4))
return;
n2s(data, type);
n2s(data, size);
@@ -954,7 +954,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
if (type != TLSEXT_TYPE_server_name)
return;
- if (data + size > d + n)
+ if (data + size > limit)
return;
data += size;
@@ -962,7 +962,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
const size_t len1 = sizeof(kSafariExtensionsBlock);
const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
- if (data + len1 + len2 != d + n)
+ if (data + len1 + len2 != limit)
return;
if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
return;
@@ -971,7 +971,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
} else {
const size_t len = sizeof(kSafariExtensionsBlock);
- if (data + len != d + n)
+ if (data + len != limit)
return;
if (memcmp(data, kSafariExtensionsBlock, len) != 0)
return;
@@ -981,8 +981,8 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
}
# endif /* !OPENSSL_NO_EC */
-int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
- int n, int *al)
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
+ unsigned char *limit, int *al)
{
unsigned short type;
unsigned short size;
@@ -1004,7 +1004,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
# ifndef OPENSSL_NO_EC
if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
- ssl_check_for_safari(s, data, d, n);
+ ssl_check_for_safari(s, data, limit);
# endif /* !OPENSSL_NO_EC */
# ifndef OPENSSL_NO_SRP
@@ -1016,22 +1016,22 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
s->srtp_profile = NULL;
- if (data == d + n)
+ if (data == limit)
goto ri_check;
- if (data > (d + n - 2))
+ if (data > (limit - 2))
goto err;
n2s(data, len);
- if (data > (d + n - len))
+ if (data + len != limit)
goto err;
- while (data <= (d + n - 4)) {
+ while (data <= (limit - 4)) {
n2s(data, type);
n2s(data, size);
- if (data + size > (d + n))
+ if (data + size > (limit))
goto err;
# if 0
fprintf(stderr, "Received extension type %d size %d\n", type, size);
@@ -1396,7 +1396,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
}
/* Spurious data on the end */
- if (data != d + n)
+ if (data != limit)
goto err;
*p = data;
@@ -2291,10 +2291,13 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
/* Check key name matches */
if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
return 2;
- HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
- tlsext_tick_md(), NULL);
- EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- tctx->tlsext_tick_aes_key, etick + 16);
+ if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+ tlsext_tick_md(), NULL) <= 0
+ || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ tctx->tlsext_tick_aes_key,
+ etick + 16) <= 0) {
+ goto err;
+ }
}
/*
* Attempt to process session ticket, first conduct sanity and integrity
@@ -2302,13 +2305,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
*/
mlen = HMAC_size(&hctx);
if (mlen < 0) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
+ goto err;
}
eticklen -= mlen;
/* Check HMAC of encrypted ticket */
- HMAC_Update(&hctx, etick, eticklen);
- HMAC_Final(&hctx, tick_hmac, NULL);
+ if (HMAC_Update(&hctx, etick, eticklen) <= 0
+ || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
+ goto err;
+ }
HMAC_CTX_cleanup(&hctx);
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
EVP_CIPHER_CTX_cleanup(&ctx);
@@ -2319,11 +2323,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
sdec = OPENSSL_malloc(eticklen);
- if (!sdec) {
+ if (!sdec || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
EVP_CIPHER_CTX_cleanup(&ctx);
return -1;
}
- EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
EVP_CIPHER_CTX_cleanup(&ctx);
OPENSSL_free(sdec);
@@ -2356,6 +2359,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
* For session parse failure, indicate that we need to send a new ticket.
*/
return 2;
+err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ HMAC_CTX_cleanup(&hctx);
+ return -1;
}
/* Tables to translate from NIDs to TLS v1.2 ids */
diff --git a/ssl/tls1.h b/ssl/tls1.h
index 69d8186a4e24..91504b17e896 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -235,8 +235,7 @@ extern "C" {
/*
* ExtensionType value for TLS padding extension.
- * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
- * http://tools.ietf.org/html/draft-agl-tls-padding-03
+ * http://tools.ietf.org/html/draft-agl-tls-padding
*/
# define TLSEXT_TYPE_padding 21
@@ -261,20 +260,19 @@ extern "C" {
# define TLSEXT_TYPE_next_proto_neg 13172
# endif
-/* NameType value from RFC 3546 */
+/* NameType value from RFC3546 */
# define TLSEXT_NAMETYPE_host_name 0
-/* status request value from RFC 3546 */
+/* status request value from RFC3546 */
# define TLSEXT_STATUSTYPE_ocsp 1
-/* ECPointFormat values from draft-ietf-tls-ecc-12 */
+/* ECPointFormat values from RFC4492 */
# define TLSEXT_ECPOINTFORMAT_first 0
# define TLSEXT_ECPOINTFORMAT_uncompressed 0
# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1
# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2
# define TLSEXT_ECPOINTFORMAT_last 2
-/* Signature and hash algorithms from RFC 5246 */
-
+/* Signature and hash algorithms from RFC5246 */
# define TLSEXT_signature_anonymous 0
# define TLSEXT_signature_rsa 1
# define TLSEXT_signature_dsa 2
@@ -404,7 +402,6 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066
/* AES ciphersuites from RFC3268 */
-
# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F
# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030
# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031
@@ -570,7 +567,7 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA"
# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA"
-/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */
+/* ECC ciphersuites from RFC4492 */
# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA"
# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA"
# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA"