diff options
author | jsing <> | 2018-05-13 15:51:29 +0000 |
---|---|---|
committer | jsing <> | 2018-05-13 15:51:29 +0000 |
commit | 8920c7aaf03b3509ed0ae19ea95e97a25eb2acc2 (patch) | |
tree | 5bb3196c5410e12e36e9f2632aaa70b1c46618d9 /src | |
parent | a63de23e1f0e03f20ea5ec136638a8ce4d3c09d2 (diff) | |
download | openbsd-8920c7aaf03b3509ed0ae19ea95e97a25eb2acc2.tar.gz openbsd-8920c7aaf03b3509ed0ae19ea95e97a25eb2acc2.tar.bz2 openbsd-8920c7aaf03b3509ed0ae19ea95e97a25eb2acc2.zip |
More clean up of the RSA key exchange code.
Convert to CBS, use more appropriate variable names and improve validation.
Allocate a dedicated buffer to hold the decrypted result, rather than
decrypting into the handshake buffer (which is also used to send data).
ok beck@ inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index e72593e6b1..3da9cacd7d 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.29 2018/04/11 17:47:36 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.30 2018/05/13 15:51:29 jsing 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 | * |
@@ -1727,12 +1727,18 @@ static int | |||
1727 | ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n) | 1727 | ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n) |
1728 | { | 1728 | { |
1729 | unsigned char fakekey[SSL_MAX_MASTER_KEY_LENGTH]; | 1729 | unsigned char fakekey[SSL_MAX_MASTER_KEY_LENGTH]; |
1730 | unsigned char *d; | 1730 | unsigned char *pms = NULL; |
1731 | RSA *rsa = NULL; | 1731 | size_t pms_len = 0; |
1732 | EVP_PKEY *pkey = NULL; | 1732 | EVP_PKEY *pkey = NULL; |
1733 | int i, al; | 1733 | RSA *rsa = NULL; |
1734 | CBS cbs, enc_pms; | ||
1735 | int decrypt_len; | ||
1736 | int al = -1; | ||
1737 | |||
1738 | if (n < 0) | ||
1739 | goto err; | ||
1734 | 1740 | ||
1735 | d = p; | 1741 | CBS_init(&cbs, p, n); |
1736 | 1742 | ||
1737 | arc4random_buf(fakekey, sizeof(fakekey)); | 1743 | arc4random_buf(fakekey, sizeof(fakekey)); |
1738 | fakekey[0] = s->client_version >> 8; | 1744 | fakekey[0] = s->client_version >> 8; |
@@ -1747,30 +1753,32 @@ ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n) | |||
1747 | } | 1753 | } |
1748 | rsa = pkey->pkey.rsa; | 1754 | rsa = pkey->pkey.rsa; |
1749 | 1755 | ||
1750 | if (2 > n) | 1756 | pms_len = RSA_size(rsa); |
1757 | if (pms_len < SSL_MAX_MASTER_KEY_LENGTH) | ||
1758 | goto err; | ||
1759 | if ((pms = malloc(pms_len)) == NULL) | ||
1760 | goto err; | ||
1761 | p = pms; | ||
1762 | |||
1763 | if (!CBS_get_u16_length_prefixed(&cbs, &enc_pms)) | ||
1751 | goto truncated; | 1764 | goto truncated; |
1752 | n2s(p, i); | 1765 | if (CBS_len(&cbs) != 0 || CBS_len(&enc_pms) != RSA_size(rsa)) { |
1753 | if (n != i + 2) { | ||
1754 | SSLerror(s, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); | 1766 | SSLerror(s, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); |
1755 | goto err; | 1767 | goto err; |
1756 | } else | 1768 | } |
1757 | n = i; | ||
1758 | 1769 | ||
1759 | i = RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); | 1770 | decrypt_len = RSA_private_decrypt(CBS_len(&enc_pms), CBS_data(&enc_pms), |
1771 | pms, rsa, RSA_PKCS1_PADDING); | ||
1760 | 1772 | ||
1761 | ERR_clear_error(); | 1773 | ERR_clear_error(); |
1762 | 1774 | ||
1763 | al = -1; | 1775 | if (decrypt_len != SSL_MAX_MASTER_KEY_LENGTH) { |
1764 | |||
1765 | if (i != SSL_MAX_MASTER_KEY_LENGTH) { | ||
1766 | al = SSL_AD_DECODE_ERROR; | 1776 | al = SSL_AD_DECODE_ERROR; |
1767 | /* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */ | 1777 | /* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */ |
1768 | } | 1778 | } |
1769 | 1779 | ||
1770 | if (p - d + 2 > n) /* needed in the SSL3 case */ | 1780 | if ((al == -1) && !((pms[0] == (s->client_version >> 8)) && |
1771 | goto truncated; | 1781 | (pms[1] == (s->client_version & 0xff)))) { |
1772 | if ((al == -1) && !((p[0] == (s->client_version >> 8)) && | ||
1773 | (p[1] == (s->client_version & 0xff)))) { | ||
1774 | /* | 1782 | /* |
1775 | * The premaster secret must contain the same version number | 1783 | * The premaster secret must contain the same version number |
1776 | * as the ClientHello to detect version rollback attacks | 1784 | * as the ClientHello to detect version rollback attacks |
@@ -1796,23 +1804,25 @@ ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n) | |||
1796 | * on PKCS #1 v1.5 RSA padding (see RFC 2246, | 1804 | * on PKCS #1 v1.5 RSA padding (see RFC 2246, |
1797 | * section 7.4.7.1). | 1805 | * section 7.4.7.1). |
1798 | */ | 1806 | */ |
1799 | i = SSL_MAX_MASTER_KEY_LENGTH; | ||
1800 | p = fakekey; | 1807 | p = fakekey; |
1801 | } | 1808 | } |
1802 | 1809 | ||
1803 | s->session->master_key_length = | 1810 | s->session->master_key_length = |
1804 | tls1_generate_master_secret(s, | 1811 | tls1_generate_master_secret(s, |
1805 | s->session->master_key, p, i); | 1812 | s->session->master_key, p, SSL_MAX_MASTER_KEY_LENGTH); |
1806 | 1813 | ||
1807 | explicit_bzero(p, i); | 1814 | freezero(pms, pms_len); |
1808 | 1815 | ||
1809 | return (1); | 1816 | return (1); |
1810 | truncated: | 1817 | |
1818 | truncated: | ||
1811 | al = SSL_AD_DECODE_ERROR; | 1819 | al = SSL_AD_DECODE_ERROR; |
1812 | SSLerror(s, SSL_R_BAD_PACKET_LENGTH); | 1820 | SSLerror(s, SSL_R_BAD_PACKET_LENGTH); |
1813 | f_err: | 1821 | f_err: |
1814 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 1822 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
1815 | err: | 1823 | err: |
1824 | freezero(pms, pms_len); | ||
1825 | |||
1816 | return (-1); | 1826 | return (-1); |
1817 | } | 1827 | } |
1818 | 1828 | ||