#include <stdio.h>
#include "ssl_locl.h"
#include "kssl_lcl.h"
+#include "../crypto/constant_time_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
#endif
#include <openssl/md5.h>
+#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_server_method(int ver);
static const SSL_METHOD *ssl3_get_server_method(int ver)
return(NULL);
}
+IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ ssl3_get_server_method)
+#endif
+
#ifndef OPENSSL_NO_SRP
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{
}
#endif
-IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
- ssl3_accept,
- ssl_undefined_function,
- ssl3_get_server_method)
-
int ssl3_accept(SSL *s)
{
BUF_MEM *buf;
s->init_num=0;
s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
if (s->state != SSL_ST_RENEGOTIATE)
{
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
-
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
+ /*
+ * This *should* be the first time we enable CCS, but be
+ * extra careful about surrounding code changes. We need
+ * to set this here because we don't know if we're
+ * expecting a CertificateVerify or not.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
case SSL3_ST_SR_NEXT_PROTO_A:
case SSL3_ST_SR_NEXT_PROTO_B:
+ /*
+ * Enable CCS for resumed handshakes with NPN.
+ * In a full handshake with NPN, we end up here through
+ * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
+ * already set. Receiving a CCS clears the flag, so make
+ * sure not to re-enable it to ban duplicates.
+ * s->s3->change_cipher_spec is set when a CCS is
+ * processed in s3_pkt.c, and remains set until
+ * the client's Finished message is read.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
+
ret=ssl3_get_next_proto(s);
if (ret <= 0) goto end;
s->init_num = 0;
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
+ /*
+ * Enable CCS for resumed handshakes without NPN.
+ * In a full handshake, we end up here through
+ * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
+ * already set. Receiving a CCS clears the flag, so make
+ * sure not to re-enable it to ban duplicates.
+ * s->s3->change_cipher_spec is set when a CCS is
+ * processed in s3_pkt.c, and remains set until
+ * the client's Finished message is read.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
#else
if (s->s3->next_proto_neg_seen)
{
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
}
else
else
{
i=ssl_get_prev_session(s, p, j, d + n);
- if (i == 1)
+ /*
+ * Only resume if the session's version matches the negotiated
+ * version.
+ * RFC 5246 does not provide much useful advice on resumption
+ * with a different protocol version. It doesn't forbid it but
+ * the sanity of such behaviour would be questionable.
+ * In practice, clients do not accept a version mismatch and
+ * will abort the handshake with an error.
+ */
+ if (i == 1 && s->version == s->session->ssl_version)
{ /* previous session */
s->hit=1;
}
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
+ unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+ int decrypt_len;
+ unsigned char decrypt_good, version_good;
+
/* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp)
{
n=i;
}
- i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
-
- al = -1;
-
- if (i != SSL_MAX_MASTER_KEY_LENGTH)
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
- }
-
- if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
- {
- /* The premaster secret must contain the same version number as the
- * ClientHello to detect version rollback attacks (strangely, the
- * protocol does not offer such protection for DH ciphersuites).
- * However, buggy clients exist that send the negotiated protocol
- * version instead if the server does not support the requested
- * protocol version.
- * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
- if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
- (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
+ /* We must not leak whether a decryption failure occurs because
+ * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
+ * RFC 2246, section 7.4.7.1). The code follows that advice of
+ * the TLS RFC and generates a random premaster secret for the
+ * case that the decrypt fails. See
+ * https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
- /* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
- * (http://eprint.iacr.org/2003/052/) exploits the version
- * number check as a "bad version oracle" -- an alert would
- * reveal that the plaintext corresponding to some ciphertext
- * made up by the adversary is properly formatted except
- * that the version number is wrong. To avoid such attacks,
- * we should treat this just like any other decryption error. */
- }
+ /* should be RAND_bytes, but we cannot work around a failure. */
+ if (RAND_pseudo_bytes(rand_premaster_secret,
+ sizeof(rand_premaster_secret)) <= 0)
+ goto err;
+ decrypt_len = RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+ ERR_clear_error();
+
+ /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
+ * decrypt_good will be 0xff if so and zero otherwise. */
+ decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
+
+ /* If the version in the decrypted pre-master secret is correct
+ * then version_good will be 0xff, otherwise it'll be zero.
+ * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+ * (http://eprint.iacr.org/2003/052/) exploits the version
+ * number check as a "bad version oracle". Thus version checks
+ * are done in constant time and are treated like any other
+ * decryption error. */
+ version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8));
+ version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff));
+
+ /* The premaster secret must contain the same version number as
+ * the ClientHello to detect version rollback attacks
+ * (strangely, the protocol does not offer such protection for
+ * DH ciphersuites). However, buggy clients exist that send the
+ * negotiated protocol version instead if the server does not
+ * support the requested protocol version. If
+ * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
+ if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
+ {
+ unsigned char workaround_good;
+ workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8));
+ workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff));
+ version_good |= workaround_good;
+ }
+
+ /* Both decryption and version must be good for decrypt_good
+ * to remain non-zero (0xff). */
+ decrypt_good &= version_good;
+
+ /* Now copy rand_premaster_secret over p using
+ * decrypt_good_mask. */
+ for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
+ {
+ p[i] = constant_time_select_8(decrypt_good, p[i],
+ rand_premaster_secret[i]);
}
- if (al != -1)
- {
- /* Some decryption failure -- use random value instead as countermeasure
- * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
- * (see RFC 2246, section 7.4.7.1). */
- ERR_clear_error();
- i = SSL_MAX_MASTER_KEY_LENGTH;
- p[0] = s->client_version >> 8;
- p[1] = s->client_version & 0xff;
- if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
- goto err;
- }
-
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,