More tweaks for comments due indent issues
[openssl.git] / ssl / s3_srvr.c
index aefc559011c09c4127472f30cd5816cc0b160ed3..d8155c3ac945060f65cfe9e9d2d03b1afc22870d 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;
@@ -283,6 +286,7 @@ int ssl3_accept(SSL *s)
                                        }
                                if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
                                        {
+                                       BUF_MEM_free(buf);
                                        ret= -1;
                                        goto end;
                                        }
@@ -296,8 +300,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)
                                {
@@ -402,32 +408,16 @@ int ssl3_accept(SSL *s)
                                        s->state=SSL3_ST_SW_CHANGE_A;
 #endif
                        else
-#ifndef OPENSSL_NO_TLSEXT
-                               s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A;
-#else
-                       s->state = SSL3_ST_SW_CERT_A;
-#endif
-                       s->init_num = 0;
-                       break;
-
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
-                       ret = tls1_send_server_supplemental_data(s, &skip);
-                       if (ret <= 0) goto end;
-
-                       s->state = SSL3_ST_SW_CERT_A;
+                                       s->state = SSL3_ST_SW_CERT_A;
                        s->init_num = 0;
                        break;
-#endif
 
                case SSL3_ST_SW_CERT_A:
                case SSL3_ST_SW_CERT_B:
                        /* Check if it is anon DH or anon ECDH, */
                        /* normal PSK or KRB5 or SRP */
-                       if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
-                               && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
-                               && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+                       if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP))
+                               && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                                {
                                ret=ssl3_send_server_certificate(s);
                                if (ret <= 0) goto end;
@@ -456,20 +446,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
@@ -483,7 +464,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
@@ -530,7 +511,9 @@ int ssl3_accept(SSL *s)
                                  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
                                 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
                                 /* never request cert in Kerberos ciphersuites */
-                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
+                               /* don't request certificate for SRP auth */
+                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
                                /* With normal PSK Certificates and
                                 * Certificate Requests are omitted */
                                || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@@ -589,37 +572,16 @@ int ssl3_accept(SSL *s)
 
                        s->state=s->s3->tmp.next_state;
                        break;
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_SR_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_SR_SUPPLEMENTAL_DATA_B:
-                       ret=tls1_get_client_supplemental_data(s);
-                       if (ret <= 0) goto end;
-                       s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
-                       s->state=SSL3_ST_SW_FLUSH;
-                       s->init_num=0;
-                       break;
-#endif
+
                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;
-#ifndef OPENSSL_NO_TLSEXT
-                       else if (ret == 3)
-                               s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A;
-#endif
-                       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:
@@ -700,7 +662,14 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SR_CERT_VRFY_A:
                case SSL3_ST_SR_CERT_VRFY_B:
-
+                       /*
+                        * 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;
@@ -719,6 +688,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;
@@ -728,6 +710,18 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SR_FINISHED_A:
                case SSL3_ST_SR_FINISHED_B:
+                       /*
+                        * 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;
@@ -798,7 +792,9 @@ int ssl3_accept(SSL *s)
                                s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #else
                                if (s->s3->next_proto_neg_seen)
+                                       {
                                        s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+                                       }
                                else
                                        s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #endif
@@ -886,56 +882,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;
-#ifndef OPENSSL_NO_TLSEXT
-       if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
-               return 3;
-#endif
-       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;
@@ -950,7 +896,7 @@ int ssl3_get_client_hello(SSL *s)
 #endif
        STACK_OF(SSL_CIPHER) *ciphers=NULL;
 
-       if (s->state == SSL3_ST_SR_CLNT_HELLO_C)
+       if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet)
                goto retry_cert;
 
        /* We do this so that we will respond with our native type.
@@ -1038,7 +984,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;
                        }
@@ -1089,8 +1044,9 @@ int ssl3_get_client_hello(SSL *s)
                                        }
                                /* else cookie verification succeeded */
                                }
+                       /* default verification */
                        else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, 
-                                                 s->d1->cookie_len) != 0) /* default verification */
+                                                 s->d1->cookie_len) != 0)
                                {
                                        al=SSL_AD_HANDSHAKE_FAILURE;
                                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
@@ -1164,14 +1120,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)
                                {
@@ -1342,7 +1299,8 @@ int ssl3_get_client_hello(SSL *s)
        else if (s->hit)
                comp = NULL;
        else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
-               { /* See if we have a match */
+               {
+               /* See if we have a match */
                int m,nn,o,v,done=0;
 
                nn=sk_SSL_COMP_num(s->ctx->comp_methods);
@@ -1396,6 +1354,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)
@@ -1462,7 +1425,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
@@ -1520,7 +1484,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.
@@ -1902,7 +1867,7 @@ int ssl3_send_server_key_exchange(SSL *s)
                        n+=2+nr[i];
                        }
 
-               if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+               if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP))
                        && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                        {
                        if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
@@ -2146,6 +2111,11 @@ int ssl3_send_certificate_request(SSL *s)
 #ifdef NETSCAPE_HANG_BUG
                if (!SSL_IS_DTLS(s))
                        {
+                       if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+                               goto err;
+                               }
                        p=(unsigned char *)s->init_buf->data + s->init_num;
                        /* do the header */
                        *(p++)=SSL3_MT_SERVER_DONE;
@@ -2194,7 +2164,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                SSL3_ST_SR_KEY_EXCH_A,
                SSL3_ST_SR_KEY_EXCH_B,
                SSL3_MT_CLIENT_KEY_EXCHANGE,
-               2048, /* ??? */
+               2048,
                &ok);
 
        if (!ok) return((int)n);
