summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libssl/src/ssl/d1_clnt.c10
-rw-r--r--lib/libssl/src/ssl/s3_clnt.c85
-rw-r--r--lib/libssl/src/ssl/s3_srvr.c106
3 files changed, 148 insertions, 53 deletions
diff --git a/lib/libssl/src/ssl/d1_clnt.c b/lib/libssl/src/ssl/d1_clnt.c
index 3f47a3854b2..b85908c7330 100644
--- a/lib/libssl/src/ssl/d1_clnt.c
+++ b/lib/libssl/src/ssl/d1_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: d1_clnt.c,v 1.28 2014/07/11 09:24:44 beck Exp $ */
+/* $OpenBSD: d1_clnt.c,v 1.29 2014/07/11 22:57:25 miod Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -879,6 +879,8 @@ dtls1_get_hello_verify(SSL *s)
return (1);
}
+ if (2 > n)
+ goto truncated;
data = (unsigned char *)s->init_msg;
if ((data[0] != (s->version >> 8)) || (data[1] != (s->version&0xff))) {
@@ -889,7 +891,11 @@ dtls1_get_hello_verify(SSL *s)
}
data += 2;
+ if (2 + 1 > n)
+ goto truncated;
cookie_len = *(data++);
+ if (2 + 1 + cookie_len > n)
+ goto truncated;
if (cookie_len > sizeof(s->d1->cookie)) {
al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
@@ -901,6 +907,8 @@ dtls1_get_hello_verify(SSL *s)
s->d1->send_cookie = 1;
return 1;
+truncated:
+ al = SSL_AD_DECODE_ERROR;
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
return -1;
diff --git a/lib/libssl/src/ssl/s3_clnt.c b/lib/libssl/src/ssl/s3_clnt.c
index 3596acf1de5..884b9f1efb8 100644
--- a/lib/libssl/src/ssl/s3_clnt.c
+++ b/lib/libssl/src/ssl/s3_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_clnt.c,v 1.77 2014/07/11 15:44:53 miod Exp $ */
+/* $OpenBSD: s3_clnt.c,v 1.78 2014/07/11 22:57:25 miod Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -814,6 +814,8 @@ ssl3_get_server_hello(SSL *s)
d = p = (unsigned char *)s->init_msg;
+ if (2 > n)
+ goto truncated;
if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) {
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION);
s->version = (s->version&0xff00) | p[1];
@@ -823,6 +825,10 @@ ssl3_get_server_hello(SSL *s)
p += 2;
/* load the server hello data */
+
+ if (p + SSL3_RANDOM_SIZE + 1 - d > n)
+ goto truncated;
+
/* load the server random */
memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE);
p += SSL3_RANDOM_SIZE;
@@ -838,6 +844,9 @@ ssl3_get_server_hello(SSL *s)
goto f_err;
}
+ if (p + j + 2 - d > n)
+ goto truncated;
+
/*
* Check if we want to resume the session based on external
* pre-shared secret
@@ -935,6 +944,8 @@ ssl3_get_server_hello(SSL *s)
}
/* lets get the compression algorithm */
/* COMPRESSION */
+ if (p + 1 - d > n)
+ goto truncated;
if (*(p++) != 0) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
@@ -958,15 +969,15 @@ ssl3_get_server_hello(SSL *s)
}
}
- if (p != (d + n)) {
- /* wrong packet length */
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
- SSL_R_BAD_PACKET_LENGTH);
- goto f_err;
- }
+ if (p != d + n)
+ goto truncated;
return (1);
+
+truncated:
+ /* wrong packet length */
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
@@ -1015,6 +1026,8 @@ ssl3_get_server_certificate(SSL *s)
goto err;
}
+ if (p + 3 - d > n)
+ goto truncated;
n2l3(p, llen);
if (llen + 3 != n) {
al = SSL_AD_DECODE_ERROR;
@@ -1023,6 +1036,8 @@ ssl3_get_server_certificate(SSL *s)
goto f_err;
}
for (nc = 0; nc < llen; ) {
+ if (p + 3 - d > n)
+ goto truncated;
n2l3(p, l);
if ((l + nc + 3) > llen) {
al = SSL_AD_DECODE_ERROR;
@@ -1094,7 +1109,7 @@ ssl3_get_server_certificate(SSL *s)
x = NULL;
al = SSL3_AL_FATAL;
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
- SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
+ SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
goto f_err;
}
@@ -1103,7 +1118,7 @@ ssl3_get_server_certificate(SSL *s)
x = NULL;
al = SSL3_AL_FATAL;
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
- SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ SSL_R_UNKNOWN_CERTIFICATE_TYPE);
goto f_err;
}
@@ -1137,6 +1152,11 @@ ssl3_get_server_certificate(SSL *s)
ret = 1;
if (0) {
+truncated:
+ /* wrong packet length */
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+ SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}
@@ -1206,6 +1226,8 @@ ssl3_get_key_exchange(SSL *s)
ERR_R_MALLOC_FAILURE);
goto err;
}
+ if (2 > n)
+ goto truncated;
n2s(p, i);
param_len = i + 2;
if (param_len > n) {
@@ -1221,6 +1243,8 @@ ssl3_get_key_exchange(SSL *s)
}
p += i;
+ if (param_len + 2 > n)
+ goto truncated;
n2s(p, i);
param_len += i + 2;
if (param_len > n) {
@@ -1258,6 +1282,8 @@ ssl3_get_key_exchange(SSL *s)
ERR_R_DH_LIB);
goto err;
}
+ if (2 > n)
+ goto truncated;
n2s(p, i);
param_len = i + 2;
if (param_len > n) {
@@ -1273,6 +1299,8 @@ ssl3_get_key_exchange(SSL *s)
}
p += i;
+ if (param_len + 2 > n)
+ goto truncated;
n2s(p, i);
param_len += i + 2;
if (param_len > n) {
@@ -1288,6 +1316,8 @@ ssl3_get_key_exchange(SSL *s)
}
p += i;
+ if (param_len + 2 > n)
+ goto truncated;
n2s(p, i);
param_len += i + 2;
if (param_len > n) {
@@ -1376,6 +1406,8 @@ ssl3_get_key_exchange(SSL *s)
goto err;
}
+ if (param_len + 1 > n)
+ goto truncated;
encoded_pt_len = *p;
/* length of encoded point */
p += 1;
@@ -1435,6 +1467,8 @@ ssl3_get_key_exchange(SSL *s)
* Check key type is consistent
* with signature
*/
+ if (2 > n)
+ goto truncated;
if (sigalg != (int)p[1]) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_WRONG_SIGNATURE_TYPE);
@@ -1453,11 +1487,13 @@ ssl3_get_key_exchange(SSL *s)
} else
md = EVP_sha1();
+ if (2 > n)
+ goto truncated;
n2s(p, i);
n -= 2;
j = EVP_PKEY_size(pkey);
- if ((i != n) || (n > j) || (n <= 0)) {
+ if (i != n || n > j) {
/* wrong packet length */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
@@ -1534,6 +1570,10 @@ ssl3_get_key_exchange(SSL *s)
EVP_PKEY_free(pkey);
EVP_MD_CTX_cleanup(&md_ctx);
return (1);
+truncated:
+ /* wrong packet length */
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
@@ -1606,13 +1646,26 @@ ssl3_get_certificate_request(SSL *s)
}
/* get the certificate types */
+ if (1 > n)
+ goto truncated;
ctype_num= *(p++);
if (ctype_num > SSL3_CT_NUMBER)
ctype_num = SSL3_CT_NUMBER;
+ if (p + ctype_num - d > n) {
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
+ SSL_R_DATA_LENGTH_TOO_LONG);
+ goto err;
+ }
+
for (i = 0; i < ctype_num; i++)
s->s3->tmp.ctype[i] = p[i];
p += ctype_num;
if (SSL_USE_SIGALGS(s)) {
+ if (p + 2 - d > n) {
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
+ SSL_R_DATA_LENGTH_TOO_LONG);
+ goto err;
+ }
n2s(p, llen);
/* Check we have enough room for signature algorithms and
* following length value.
@@ -1633,6 +1686,11 @@ ssl3_get_certificate_request(SSL *s)
}
/* get the CA RDNs */
+ if (p + 2 - d > n) {
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
+ SSL_R_DATA_LENGTH_TOO_LONG);
+ goto err;
+ }
n2s(p, llen);
if ((unsigned long)(p - d + llen) != n) {
@@ -1698,6 +1756,11 @@ cont:
ca_sk = NULL;
ret = 1;
+ if (0) {
+truncated:
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
+ SSL_R_BAD_PACKET_LENGTH);
+ }
err:
if (ca_sk != NULL)
sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
diff --git a/lib/libssl/src/ssl/s3_srvr.c b/lib/libssl/src/ssl/s3_srvr.c
index 66a4552237d..89325b7be90 100644
--- a/lib/libssl/src/ssl/s3_srvr.c
+++ b/lib/libssl/src/ssl/s3_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_srvr.c,v 1.74 2014/07/11 15:18:52 miod Exp $ */
+/* $OpenBSD: s3_srvr.c,v 1.75 2014/07/11 22:57:25 miod Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -894,18 +894,17 @@ ssl3_get_client_hello(SSL *s)
s->state = SSL3_ST_SR_CLNT_HELLO_B;
}
s->first_packet = 1;
- n = s->method->ssl_get_message(s,
- SSL3_ST_SR_CLNT_HELLO_B,
- SSL3_ST_SR_CLNT_HELLO_C,
- SSL3_MT_CLIENT_HELLO,
- SSL3_RT_MAX_PLAIN_LENGTH,
- &ok);
+ n = s->method->ssl_get_message(s, SSL3_ST_SR_CLNT_HELLO_B,
+ SSL3_ST_SR_CLNT_HELLO_C, SSL3_MT_CLIENT_HELLO,
+ SSL3_RT_MAX_PLAIN_LENGTH, &ok);
if (!ok)
return ((int)n);
s->first_packet = 0;
- d = p=(unsigned char *)s->init_msg;
+ d = p = (unsigned char *)s->init_msg;
+ if (2 > n)
+ goto truncated;
/*
* Use version from inside client hello, not from record header.
* (may differ: see RFC 2246, Appendix E, second paragraph)
@@ -944,12 +943,17 @@ ssl3_get_client_hello(SSL *s)
return (1);
}
+ if (p + SSL3_RANDOM_SIZE + 1 - d > n)
+ goto truncated;
+
/* load the client random */
memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE);
p += SSL3_RANDOM_SIZE;
/* get the session-id */
j= *(p++);
+ if (p + j - d > n)
+ goto truncated;
s->hit = 0;
/*
@@ -988,6 +992,8 @@ ssl3_get_client_hello(SSL *s)
if (SSL_IS_DTLS(s)) {
/* cookie stuff */
+ if (p + 1 - d > n)
+ goto truncated;
cookie_len = *(p++);
/*
@@ -1003,6 +1009,9 @@ ssl3_get_client_hello(SSL *s)
goto f_err;
}
+ if (p + cookie_len - d > n)
+ goto truncated;
+
/* verify the cookie if appropriate option is set. */
if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
cookie_len > 0) {
@@ -1032,6 +1041,8 @@ ssl3_get_client_hello(SSL *s)
p += cookie_len;
}
+ if (p + 2 - d > n)
+ goto truncated;
n2s(p, i);
if ((i == 0) && (j != 0)) {
/* we need a cipher if we are not resuming a session */
@@ -1040,13 +1051,8 @@ ssl3_get_client_hello(SSL *s)
SSL_R_NO_CIPHERS_SPECIFIED);
goto f_err;
}
- if ((p + i) >= (d + n)) {
- /* not enough data */
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
- SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
+ if (p + i - d > n)
+ goto truncated;
if ((i > 0) &&
(ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL)) {
goto err;
@@ -1078,14 +1084,11 @@ ssl3_get_client_hello(SSL *s)
}
/* compression */
+ if (p + 1 - d > n)
+ goto truncated;
i= *(p++);
- if ((p + i) > (d + n)) {
- /* not enough data */
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
- SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
+ if (p + i - d > n)
+ goto truncated;
for (j = 0; j < i; j++) {
if (p[j] == 0)
break;
@@ -1247,6 +1250,9 @@ ssl3_get_client_hello(SSL *s)
if (ret < 0)
ret = 1;
if (0) {
+truncated:
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}
@@ -1847,7 +1853,7 @@ ssl3_get_client_key_exchange(SSL *s)
int i, al, ok;
long n;
unsigned long alg_k;
- unsigned char *p;
+ unsigned char *d, *p;
RSA *rsa = NULL;
EVP_PKEY *pkey = NULL;
BIGNUM *pub = NULL;
@@ -1863,7 +1869,7 @@ ssl3_get_client_key_exchange(SSL *s)
SSL3_ST_SR_KEY_EXCH_B, SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok);
if (!ok)
return ((int)n);
- p = (unsigned char *)s->init_msg;
+ d = p = (unsigned char *)s->init_msg;
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
@@ -1897,6 +1903,8 @@ ssl3_get_client_key_exchange(SSL *s)
/* TLS and [incidentally] DTLS{0xFEFF} */
if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) {
+ if (2 > n)
+ goto truncated;
n2s(p, i);
if (n != i + 2) {
if (!(s->options & SSL_OP_TLS_D5_BUG)) {
@@ -1919,6 +1927,8 @@ ssl3_get_client_key_exchange(SSL *s)
/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
}
+ if (p + 2 - d > n) /* needed in the SSL3 case */
+ goto truncated;
if ((al == -1) && !((p[0] == (s->client_version >> 8)) &&
(p[1] == (s->client_version & 0xff)))) {
/*
@@ -1975,6 +1985,8 @@ ssl3_get_client_key_exchange(SSL *s)
OPENSSL_cleanse(p, i);
} else
if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) {
+ if (2 > n)
+ goto truncated;
n2s(p, i);
if (n != i + 2) {
if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) {
@@ -2206,6 +2218,8 @@ ssl3_get_client_key_exchange(SSL *s)
client_pub_pkey) <= 0)
ERR_clear_error();
}
+ if (2 > n)
+ goto truncated;
/* Decrypt session key */
if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag,
&Tclass, n) != V_ASN1_CONSTRUCTED ||
@@ -2242,11 +2256,14 @@ gerr:
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
- SSL_R_UNKNOWN_CIPHER_TYPE);
+ SSL_R_UNKNOWN_CIPHER_TYPE);
goto f_err;
}
return (1);
+truncated:
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
@@ -2338,6 +2355,8 @@ ssl3_get_cert_verify(SSL *s)
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
+ if (2 > n)
+ goto truncated;
/* Check key type is consistent with signature */
if (sigalg != (int)p[1]) {
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
@@ -2355,14 +2374,12 @@ ssl3_get_cert_verify(SSL *s)
p += 2;
n -= 2;
}
+ if (2 > n)
+ goto truncated;
n2s(p, i);
n -= 2;
- if (i > n) {
- SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
- SSL_R_LENGTH_MISMATCH);
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
+ if (i > n)
+ goto truncated;
}
j = EVP_PKEY_size(pkey);
if ((i > j) || (n > j) || (n <= 0)) {
@@ -2445,7 +2462,10 @@ ssl3_get_cert_verify(SSL *s)
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_verify_init(pctx);
if (i != 64) {
- fprintf(stderr, "GOST signature length is %d", i);
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
+ SSL_R_WRONG_SIGNATURE_SIZE);
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
}
for (idx = 0; idx < 64; idx++) {
signature[63 - idx] = p[idx];
@@ -2469,6 +2489,9 @@ ssl3_get_cert_verify(SSL *s)
ret = 1;
if (0) {
+truncated:
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}
@@ -2490,7 +2513,6 @@ ssl3_get_client_certificate(SSL *s)
X509 *x = NULL;
unsigned long l, nc, llen, n;
const unsigned char *p, *q;
- unsigned char *d;
STACK_OF(X509) *sk = NULL;
n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B,
@@ -2528,7 +2550,7 @@ ssl3_get_client_certificate(SSL *s)
SSL_R_WRONG_MESSAGE_TYPE);
goto f_err;
}
- p = d = (unsigned char *)s->init_msg;
+ p = (const unsigned char *)s->init_msg;
if ((sk = sk_X509_new_null()) == NULL) {
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
@@ -2536,16 +2558,14 @@ ssl3_get_client_certificate(SSL *s)
goto err;
}
+ if (3 > n)
+ goto truncated;
n2l3(p, llen);
- if (llen + 3 != n) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
- SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
+ if (llen + 3 != n)
+ goto truncated;
for (nc = 0; nc < llen;) {
n2l3(p, l);
- if ((l + nc + 3) > llen) {
+ if (l + nc + 3 > llen) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
SSL_R_CERT_LENGTH_MISMATCH);
@@ -2635,6 +2655,10 @@ ssl3_get_client_certificate(SSL *s)
ret = 1;
if (0) {
+truncated:
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
+ SSL_R_BAD_PACKET_LENGTH);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}