PR: 2748
[openssl.git] / ssl / d1_srvr.c
index 1fd3d1c5a55d896c9971ef9c9d3c68da0d8ae6cd..17cc0227511d16d54c77fbe30bfc2fd8fc01c040 100644 (file)
@@ -150,6 +150,7 @@ int dtls1_accept(SSL *s)
        unsigned long alg_k;
        int ret= -1;
        int new_state,state,skip=0;
+       int listen;
 
        RAND_add(&Time,sizeof(Time),0);
        ERR_clear_error();
@@ -159,11 +160,15 @@ int dtls1_accept(SSL *s)
                cb=s->info_callback;
        else if (s->ctx->info_callback != NULL)
                cb=s->ctx->info_callback;
+       
+       listen = s->d1->listen;
 
        /* init things to blank */
        s->in_handshake++;
        if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
 
+       s->d1->listen = listen;
+
        if (s->cert == NULL)
                {
                SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
@@ -273,11 +278,23 @@ int dtls1_accept(SSL *s)
 
                        s->init_num=0;
 
+                       /* Reflect ClientHello sequence to remain stateless while listening */
+                       if (listen)
+                               {
+                               memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence));
+                               }
+
                        /* If we're just listening, stop here */
-                       if (s->d1->listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
+                       if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A)
                                {
                                ret = 2;
                                s->d1->listen = 0;
+                               /* Set expected sequence numbers
+                                * to continue the handshake.
+                                */
+                               s->d1->handshake_read_seq = 2;
+                               s->d1->handshake_write_seq = 1;
+                               s->d1->next_handshake_write_seq = 1;
                                goto end;
                                }
                        
@@ -286,7 +303,6 @@ int dtls1_accept(SSL *s)
                case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
                case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
 
-                       dtls1_start_timer(s);
                        ret = dtls1_send_hello_verify_request(s);
                        if ( ret <= 0) goto end;
                        s->state=SSL3_ST_SW_FLUSH;
@@ -469,15 +485,16 @@ int dtls1_accept(SSL *s)
                        ret = ssl3_check_client_hello(s);
                        if (ret <= 0)
                                goto end;
-                       dtls1_stop_timer(s);
                        if (ret == 2)
+                               {
+                               dtls1_stop_timer(s);
                                s->state = SSL3_ST_SR_CLNT_HELLO_C;
+                               }
                        else {
                                /* could be sent for a DH cert, even if we
                                 * have not asked for it :-) */
                                ret=ssl3_get_client_certificate(s);
                                if (ret <= 0) goto end;
-                               dtls1_stop_timer(s);
                                s->init_num=0;
                                s->state=SSL3_ST_SR_KEY_EXCH_A;
                        }
@@ -487,7 +504,6 @@ int dtls1_accept(SSL *s)
                case SSL3_ST_SR_KEY_EXCH_B:
                        ret=ssl3_get_client_key_exchange(s);
                        if (ret <= 0) goto end;
-                       dtls1_stop_timer(s);
                        s->state=SSL3_ST_SR_CERT_VRFY_A;
                        s->init_num=0;
 
@@ -524,7 +540,6 @@ int dtls1_accept(SSL *s)
                        /* we should decide if we expected this one */
                        ret=ssl3_get_cert_verify(s);
                        if (ret <= 0) goto end;
-                       dtls1_stop_timer(s);
 
                        s->state=SSL3_ST_SR_FINISHED_A;
                        s->init_num=0;
@@ -736,9 +751,6 @@ int dtls1_send_hello_verify_request(SSL *s)
                /* number of bytes to write */
                s->init_num=p-buf;
                s->init_off=0;
-
-               /* buffer the message to handle re-xmits */
-               dtls1_buffer_message(s, 0);
                }
 
        /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
@@ -1017,12 +1029,11 @@ int dtls1_send_server_key_exchange(SSL *s)
                                SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
                                goto err;
                                }
-                       if (!EC_KEY_up_ref(ecdhp))
+                       if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
                                {
                                SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
                                goto err;
                                }
-                       ecdh = ecdhp;
 
                        s->s3->tmp.ecdh=ecdh;
                        if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
@@ -1259,7 +1270,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
                                EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
                                EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
-                               EVP_SignUpdate(&md_ctx,&(d[4]),n);
+                               EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
                                if (!EVP_SignFinal(&md_ctx,&(p[2]),
                                        (unsigned int *)&i,pkey))
                                        {
@@ -1525,9 +1536,10 @@ int dtls1_send_newsession_ticket(SSL *s)
                p += hlen;
                /* Now write out lengths: p points to end of data written */
                /* Total length */
-               len = p - (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
+               len = p - (unsigned char *)(s->init_buf->data);
+               /* Ticket length */
                p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
-               s2n(len - 18, p);  /* Ticket length */
+               s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p);
 
                /* number of bytes to write */
                s->init_num= len;