Document dead code.
[openssl.git] / ssl / s3_srvr.c
index 8a4faa66fae63094c5d663bf066fed58e4736eaf..d7327649d5f07ce23761c046e00d42398463e9ca 100644 (file)
@@ -522,6 +522,7 @@ int ssl3_accept(SSL *s)
                                {
                                int offset=0;
                                int dgst_num;
+
                                s->state=SSL3_ST_SR_CERT_VRFY_A;
                                s->init_num=0;
 
@@ -531,12 +532,21 @@ int ssl3_accept(SSL *s)
                                 * should be generalized. But it is next step
                                 */
                                if (s->s3->handshake_buffer)
-                                       ssl3_digest_cached_records(s);
+                                       if (!ssl3_digest_cached_records(s))
+                                               return -1;
                                for (dgst_num=0; dgst_num<SSL_MAX_DIGEST;dgst_num++)    
                                        if (s->s3->handshake_dgst[dgst_num]) 
                                                {
+                                               int dgst_size;
+
                                                s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset]));
-                                               offset+=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
+                                               dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
+                                               if (dgst_size < 0)
+                                                       {
+                                                       ret = -1;
+                                                       goto end;
+                                                       }
+                                               offset+=dgst_size;
                                                }               
                                }
                        break;
@@ -947,22 +957,28 @@ int ssl3_get_client_hello(SSL *s)
                                break;
                                }
                        }
-               if (j == 0)
+               if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
                        {
-                       if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
+                       /* Special case as client bug workaround: the previously used cipher may
+                        * not be in the current list, the client instead might be trying to
+                        * continue using a cipher that before wasn't chosen due to server
+                        * preferences.  We'll have to reject the connection if the cipher is not
+                        * enabled, though. */
+                       c = sk_SSL_CIPHER_value(ciphers, 0);
+                       if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0)
                                {
-                               /* Very bad for multi-threading.... */
-                               s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0);
-                               }
-                       else
-                               {
-                               /* we need to have the cipher in the cipher
-                                * list if we are asked to reuse it */
-                               al=SSL_AD_ILLEGAL_PARAMETER;
-                               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
-                               goto f_err;
+                               s->session->cipher = c;
+                               j = 1;
                                }
                        }
+               if (j == 0)
+                       {
+                       /* we need to have the cipher in the cipher
+                        * list if we are asked to reuse it */
+                       al=SSL_AD_ILLEGAL_PARAMETER;
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
+                       goto f_err;
+                       }
                }
 
        /* compression */
@@ -1004,6 +1020,59 @@ int ssl3_get_client_hello(SSL *s)
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
                        goto err;
                }
+
+       /* Check if we want to use external pre-shared secret for this
+        * handshake for not reused session only. We need to generate
+        * server_random before calling tls_session_secret_cb in order to allow
+        * SessionTicket processing to use it in key derivation. */
+       {
+               unsigned long Time;
+               unsigned char *pos;
+               Time=(unsigned long)time(NULL);                 /* Time */
+               pos=s->s3->server_random;
+               l2n(Time,pos);
+               if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
+                       {
+                       al=SSL_AD_INTERNAL_ERROR;
+                       goto f_err;
+                       }
+       }
+
+       if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
+               {
+               SSL_CIPHER *pref_cipher=NULL;
+
+               s->session->master_key_length=sizeof(s->session->master_key);
+               if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
+                       ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
+                       {
+                       s->hit=1;
+                       s->session->ciphers=ciphers;
+                       s->session->verify_result=X509_V_OK;
+
+                       ciphers=NULL;
+
+                       /* check if some cipher was preferred by call back */
+                       pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
+                       if (pref_cipher == NULL)
+                               {
+                               al=SSL_AD_HANDSHAKE_FAILURE;
+                               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
+                               goto f_err;
+                               }
+
+                       s->session->cipher=pref_cipher;
+
+                       if (s->cipher_list)
+                               sk_SSL_CIPHER_free(s->cipher_list);
+
+                       if (s->cipher_list_by_id)
+                               sk_SSL_CIPHER_free(s->cipher_list_by_id);
+
+                       s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
+                       s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
+                       }
+               }
 #endif
 
        /* Worst case, we will use the NULL compression, but if we have other
@@ -1067,7 +1136,6 @@ int ssl3_get_client_hello(SSL *s)
                        goto f_err;
                        }
                s->s3->tmp.new_cipher=c;
-               ssl3_digest_cached_records(s);
                }
        else
                {
@@ -1098,10 +1166,10 @@ int ssl3_get_client_hello(SSL *s)
                else
 #endif
                s->s3->tmp.new_cipher=s->session->cipher;
-               /* Clear cached handshake records */
-               BIO_free(s->s3->handshake_buffer);
-               s->s3->handshake_buffer = NULL;
                }
+
+       if (!ssl3_digest_cached_records(s))
+               goto f_err;
        
        /* we now have the following setup. 
         * client_random
@@ -1130,16 +1198,22 @@ int ssl3_send_server_hello(SSL *s)
        unsigned char *buf;
        unsigned char *p,*d;
        int i,sl;
-       unsigned long l,Time;
+       unsigned long l;
+#ifdef OPENSSL_NO_TLSEXT
+       unsigned long Time;
+#endif
 
        if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
                {
                buf=(unsigned char *)s->init_buf->data;
+#ifdef OPENSSL_NO_TLSEXT
                p=s->s3->server_random;
+               /* Generate server_random if it was not needed previously */
                Time=(unsigned long)time(NULL);                 /* Time */
                l2n(Time,p);
                if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
                        return -1;
+#endif
                /* Do the message type and length last */
                d=p= &(buf[4]);
 
@@ -1210,13 +1284,13 @@ int ssl3_send_server_hello(SSL *s)
                *(d++)=SSL3_MT_SERVER_HELLO;
                l2n3(l,d);
 
-               s->state=SSL3_ST_CW_CLNT_HELLO_B;
+               s->state=SSL3_ST_SW_SRVR_HELLO_B;
                /* number of bytes to write */
                s->init_num=p-buf;
                s->init_off=0;
                }
 
-       /* SSL3_ST_CW_CLNT_HELLO_B */
+       /* SSL3_ST_SW_SRVR_HELLO_B */
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        }
 
@@ -1240,7 +1314,7 @@ int ssl3_send_server_done(SSL *s)
                s->init_off=0;
                }
 
-       /* SSL3_ST_CW_CLNT_HELLO_B */
+       /* SSL3_ST_SW_SRVR_DONE_B */
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        }