fix compilation error
[openssl.git] / ssl / s3_srvr.c
index 440fc13e4fe75765005d8a12e8d9ea103a5822b0..90e95d6bc11fb4908156437673aaec9f4e8c6927 100644 (file)
 #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)
@@ -179,6 +181,12 @@ 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)
        {
@@ -205,11 +213,6 @@ 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;
@@ -291,6 +294,7 @@ int ssl3_accept(SSL *s)
                                        }
                                if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
                                        {
+                                       BUF_MEM_free(buf);
                                        ret= -1;
                                        goto end;
                                        }
@@ -304,8 +308,10 @@ int ssl3_accept(SSL *s)
                                }
 
                        s->init_num=0;
-                       s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
                        s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY;
+                       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)
                                {
@@ -447,20 +453,11 @@ int ssl3_accept(SSL *s)
                case SSL3_ST_SW_KEY_EXCH_B:
                        alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
-                       /* clear this, it may get reset by
-                        * send_server_key_exchange */
-                       if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
-                               && !(alg_k & SSL_kKRB5)
-#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;
+                       /*
+                        * clear this, it may get reset by
+                        * send_server_key_exchange
+                        */
+                       s->s3->tmp.use_rsa_tmp=0;
 
 
                        /* only send if a DH key exchange, fortezza or
@@ -474,7 +471,7 @@ int ssl3_accept(SSL *s)
                         * server certificate contains the server's
                         * public key for key exchange.
                         */
-                       if (s->s3->tmp.use_rsa_tmp
+                       if (0
                        /* PSK: send ServerKeyExchange if PSK identity
                         * hint if provided */
 #ifndef OPENSSL_NO_PSK
@@ -585,21 +582,13 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SR_CERT_A:
                case SSL3_ST_SR_CERT_B:
-                       /* Check for second client hello (MS SGC) */
-                       ret = ssl3_check_client_hello(s);
-                       if (ret <= 0)
-                               goto end;
-                       if (ret == 2)
-                               s->state = SSL3_ST_SR_CLNT_HELLO_C;
-                       else {
-                               if (s->s3->tmp.cert_request)
-                                       {
-                                       ret=ssl3_get_client_certificate(s);
-                                       if (ret <= 0) goto end;
-                                       }
-                               s->init_num=0;
-                               s->state=SSL3_ST_SR_KEY_EXCH_A;
-                       }
+                       if (s->s3->tmp.cert_request)
+                               {
+                               ret=ssl3_get_client_certificate(s);
+                               if (ret <= 0) goto end;
+                               }
+                       s->init_num=0;
+                       s->state=SSL3_ST_SR_KEY_EXCH_A;
                        break;
 
                case SSL3_ST_SR_KEY_EXCH_A:
@@ -680,8 +669,14 @@ int ssl3_accept(SSL *s)
 
                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;
@@ -700,6 +695,19 @@ int ssl3_accept(SSL *s)
 #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;
@@ -709,7 +717,18 @@ int ssl3_accept(SSL *s)
 
                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;
@@ -781,7 +800,6 @@ int ssl3_accept(SSL *s)
 #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
@@ -871,52 +889,6 @@ int ssl3_send_hello_request(SSL *s)
        return ssl_do_write(s);
        }
 
-int ssl3_check_client_hello(SSL *s)
-       {
-       int ok;
-       long n;
-
-       /* this function is called when we really expect a Certificate message,
-        * so permit appropriate message length */
-       n=s->method->ssl_get_message(s,
-               SSL3_ST_SR_CERT_A,
-               SSL3_ST_SR_CERT_B,
-               -1,
-               s->max_cert_list,
-               &ok);
-       if (!ok) return((int)n);
-       s->s3->tmp.reuse_message = 1;
-       if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
-               {
-               /* We only allow the client to restart the handshake once per
-                * negotiation. */
-               if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
-                       {
-                       SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
-                       return -1;
-                       }
-               /* Throw away what we have done so far in the current handshake,
-                * which will now be aborted. (A full SSL_clear would be too much.) */
-#ifndef OPENSSL_NO_DH
-               if (s->s3->tmp.dh != NULL)
-                       {
-                       DH_free(s->s3->tmp.dh);
-                       s->s3->tmp.dh = NULL;
-                       }
-#endif
-#ifndef OPENSSL_NO_ECDH
-               if (s->s3->tmp.ecdh != NULL)
-                       {
-                       EC_KEY_free(s->s3->tmp.ecdh);
-                       s->s3->tmp.ecdh = NULL;
-                       }
-#endif
-               s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
-               return 2;
-               }
-       return 1;
-}
-
 int ssl3_get_client_hello(SSL *s)
        {
        int i,j,ok,al=SSL_AD_INTERNAL_ERROR,ret= -1;
@@ -1019,7 +991,16 @@ int ssl3_get_client_hello(SSL *s)
        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;
                        }
@@ -1145,14 +1126,15 @@ int ssl3_get_client_hello(SSL *s)
                id=s->session->cipher->id;
 
 #ifdef CIPHER_DEBUG
-               printf("client sent %d ciphers\n",sk_num(ciphers));
+               fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers));
 #endif
                for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
                        {
                        c=sk_SSL_CIPHER_value(ciphers,i);
 #ifdef CIPHER_DEBUG
-                       printf("client [%2d of %2d]:%s\n",
-                               i,sk_num(ciphers),SSL_CIPHER_get_name(c));
+                       fprintf(stderr,"client [%2d of %2d]:%s\n",
+                               i,sk_SSL_CIPHER_num(ciphers),
+                               SSL_CIPHER_get_name(c));
 #endif
                        if (c->id == id)
                                {
@@ -1377,6 +1359,11 @@ int ssl3_get_client_hello(SSL *s)
                        goto f_err;
                        }
                ciphers=NULL;
+               if (!tls1_set_server_sigalgs(s))
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+                       goto err;
+                       }
                /* Let cert callback update server certificates if required */
                retry_cert:             
                if (s->cert->cert_cb)