@@ -2205,6 +2175,11 @@ int ssl3_get_client_key_exchange(SSL *s)
 #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;
+               size_t j;
+
                /* FIX THIS UP EAY EAY EAY EAY */
                if (s->s3->tmp.use_rsa_tmp)
                        {
@@ -2242,8 +2217,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;
@@ -2252,59 +2228,84 @@ int ssl3_get_client_key_exchange(SSL *s)
                                n=i;
                        }
 
-               i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
-
-               al = -1;
-               
-               if (i != SSL_MAX_MASTER_KEY_LENGTH)
+               /*
+                * 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_DECODE_ERROR;
-                       /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
+                       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;
                        }
 
-               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); */
-
-                               /* 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. */
-                               }
-                       }
+               /* 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 */
 
-               if (al != -1)
+               /* 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 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++)
                        {
-                       /* 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;
+                       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
@@ -2481,10 +2482,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);
@@ -2498,10 +2499,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);
@@ -2591,11 +2592,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 */
@@ -2869,6 +2870,13 @@ int ssl3_get_client_key_exchange(SSL *s)
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB);
                                goto err;
                                }
+                       if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0
+                               || BN_is_zero(s->srp_ctx.A))
+                               {
+                               al=SSL_AD_ILLEGAL_PARAMETER;
+                               SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_PARAMETERS);
+                               goto f_err;
+                               }
                        if (s->session->srp_username != NULL)
                                OPENSSL_free(s->session->srp_username);
                        s->session->srp_username = BUF_strdup(s->srp_ctx.login);
@@ -2897,6 +2905,8 @@ int ssl3_get_client_key_exchange(SSL *s)
                        unsigned char premaster_secret[32], *start;
                        size_t outlen=32, inlen;
                        unsigned long alg_a;
+                       int Ttag, Tclass;
+                       long Tlen;
 
                        /* Get our certificate private key*/
                        alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2918,26 +2928,15 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        ERR_clear_error();
                                }
                        /* Decrypt session key */
-                       if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) 
-                               {
-                               SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
-                               goto gerr;
-                               }
-                       if (p[1] == 0x81)
-                               {
-                               start = p+3;
-                               inlen = p[2];
-                               }
-                       else if (p[1] < 0x80)
-                               {
-                               start = p+2;
-                               inlen = p[1];
-                               }
-                       else
+                       if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || 
+                               Ttag != V_ASN1_SEQUENCE ||
+                               Tclass != V_ASN1_UNIVERSAL) 
                                {
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
                                goto gerr;
                                }
+                       start = p;
+                       inlen = Tlen;
                        if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
 
                                {
@@ -3001,7 +3000,7 @@ int ssl3_get_cert_verify(SSL *s)
                SSL3_ST_SR_CERT_VRFY_A,
                SSL3_ST_SR_CERT_VRFY_B,
                -1,
-               516, /* Enough for 4096 bit RSA key with TLS v1.2 */
+               SSL3_RT_MAX_PLAIN_LENGTH,
                &ok);
 
        if (!ok) return((int)n);
@@ -3021,7 +3020,7 @@ int ssl3_get_cert_verify(SSL *s)
        if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
                {
                s->s3->tmp.reuse_message=1;
-               if ((peer != NULL) && (type & EVP_PKT_SIGN))
+               if (peer != NULL)
                        {
                        al=SSL_AD_UNEXPECTED_MESSAGE;
                        SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
@@ -3412,7 +3411,11 @@ int ssl3_send_server_certificate(SSL *s)
                                }
                        }
 
-               ssl3_output_cert_chain(s,cpk);
+               if (!ssl3_output_cert_chain(s,cpk))
+                       {
+                       SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+                       return(0);
+                       }
                s->state=SSL3_ST_SW_CERT_B;
                }
 
@@ -3470,7 +3473,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) +
@@ -3554,7 +3558,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)
@@ -3602,11 +3607,12 @@ int ssl3_get_next_proto(SSL *s)
                return -1;
                }
 
+       /* See the payload format below */
        n=s->method->ssl_get_message(s,
                SSL3_ST_SR_NEXT_PROTO_A,
                SSL3_ST_SR_NEXT_PROTO_B,
                SSL3_MT_NEXT_PROTO,
-               514,  /* See the payload format below */
+               514,
                &ok);
 
        if (!ok)
