summaryrefslogtreecommitdiff
path: root/src/lib/libssl/s3_clnt.c
diff options
context:
space:
mode:
authormiod <>2014-07-11 22:57:25 +0000
committermiod <>2014-07-11 22:57:25 +0000
commitc95157e4b6c5e281cb496ef41f9969df25abef91 (patch)
treed76e443b574ed3f2bb44b4cd1fdacdba22613ea8 /src/lib/libssl/s3_clnt.c
parent994822f5ed5b52cdb013f4acc6ea695367f1bd47 (diff)
downloadopenbsd-c95157e4b6c5e281cb496ef41f9969df25abef91.tar.gz
openbsd-c95157e4b6c5e281cb496ef41f9969df25abef91.tar.bz2
openbsd-c95157e4b6c5e281cb496ef41f9969df25abef91.zip
As reported by David Ramos, most consumer of ssl_get_message() perform late
bounds check, after reading the 2-, 3- or 4-byte size of the next chunk to process. But the size fields themselves are not checked for being entirely contained in the buffer. Since reading past your bounds is bad practice, and may not possible if you are using a secure memory allocator, we need to add the necessary bounds check, at the expense of some readability. As a bonus, a wrong size GOST session key will now trigger an error instead of a printf to stderr and it being handled as if it had the correct size. Creating this diff made my eyes bleed (in the real sense); reviewing it made guenther@'s and beck@'s eyes bleed too (in the literal sense). ok guenther@ beck@
Diffstat (limited to 'src/lib/libssl/s3_clnt.c')
-rw-r--r--src/lib/libssl/s3_clnt.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c
index 3596acf1de..884b9f1efb 100644
--- a/src/lib/libssl/s3_clnt.c
+++ b/src/lib/libssl/s3_clnt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s3_clnt.c,v 1.77 2014/07/11 15:44:53 miod Exp $ */ 1/* $OpenBSD: s3_clnt.c,v 1.78 2014/07/11 22:57:25 miod Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -814,6 +814,8 @@ ssl3_get_server_hello(SSL *s)
814 814
815 d = p = (unsigned char *)s->init_msg; 815 d = p = (unsigned char *)s->init_msg;
816 816
817 if (2 > n)
818 goto truncated;
817 if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { 819 if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) {
818 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); 820 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION);
819 s->version = (s->version&0xff00) | p[1]; 821 s->version = (s->version&0xff00) | p[1];
@@ -823,6 +825,10 @@ ssl3_get_server_hello(SSL *s)
823 p += 2; 825 p += 2;
824 826
825 /* load the server hello data */ 827 /* load the server hello data */
828
829 if (p + SSL3_RANDOM_SIZE + 1 - d > n)
830 goto truncated;
831
826 /* load the server random */ 832 /* load the server random */
827 memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); 833 memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE);
828 p += SSL3_RANDOM_SIZE; 834 p += SSL3_RANDOM_SIZE;
@@ -838,6 +844,9 @@ ssl3_get_server_hello(SSL *s)
838 goto f_err; 844 goto f_err;
839 } 845 }
840 846
847 if (p + j + 2 - d > n)
848 goto truncated;
849
841 /* 850 /*
842 * Check if we want to resume the session based on external 851 * Check if we want to resume the session based on external
843 * pre-shared secret 852 * pre-shared secret
@@ -935,6 +944,8 @@ ssl3_get_server_hello(SSL *s)
935 } 944 }
936 /* lets get the compression algorithm */ 945 /* lets get the compression algorithm */
937 /* COMPRESSION */ 946 /* COMPRESSION */
947 if (p + 1 - d > n)
948 goto truncated;
938 if (*(p++) != 0) { 949 if (*(p++) != 0) {
939 al = SSL_AD_ILLEGAL_PARAMETER; 950 al = SSL_AD_ILLEGAL_PARAMETER;
940 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, 951 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
@@ -958,15 +969,15 @@ ssl3_get_server_hello(SSL *s)
958 } 969 }
959 } 970 }
960 971
961 if (p != (d + n)) { 972 if (p != d + n)
962 /* wrong packet length */ 973 goto truncated;
963 al = SSL_AD_DECODE_ERROR;
964 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
965 SSL_R_BAD_PACKET_LENGTH);
966 goto f_err;
967 }
968 974
969 return (1); 975 return (1);
976
977truncated:
978 /* wrong packet length */
979 al = SSL_AD_DECODE_ERROR;
980 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH);
970f_err: 981f_err:
971 ssl3_send_alert(s, SSL3_AL_FATAL, al); 982 ssl3_send_alert(s, SSL3_AL_FATAL, al);
972err: 983err:
@@ -1015,6 +1026,8 @@ ssl3_get_server_certificate(SSL *s)
1015 goto err; 1026 goto err;
1016 } 1027 }
1017 1028
1029 if (p + 3 - d > n)
1030 goto truncated;
1018 n2l3(p, llen); 1031 n2l3(p, llen);
1019 if (llen + 3 != n) { 1032 if (llen + 3 != n) {
1020 al = SSL_AD_DECODE_ERROR; 1033 al = SSL_AD_DECODE_ERROR;
@@ -1023,6 +1036,8 @@ ssl3_get_server_certificate(SSL *s)
1023 goto f_err; 1036 goto f_err;
1024 } 1037 }
1025 for (nc = 0; nc < llen; ) { 1038 for (nc = 0; nc < llen; ) {
1039 if (p + 3 - d > n)
1040 goto truncated;
1026 n2l3(p, l); 1041 n2l3(p, l);
1027 if ((l + nc + 3) > llen) { 1042 if ((l + nc + 3) > llen) {
1028 al = SSL_AD_DECODE_ERROR; 1043 al = SSL_AD_DECODE_ERROR;
@@ -1094,7 +1109,7 @@ ssl3_get_server_certificate(SSL *s)
1094 x = NULL; 1109 x = NULL;
1095 al = SSL3_AL_FATAL; 1110 al = SSL3_AL_FATAL;
1096 SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, 1111 SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
1097 SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); 1112 SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
1098 goto f_err; 1113 goto f_err;
1099 } 1114 }
1100 1115
@@ -1103,7 +1118,7 @@ ssl3_get_server_certificate(SSL *s)
1103 x = NULL; 1118 x = NULL;
1104 al = SSL3_AL_FATAL; 1119 al = SSL3_AL_FATAL;
1105 SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, 1120 SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
1106 SSL_R_UNKNOWN_CERTIFICATE_TYPE); 1121 SSL_R_UNKNOWN_CERTIFICATE_TYPE);
1107 goto f_err; 1122 goto f_err;
1108 } 1123 }
1109 1124
@@ -1137,6 +1152,11 @@ ssl3_get_server_certificate(SSL *s)
1137 ret = 1; 1152 ret = 1;
1138 1153
1139 if (0) { 1154 if (0) {
1155truncated:
1156 /* wrong packet length */
1157 al = SSL_AD_DECODE_ERROR;
1158 SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
1159 SSL_R_BAD_PACKET_LENGTH);
1140f_err: 1160f_err:
1141 ssl3_send_alert(s, SSL3_AL_FATAL, al); 1161 ssl3_send_alert(s, SSL3_AL_FATAL, al);
1142 } 1162 }
@@ -1206,6 +1226,8 @@ ssl3_get_key_exchange(SSL *s)
1206 ERR_R_MALLOC_FAILURE); 1226 ERR_R_MALLOC_FAILURE);
1207 goto err; 1227 goto err;
1208 } 1228 }
1229 if (2 > n)
1230 goto truncated;
1209 n2s(p, i); 1231 n2s(p, i);
1210 param_len = i + 2; 1232 param_len = i + 2;
1211 if (param_len > n) { 1233 if (param_len > n) {
@@ -1221,6 +1243,8 @@ ssl3_get_key_exchange(SSL *s)
1221 } 1243 }
1222 p += i; 1244 p += i;
1223 1245
1246 if (param_len + 2 > n)
1247 goto truncated;
1224 n2s(p, i); 1248 n2s(p, i);
1225 param_len += i + 2; 1249 param_len += i + 2;
1226 if (param_len > n) { 1250 if (param_len > n) {
@@ -1258,6 +1282,8 @@ ssl3_get_key_exchange(SSL *s)
1258 ERR_R_DH_LIB); 1282 ERR_R_DH_LIB);
1259 goto err; 1283 goto err;
1260 } 1284 }
1285 if (2 > n)
1286 goto truncated;
1261 n2s(p, i); 1287 n2s(p, i);
1262 param_len = i + 2; 1288 param_len = i + 2;
1263 if (param_len > n) { 1289 if (param_len > n) {
@@ -1273,6 +1299,8 @@ ssl3_get_key_exchange(SSL *s)
1273 } 1299 }
1274 p += i; 1300 p += i;
1275 1301
1302 if (param_len + 2 > n)
1303 goto truncated;
1276 n2s(p, i); 1304 n2s(p, i);
1277 param_len += i + 2; 1305 param_len += i + 2;
1278 if (param_len > n) { 1306 if (param_len > n) {
@@ -1288,6 +1316,8 @@ ssl3_get_key_exchange(SSL *s)
1288 } 1316 }
1289 p += i; 1317 p += i;
1290 1318
1319 if (param_len + 2 > n)
1320 goto truncated;
1291 n2s(p, i); 1321 n2s(p, i);
1292 param_len += i + 2; 1322 param_len += i + 2;
1293 if (param_len > n) { 1323 if (param_len > n) {
@@ -1376,6 +1406,8 @@ ssl3_get_key_exchange(SSL *s)
1376 goto err; 1406 goto err;
1377 } 1407 }
1378 1408
1409 if (param_len + 1 > n)
1410 goto truncated;
1379 encoded_pt_len = *p; 1411 encoded_pt_len = *p;
1380 /* length of encoded point */ 1412 /* length of encoded point */
1381 p += 1; 1413 p += 1;
@@ -1435,6 +1467,8 @@ ssl3_get_key_exchange(SSL *s)
1435 * Check key type is consistent 1467 * Check key type is consistent
1436 * with signature 1468 * with signature
1437 */ 1469 */
1470 if (2 > n)
1471 goto truncated;
1438 if (sigalg != (int)p[1]) { 1472 if (sigalg != (int)p[1]) {
1439 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, 1473 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
1440 SSL_R_WRONG_SIGNATURE_TYPE); 1474 SSL_R_WRONG_SIGNATURE_TYPE);
@@ -1453,11 +1487,13 @@ ssl3_get_key_exchange(SSL *s)
1453 } else 1487 } else
1454 md = EVP_sha1(); 1488 md = EVP_sha1();
1455 1489
1490 if (2 > n)
1491 goto truncated;
1456 n2s(p, i); 1492 n2s(p, i);
1457 n -= 2; 1493 n -= 2;
1458 j = EVP_PKEY_size(pkey); 1494 j = EVP_PKEY_size(pkey);
1459 1495
1460 if ((i != n) || (n > j) || (n <= 0)) { 1496 if (i != n || n > j) {
1461 /* wrong packet length */ 1497 /* wrong packet length */
1462 al = SSL_AD_DECODE_ERROR; 1498 al = SSL_AD_DECODE_ERROR;
1463 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, 1499 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
@@ -1534,6 +1570,10 @@ ssl3_get_key_exchange(SSL *s)
1534 EVP_PKEY_free(pkey); 1570 EVP_PKEY_free(pkey);
1535 EVP_MD_CTX_cleanup(&md_ctx); 1571 EVP_MD_CTX_cleanup(&md_ctx);
1536 return (1); 1572 return (1);
1573truncated:
1574 /* wrong packet length */
1575 al = SSL_AD_DECODE_ERROR;
1576 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_PACKET_LENGTH);
1537f_err: 1577f_err:
1538 ssl3_send_alert(s, SSL3_AL_FATAL, al); 1578 ssl3_send_alert(s, SSL3_AL_FATAL, al);
1539err: 1579err:
@@ -1606,13 +1646,26 @@ ssl3_get_certificate_request(SSL *s)
1606 } 1646 }
1607 1647
1608 /* get the certificate types */ 1648 /* get the certificate types */
1649 if (1 > n)
1650 goto truncated;
1609 ctype_num= *(p++); 1651 ctype_num= *(p++);
1610 if (ctype_num > SSL3_CT_NUMBER) 1652 if (ctype_num > SSL3_CT_NUMBER)
1611 ctype_num = SSL3_CT_NUMBER; 1653 ctype_num = SSL3_CT_NUMBER;
1654 if (p + ctype_num - d > n) {
1655 SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
1656 SSL_R_DATA_LENGTH_TOO_LONG);
1657 goto err;
1658 }
1659
1612 for (i = 0; i < ctype_num; i++) 1660 for (i = 0; i < ctype_num; i++)
1613 s->s3->tmp.ctype[i] = p[i]; 1661 s->s3->tmp.ctype[i] = p[i];
1614 p += ctype_num; 1662 p += ctype_num;
1615 if (SSL_USE_SIGALGS(s)) { 1663 if (SSL_USE_SIGALGS(s)) {
1664 if (p + 2 - d > n) {
1665 SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
1666 SSL_R_DATA_LENGTH_TOO_LONG);
1667 goto err;
1668 }
1616 n2s(p, llen); 1669 n2s(p, llen);
1617 /* Check we have enough room for signature algorithms and 1670 /* Check we have enough room for signature algorithms and
1618 * following length value. 1671 * following length value.
@@ -1633,6 +1686,11 @@ ssl3_get_certificate_request(SSL *s)
1633 } 1686 }
1634 1687
1635 /* get the CA RDNs */ 1688 /* get the CA RDNs */
1689 if (p + 2 - d > n) {
1690 SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
1691 SSL_R_DATA_LENGTH_TOO_LONG);
1692 goto err;
1693 }
1636 n2s(p, llen); 1694 n2s(p, llen);
1637 1695
1638 if ((unsigned long)(p - d + llen) != n) { 1696 if ((unsigned long)(p - d + llen) != n) {
@@ -1698,6 +1756,11 @@ cont:
1698 ca_sk = NULL; 1756 ca_sk = NULL;
1699 1757
1700 ret = 1; 1758 ret = 1;
1759 if (0) {
1760truncated:
1761 SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
1762 SSL_R_BAD_PACKET_LENGTH);
1763 }
1701err: 1764err:
1702 if (ca_sk != NULL) 1765 if (ca_sk != NULL)
1703 sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); 1766 sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);