@@ -1450,7 +1437,8 @@ int ssl3_get_client_hello(SSL *s)
                        goto f_err;
                }
        
-       /* we now have the following setup. 
+       /*-
+        * we now have the following setup. 
         * client_random
         * cipher_list          - our prefered list of ciphers
         * ciphers              - the clients prefered list of ciphers
@@ -1508,7 +1496,8 @@ int ssl3_send_server_hello(SSL *s)
                memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
                p+=SSL3_RANDOM_SIZE;
 
-               /* There are several cases for the session ID to send
+               /*-
+                * There are several cases for the session ID to send
                 * back in the server hello:
                 * - For session reuse from the session cache,
                 *   we send back the old session ID.
@@ -2223,8 +2212,9 @@ int ssl3_get_client_key_exchange(SSL *s)
        if (alg_k & SSL_kRSA)
                {
                unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
-               int decrypt_len, decrypt_good_mask;
-               unsigned char version_good;
+               int decrypt_len;
+               unsigned char decrypt_good, version_good;
+               size_t j;
 
                /* FIX THIS UP EAY EAY EAY EAY */
                if (s->s3->tmp.use_rsa_tmp)
@@ -2263,8 +2253,9 @@ int ssl3_get_client_key_exchange(SSL *s)
                                {
                                if (!(s->options & SSL_OP_TLS_D5_BUG))
                                        {
+                                       al = SSL_AD_DECODE_ERROR;
                                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
-                                       goto err;
+                                       goto f_err;
                                        }
                                else
                                        p-=2;
@@ -2273,6 +2264,20 @@ int ssl3_get_client_key_exchange(SSL *s)
                                n=i;
                        }
 
+               /*
+                * Reject overly short RSA ciphertext because we want to be sure
+                * that the buffer size makes it safe to iterate over the entire
+                * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
+                * actual expected size is larger due to RSA padding, but the
+                * bound is sufficient to be safe.
+                */
+               if (n < SSL_MAX_MASTER_KEY_LENGTH)
+                       {
+                       al = SSL_AD_DECRYPT_ERROR;
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+                       goto f_err;
+                       }
+
                /* 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
@@ -2288,18 +2293,18 @@ int ssl3_get_client_key_exchange(SSL *s)
                ERR_clear_error();
 
                /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
-                * decrypt_good_mask will be zero if so and non-zero otherwise. */
-               decrypt_good_mask = decrypt_len ^ 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 zero. The Klima-Pokorny-Rosa
-                * extension of Bleichenbacher's attack
+                * 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 = p[0] ^ (s->client_version>>8);
-               version_good |= p[1] ^ (s->client_version&0xff);
+               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
@@ -2310,62 +2315,33 @@ int ssl3_get_client_key_exchange(SSL *s)
                 * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
                if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
                        {
-                       unsigned char workaround_mask = version_good;
-                       unsigned char workaround;
-
-                       /* workaround_mask will be 0xff if version_good is
-                        * non-zero (i.e. the version match failed). Otherwise
-                        * it'll be 0x00. */
-                       workaround_mask |= workaround_mask >> 4;
-                       workaround_mask |= workaround_mask >> 2;
-                       workaround_mask |= workaround_mask >> 1;
-                       workaround_mask = ~((workaround_mask & 1) - 1);
-
-                       workaround = p[0] ^ (s->version>>8);
-                       workaround |= p[1] ^ (s->version&0xff);
-
-                       /* If workaround_mask is 0xff (i.e. there was a version
-                        * mismatch) then we copy the value of workaround over
-                        * version_good. */
-                       version_good = (workaround & workaround_mask) |
-                                      (version_good & ~workaround_mask);
-                       }
-
-               /* If any bits in version_good are set then they'll poision
-                * decrypt_good_mask and cause rand_premaster_secret to be
-                * used. */
-               decrypt_good_mask |= version_good;
-
-               /* decrypt_good_mask will be zero iff decrypt_len ==
-                * SSL_MAX_MASTER_KEY_LENGTH and the version check passed. We
-                * fold the bottom 32 bits of it with an OR so that the LSB
-                * will be zero iff everything is good. This assumes that we'll
-                * never decrypt a value > 2**31 bytes, which seems safe. */
-               decrypt_good_mask |= decrypt_good_mask >> 16;
-               decrypt_good_mask |= decrypt_good_mask >> 8;
-               decrypt_good_mask |= decrypt_good_mask >> 4;
-               decrypt_good_mask |= decrypt_good_mask >> 2;
-               decrypt_good_mask |= decrypt_good_mask >> 1;
-               /* Now select only the LSB and subtract one. If decrypt_len ==
-                * SSL_MAX_MASTER_KEY_LENGTH and the version check passed then
-                * decrypt_good_mask will be all ones. Otherwise it'll be all
-                * zeros. */
-               decrypt_good_mask &= 1;
-               decrypt_good_mask--;
-
-               /* Now copy rand_premaster_secret over p using
-                * decrypt_good_mask. */
-               for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
-                       {
-                       p[i] = (p[i] & decrypt_good_mask) |
-                              (rand_premaster_secret[i] & ~decrypt_good_mask);
+                       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 from p using
+                * decrypt_good_mask. If decryption failed, then p does not
+                * contain valid plaintext, however, a check above guarantees
+                * it is still sufficiently large to read from.
+                */
+               for (j = 0; j < sizeof(rand_premaster_secret); j++)
+                       {
+                       p[j] = constant_time_select_8(decrypt_good, p[j],
+                                                     rand_premaster_secret[j]);
                        }
 
                s->session->master_key_length=
                        s->method->ssl3_enc->generate_master_secret(s,
                                s->session->master_key,
-                               p,i);
-               OPENSSL_cleanse(p,i);
+                               p,sizeof(rand_premaster_secret));
+               OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
                }
        else
 #endif
