Only allow ephemeral RSA keys in export ciphersuites.

OpenSSL clients would tolerate temporary RSA keys in non-export
ciphersuites. It also had an option SSL_OP_EPHEMERAL_RSA which
enabled this server side. Remove both options as they are a
protocol violation.

Thanks to Karthikeyan Bhargavan for reporting this issue.
(CVE-2015-0204)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>

(cherry picked from commit 4b4c1fcc88)

Conflicts:
	doc/ssl/SSL_CTX_set_options.pod
This commit is contained in:
Dr. Stephen Henson 2014-10-23 17:09:57 +01:00
parent ef28c6d676
commit 37580f43b5
7 changed files with 38 additions and 57 deletions

View File

@ -11,6 +11,14 @@
(CVE-2014-3572) (CVE-2014-3572)
[Steve Henson] [Steve Henson]
*) Remove non-export ephemeral RSA code on client and server. This code
violated the TLS standard by allowing the use of temporary RSA keys in
non-export ciphersuites and could be used by a server to effectively
downgrade the RSA key length used to a value smaller than the server
certificate. Thanks for Karthikeyan Bhargavan for reporting this issue.
(CVE-2015-0204)
[Steve Henson]
*) Ensure that the session ID context of an SSL is updated when its *) Ensure that the session ID context of an SSL is updated when its
SSL_CTX is updated via SSL_set_SSL_CTX. SSL_CTX is updated via SSL_set_SSL_CTX.

View File

@ -158,15 +158,7 @@ temporary/ephemeral DH parameters are used.
=item SSL_OP_EPHEMERAL_RSA =item SSL_OP_EPHEMERAL_RSA
Always use ephemeral (temporary) RSA key when doing RSA operations This option is no longer implemented and is treated as no op.
(see L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
According to the specifications this is only done, when a RSA key
can only be used for signature operations (namely under export ciphers
with restricted RSA keylength). By setting this option, ephemeral
RSA keys are always used. This option breaks compatibility with the
SSL/TLS specifications and may lead to interoperability problems with
clients and should therefore never be used. Ciphers with EDH (ephemeral
Diffie-Hellman) key exchange should be used instead.
=item SSL_OP_CIPHER_SERVER_PREFERENCE =item SSL_OP_CIPHER_SERVER_PREFERENCE

View File

@ -74,21 +74,14 @@ exchange and use EDH (Ephemeral Diffie-Hellman) key exchange instead
in order to achieve forward secrecy (see in order to achieve forward secrecy (see
L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>). L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default An application may either directly specify the key or can supply the key via a
and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of callback function. The callback approach has the advantage, that the callback
L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, violating the TLS/SSL may generate the key only in case it is actually needed. As the generation of a
standard. When ephemeral RSA key exchange is required for export ciphers, RSA key is however costly, it will lead to a significant delay in the handshake
it will automatically be used without this option! procedure. Another advantage of the callback function is that it can supply
keys of different size while the explicit setting of the key is only useful for
An application may either directly specify the key or can supply the key via key size of 512 bits to satisfy the export restricted ciphers and does give
a callback function. The callback approach has the advantage, that the away key length if a longer key would be allowed.
callback may generate the key only in case it is actually needed. As the
generation of a RSA key is however costly, it will lead to a significant
delay in the handshake procedure. Another advantage of the callback function
is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
usage) while the explicit setting of the key is only useful for key size of
512 bits to satisfy the export restricted ciphers and does give away key length
if a longer key would be allowed.
The B<tmp_rsa_callback> is called with the B<keylength> needed and The B<tmp_rsa_callback> is called with the B<keylength> needed and
the B<is_export> information. The B<is_export> flag is set, when the the B<is_export> information. The B<is_export> flag is set, when the

View File

@ -454,24 +454,15 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_KEY_EXCH_B: case SSL3_ST_SW_KEY_EXCH_B:
alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
/* clear this, it may get reset by /*
* send_server_key_exchange */ * clear this, it may get reset by
if ((s->options & SSL_OP_EPHEMERAL_RSA) * send_server_key_exchange
#ifndef OPENSSL_NO_KRB5 */
&& !(alg_k & SSL_kKRB5) s->s3->tmp.use_rsa_tmp=0;
#endif /* OPENSSL_NO_KRB5 */
)
/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
* even when forbidden by protocol specs
* (handshake may fail as clients are not required to
* be able to handle this) */
s->s3->tmp.use_rsa_tmp=1;
else
s->s3->tmp.use_rsa_tmp=0;
/* only send if a DH key exchange or /* only send if a DH key exchange or
* RSA but we have a sign only certificate */ * RSA but we have a sign only certificate */
if (s->s3->tmp.use_rsa_tmp if (0
/* PSK: send ServerKeyExchange if PSK identity /* PSK: send ServerKeyExchange if PSK identity
* hint if provided */ * hint if provided */
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK

View File

@ -1537,6 +1537,13 @@ int ssl3_get_key_exchange(SSL *s)
#ifndef OPENSSL_NO_RSA #ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA) if (alg_k & SSL_kRSA)
{ {
/* Temporary RSA keys only allowed in export ciphersuites */
if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
if ((rsa=RSA_new()) == NULL) if ((rsa=RSA_new()) == NULL)
{ {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);

View File

@ -447,20 +447,11 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SW_KEY_EXCH_B: case SSL3_ST_SW_KEY_EXCH_B:
alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
/* clear this, it may get reset by /*
* send_server_key_exchange */ * clear this, it may get reset by
if ((s->options & SSL_OP_EPHEMERAL_RSA) * send_server_key_exchange
#ifndef OPENSSL_NO_KRB5 */
&& !(alg_k & SSL_kKRB5) s->s3->tmp.use_rsa_tmp=0;
#endif /* OPENSSL_NO_KRB5 */
)
/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
* even when forbidden by protocol specs
* (handshake may fail as clients are not required to
* be able to handle this) */
s->s3->tmp.use_rsa_tmp=1;
else
s->s3->tmp.use_rsa_tmp=0;
/* only send if a DH key exchange, fortezza or /* only send if a DH key exchange, fortezza or
@ -474,7 +465,7 @@ int ssl3_accept(SSL *s)
* server certificate contains the server's * server certificate contains the server's
* public key for key exchange. * public key for key exchange.
*/ */
if (s->s3->tmp.use_rsa_tmp if (0
/* PSK: send ServerKeyExchange if PSK identity /* PSK: send ServerKeyExchange if PSK identity
* hint if provided */ * hint if provided */
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK

View File

@ -596,9 +596,8 @@ struct ssl_session_st
#define SSL_OP_SINGLE_ECDH_USE 0x00080000L #define SSL_OP_SINGLE_ECDH_USE 0x00080000L
/* If set, always create a new key when using tmp_dh parameters */ /* If set, always create a new key when using tmp_dh parameters */
#define SSL_OP_SINGLE_DH_USE 0x00100000L #define SSL_OP_SINGLE_DH_USE 0x00100000L
/* Set to always use the tmp_rsa key when doing RSA operations, /* Does nothing: retained for compatibiity */
* even when this violates protocol specs */ #define SSL_OP_EPHEMERAL_RSA 0x0
#define SSL_OP_EPHEMERAL_RSA 0x00200000L
/* Set on servers to choose the cipher according to the server's /* Set on servers to choose the cipher according to the server's
* preferences */ * preferences */
#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L #define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L