@@ -3626,7 +3632,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;
@@ -3652,156 +3659,4 @@ int ssl3_get_next_proto(SSL *s)
        }
 # endif
 
-int tls1_send_server_supplemental_data(SSL *s, int *skip)
-       {
-       int al = 0;
-       if (s->ctx->srv_supp_data_records_count)
-               {
-               unsigned char *p = NULL;
-               unsigned char *size_loc = NULL;
-               srv_supp_data_record *record = NULL;
-               size_t length = 0;
-               size_t i = 0;
-
-               for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
-                       {
-                       const unsigned char *out = NULL;
-                       unsigned short outlen = 0;
-                       int cb_retval = 0;
-                       record = &s->ctx->srv_supp_data_records[i];
-
-                       /* NULL callback or -1 omits supp data entry */
-                       if (!record->fn1)
-                               continue;
-                       cb_retval = record->fn1(s, record->supp_data_type,
-                                               &out, &outlen, &al, record->arg);
-                       if (cb_retval == -1)
-                               continue; /* skip this supp data entry */
-                       if (cb_retval == 0)
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               goto f_err;
-                               }
-                       if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               return 0;
-                               }
-                       /* write supp data entry...
-                        * if first entry, write handshake message type
-                        * jump back to write length at end */
-                       if (length == 0)
-                               {
-                               /* 1 byte message type + 3 bytes for
-                                * message length */
-                               if (!BUF_MEM_grow_clean(s->init_buf, 4))
-                                       {
-                                       SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                                       return 0;
-                                       }
-                               p = (unsigned char *)s->init_buf->data;
-                               *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
-                               /* hold on to length field to update later */
-                               size_loc = p;
-                               /* skip over handshake length field (3
-                                * bytes) and supp_data length field
-                                * (3 bytes) */
-                               p += 3 + 3;
-                               length += 1 +3 +3;
-                               }
-                       /* 2 byte supp data type + 2 byte length + outlen */
-                       if (!BUF_MEM_grow(s->init_buf, outlen + 4))
-                               {
-                               SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-                               return 0;
-                               }
-                       s2n(record->supp_data_type, p);
-                       s2n(outlen, p);
-                       memcpy(p, out, outlen);
-                       /* update length to supp data type (2 bytes) +
-                        * supp data length (2 bytes) + supp data */
-                       length += (outlen + 4);
-                       p += outlen;
-                       }
-               if (length > 0)
-                       {
-                       /* write handshake length */
-                       l2n3(length - 4, size_loc);
-                       /* supp_data length */
-                       l2n3(length - 7, size_loc);
-                       s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
-                       s->init_num = length;
-                       s->init_off = 0;
-
-                       return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-                       }
-               }
-
-       /* no supp data message sent */
-       *skip = 1;
-       s->init_num = 0;
-       s->init_off = 0;
-       return 1;
-f_err:
-       ssl3_send_alert(s,SSL3_AL_FATAL,al);
-       return 0;
-       }
-
-int tls1_get_client_supplemental_data(SSL *s)
-       {
-       int al = 0;
-       int cb_retval = 0;
-       int ok;
-       long n;
-       const unsigned char *p, *d;
-       unsigned short supp_data_entry_type = 0;
-       unsigned long supp_data_entry_len = 0;
-       unsigned long supp_data_len = 0;
-       size_t i = 0;
-
-       n=s->method->ssl_get_message(s,
-                                    SSL3_ST_SR_SUPPLEMENTAL_DATA_A,
-                                    SSL3_ST_SR_SUPPLEMENTAL_DATA_B,
-                                    SSL3_MT_SUPPLEMENTAL_DATA,
-                                    /* use default limit */
-                                    TLSEXT_MAXLEN_supplemental_data,
-                                    &ok);
-
-       if (!ok) return((int)n);
-
-       p = (unsigned char *)s->init_msg;
-       d = p;
-
-       /* The message cannot be empty */
-       if (n < 3)
-               {
-               al = SSL_AD_DECODE_ERROR;
-               SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
-               goto f_err;
-               }
-       n2l3(p, supp_data_len);
-       while (p<d+supp_data_len)
-               {
-               n2s(p, supp_data_entry_type);
-               n2s(p, supp_data_entry_len);
-               /* if there is a callback for this supp data type, send it */
-               for (i=0; i < s->ctx->srv_supp_data_records_count; i++)
-                       {
-                       if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2)
-                               {
-                               cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg);
-                               if (cb_retval == 0)
-                                       {
-                                       SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
-                                       goto f_err;
-                                       }
-                               }
-                       }
-               p+=supp_data_entry_len;
-               }
-       return 1;
-f_err:
-       ssl3_send_alert(s,SSL3_AL_FATAL,al);
-       return -1;
-       }
 #endif