@@ -2542,10 +2518,10 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        &kssl_err)) != 0)
                        {
 #ifdef KSSL_DEBUG
-                       printf("kssl_sget_tkt rtn %d [%d]\n",
+                       fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n",
                                krb5rc, kssl_err.reason);
                        if (kssl_err.text)
-                               printf("kssl_err text= %s\n", kssl_err.text);
+                               fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
 #endif /* KSSL_DEBUG */
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                kssl_err.reason);
@@ -2559,10 +2535,10 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        &authtime, &kssl_err)) != 0)
                        {
 #ifdef KSSL_DEBUG
-                       printf("kssl_check_authent rtn %d [%d]\n",
+                       fprintf(stderr,"kssl_check_authent rtn %d [%d]\n",
                                krb5rc, kssl_err.reason);
                        if (kssl_err.text)
-                               printf("kssl_err text= %s\n", kssl_err.text);
+                               fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
 #endif /* KSSL_DEBUG */
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                kssl_err.reason);
@@ -2652,11 +2628,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                        }
 
 
-               /*  Was doing kssl_ctx_free() here,
-               **  but it caused problems for apache.
-               **  kssl_ctx = kssl_ctx_free(kssl_ctx);
-               **  if (s->kssl_ctx)  s->kssl_ctx = NULL;
-               */
+               /*- Was doing kssl_ctx_free() here,
+                *  but it caused problems for apache.
+                *  kssl_ctx = kssl_ctx_free(kssl_ctx);
+                *  if (s->kssl_ctx)  s->kssl_ctx = NULL;
+                */
                }
        else
 #endif /* OPENSSL_NO_KRB5 */
@@ -3549,7 +3525,8 @@ int ssl3_send_newsession_ticket(SSL *s)
                i2d_SSL_SESSION(sess, &p);
                SSL_SESSION_free(sess);
 
-               /* Grow buffer if need be: the length calculation is as
+               /*-
+                * Grow buffer if need be: the length calculation is as
                 * follows handshake_header_length +
                 * 4 (ticket lifetime hint) + 2 (ticket length) +
                 * 16 (key name) + max_iv_len (iv length) +
@@ -3633,7 +3610,8 @@ int ssl3_send_cert_status(SSL *s)
        if (s->state == SSL3_ST_SW_CERT_STATUS_A)
                {
                unsigned char *p;
-               /* Grow buffer if need be: the length calculation is as
+               /*-
+                * Grow buffer if need be: the length calculation is as
                 * follows 1 (message type) + 3 (message length) +
                 * 1 (ocsp response type) + 3 (ocsp response length)
                 * + (ocsp response)
@@ -3705,7 +3683,8 @@ int ssl3_get_next_proto(SSL *s)
 
        p=(unsigned char *)s->init_msg;
 
-       /* The payload looks like:
+       /*-
+        * The payload looks like:
         *   uint8 proto_len;
         *   uint8 proto[proto_len];
         *   uint8 padding_len;