This commit was manufactured by cvs2svn to create branch
[oweals/openssl.git] / ssl / s3_srvr.c
index bae14c17e59ceb8921f12922e006dcad3c8bc777..5944d8c484824a9147f6c6f7ede2d872f966e3dd 100644 (file)
@@ -236,6 +236,18 @@ int ssl3_accept(SSL *s)
                return(-1);
                }
 
+#ifndef OPENSSL_NO_HEARTBEATS
+       /* If we're awaiting a HeartbeatResponse, pretend we
+        * already got and don't await it anymore, because
+        * Heartbeats don't make sense during handshakes anyway.
+        */
+       if (s->tlsext_hb_pending)
+               {
+               s->tlsext_hb_pending = 0;
+               s->tlsext_hb_seq++;
+               }
+#endif
+
        for (;;)
                {
                state=s->state;
@@ -283,6 +295,7 @@ int ssl3_accept(SSL *s)
                                }
 
                        s->init_num=0;
+                       s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 
                        if (s->state != SSL_ST_RENEGOTIATE)
                                {
@@ -338,16 +351,27 @@ int ssl3_accept(SSL *s)
                case SSL3_ST_SR_CLNT_HELLO_C:
 
                        s->shutdown=0;
-
-                       ret=ssl3_get_client_hello(s);
-                       if (ret <= 0) goto end;
+                       if (s->rwstate != SSL_X509_LOOKUP)
+                       {
+                               ret=ssl3_get_client_hello(s);
+                               if (ret <= 0) goto end;
+                       }
 #ifndef OPENSSL_NO_SRP
                        {
                        int al;
-                       if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) != SSL_ERROR_NONE)
+                       if ((ret = ssl_check_srp_ext_ClientHello(s,&al))  < 0)
+                                       {
+                                       /* callback indicates firther work to be done */
+                                       s->rwstate=SSL_X509_LOOKUP;
+                                       goto end;
+                                       }
+                       if (ret != SSL_ERROR_NONE)
                                {
-                               ssl3_send_alert(s,SSL3_AL_FATAL,al);                            
-                               SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);                     
+                               ssl3_send_alert(s,SSL3_AL_FATAL,al);    
+                               /* This is not really an error but the only means to
+                                   for a client to detect whether srp is supported. */
+                                  if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)      
+                                       SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);                     
                                ret = SSL_TLSEXT_ERR_ALERT_FATAL;                       
                                ret= -1;
                                goto end;       
@@ -858,6 +882,13 @@ int ssl3_check_client_hello(SSL *s)
        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
@@ -874,6 +905,7 @@ int ssl3_check_client_hello(SSL *s)
                        s->s3->tmp.ecdh = NULL;
                        }
 #endif
+               s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
                return 2;
                }
        return 1;
@@ -2268,6 +2300,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                if (i <= 0)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+                       BN_clear_free(pub);
                        goto err;
                        }
 
@@ -2877,7 +2910,7 @@ int ssl3_get_cert_verify(SSL *s)
                SSL3_ST_SR_CERT_VRFY_A,
                SSL3_ST_SR_CERT_VRFY_B,
                -1,
-               514, /* 514? */
+               516, /* Enough for 4096 bit RSA key with TLS v1.2 */
                &ok);
 
        if (!ok) return((int)n);