Tweaks for comments due to indent's inability to handle them
[openssl.git] / ssl / s3_srvr.c
index a2eebbb5961cc43c67ba09a9f5ed5cf24dae8f8b..5ec671a7bc4f0ff4c1563f1706566cc613b97b9e 100644 (file)
@@ -308,7 +308,6 @@ 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. */
@@ -454,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
@@ -481,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
@@ -592,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:
@@ -907,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;
@@ -1115,8 +1051,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, 
@@ -1190,14 +1127,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)
                                {
@@ -1368,7 +1306,8 @@ int ssl3_get_client_hello(SSL *s)
        else if (s->hit)
                comp = NULL;
        else if (ssl_allow_compression(s) && 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);
@@ -1500,7 +1439,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
@@ -1558,7 +1498,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.
@@ -2261,7 +2202,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);
@@ -2275,6 +2216,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                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)
@@ -2313,8 +2255,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;
@@ -2323,6 +2266,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
@@ -2370,19 +2327,23 @@ int ssl3_get_client_key_exchange(SSL *s)
                 * 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++)
+               /*
+                * 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[i] = constant_time_select_8(decrypt_good, p[i],
-                                                     rand_premaster_secret[i]);
+                       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
@@ -2559,10 +2520,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);
@@ -2576,10 +2537,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);
@@ -2669,11 +2630,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 */
@@ -3097,7 +3058,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);
@@ -3566,7 +3527,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) +
@@ -3650,7 +3612,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)
@@ -3698,11 +3661,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)
@@ -3722,7 +3686,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;