PR: 1829
[oweals/openssl.git] / ssl / d1_srvr.c
index 81c1790ab33d5f302272c1d0322047148a66f51a..bb290b88e34dd6ac817d33e2406f5a0358d7890b 100644 (file)
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/md5.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
 
 static SSL_METHOD *dtls1_get_server_method(int ver);
 static int dtls1_send_hello_verify_request(SSL *s);
@@ -133,33 +136,15 @@ static SSL_METHOD *dtls1_get_server_method(int ver)
                return(NULL);
        }
 
-SSL_METHOD *DTLSv1_server_method(void)
-       {
-       static int init=1;
-       static SSL_METHOD DTLSv1_server_data;
-
-       if (init)
-               {
-               CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
-
-               if (init)
-                       {
-                       memcpy((char *)&DTLSv1_server_data,(char *)dtlsv1_base_method(),
-                               sizeof(SSL_METHOD));
-                       DTLSv1_server_data.ssl_accept=dtls1_accept;
-                       DTLSv1_server_data.get_ssl_method=dtls1_get_server_method;
-                       init=0;
-                       }
-                       
-               CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
-               }
-       return(&DTLSv1_server_data);
-       }
+IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,
+                       dtls1_accept,
+                       ssl_undefined_function,
+                       dtls1_get_server_method)
 
 int dtls1_accept(SSL *s)
        {
        BUF_MEM *buf;
-       unsigned long l,Time=time(NULL);
+       unsigned long l,Time=(unsigned long)time(NULL);
        void (*cb)(const SSL *ssl,int type,int val)=NULL;
        long num1;
        int ret= -1;
@@ -180,7 +165,7 @@ int dtls1_accept(SSL *s)
 
        if (s->cert == NULL)
                {
-               SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
+               SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
                return(-1);
                }
 
@@ -204,7 +189,7 @@ int dtls1_accept(SSL *s)
 
                        if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00))
                                {
-                               SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+                               SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
                                return -1;
                                }
                        s->type=SSL_ST_ACCEPT;
@@ -262,6 +247,7 @@ int dtls1_accept(SSL *s)
                case SSL3_ST_SW_HELLO_REQ_B:
 
                        s->shutdown=0;
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                        ret=dtls1_send_hello_request(s);
                        if (ret <= 0) goto end;
                        s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
@@ -282,6 +268,7 @@ int dtls1_accept(SSL *s)
                        s->shutdown=0;
                        ret=ssl3_get_client_hello(s);
                        if (ret <= 0) goto end;
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
                        s->new_session = 2;
 
                        if ( s->d1->send_cookie)
@@ -295,15 +282,21 @@ int dtls1_accept(SSL *s)
                case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
                case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
 
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                        ret = dtls1_send_hello_verify_request(s);
                        if ( ret <= 0) goto end;
                        s->d1->send_cookie = 0;
                        s->state=SSL3_ST_SW_FLUSH;
                        s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
+
+                       /* HelloVerifyRequests resets Finished MAC */
+                       if (s->client_version != DTLS1_BAD_VER)
+                               ssl3_init_finished_mac(s);
                        break;
                        
                case SSL3_ST_SW_SRVR_HELLO_A:
                case SSL3_ST_SW_SRVR_HELLO_B:
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                        ret=dtls1_send_server_hello(s);
                        if (ret <= 0) goto end;
 
@@ -319,6 +312,7 @@ int dtls1_accept(SSL *s)
                        /* Check if it is anon DH */
                        if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
                                {
+                               BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                                ret=dtls1_send_server_certificate(s);
                                if (ret <= 0) goto end;
                                }
@@ -360,6 +354,7 @@ int dtls1_accept(SSL *s)
                                )
                            )
                                {
+                               BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                                ret=dtls1_send_server_key_exchange(s);
                                if (ret <= 0) goto end;
                                }
@@ -396,6 +391,7 @@ int dtls1_accept(SSL *s)
                        else
                                {
                                s->s3->tmp.cert_request=1;
+                               BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                                ret=dtls1_send_certificate_request(s);
                                if (ret <= 0) goto end;
 #ifndef NETSCAPE_HANG_BUG
@@ -410,6 +406,7 @@ int dtls1_accept(SSL *s)
 
                case SSL3_ST_SW_SRVR_DONE_A:
                case SSL3_ST_SW_SRVR_DONE_B:
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
                        ret=dtls1_send_server_done(s);
                        if (ret <= 0) goto end;
                        s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
@@ -437,6 +434,7 @@ int dtls1_accept(SSL *s)
                        ret = ssl3_check_client_hello(s);
                        if (ret <= 0)
                                goto end;
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
                        if (ret == 2)
                                s->state = SSL3_ST_SR_CLNT_HELLO_C;
                        else {
@@ -444,6 +442,7 @@ int dtls1_accept(SSL *s)
                                 * have not asked for it :-) */
                                ret=ssl3_get_client_certificate(s);
                                if (ret <= 0) goto end;
+                               BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
                                s->init_num=0;
                                s->state=SSL3_ST_SR_KEY_EXCH_A;
                        }
@@ -453,6 +452,7 @@ int dtls1_accept(SSL *s)
                case SSL3_ST_SR_KEY_EXCH_B:
                        ret=ssl3_get_client_key_exchange(s);
                        if (ret <= 0) goto end;
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
                        s->state=SSL3_ST_SR_CERT_VRFY_A;
                        s->init_num=0;
 
@@ -473,6 +473,7 @@ int dtls1_accept(SSL *s)
                        /* we should decide if we expected this one */
                        ret=ssl3_get_cert_verify(s);
                        if (ret <= 0) goto end;
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
 
                        s->state=SSL3_ST_SR_FINISHED_A;
                        s->init_num=0;
@@ -483,6 +484,7 @@ int dtls1_accept(SSL *s)
                        ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
                                SSL3_ST_SR_FINISHED_B);
                        if (ret <= 0) goto end;
+                       BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
                        if (s->hit)
                                s->state=SSL_ST_OK;
                        else
@@ -569,7 +571,7 @@ int dtls1_accept(SSL *s)
                        /* break; */
 
                default:
-                       SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_UNKNOWN_STATE);
+                       SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE);
                        ret= -1;
                        goto end;
                        /* break; */
@@ -635,20 +637,24 @@ int dtls1_send_hello_verify_request(SSL *s)
                buf = (unsigned char *)s->init_buf->data;
 
                msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
-               *(p++) = s->version >> 8;
-               *(p++) = s->version & 0xFF;
+               if (s->client_version == DTLS1_BAD_VER)
+                       *(p++) = DTLS1_BAD_VER>>8,
+                       *(p++) = DTLS1_BAD_VER&0xff;
+               else
+                       *(p++) = s->version >> 8,
+                       *(p++) = s->version & 0xFF;
 
-               *(p++) = (unsigned char) s->d1->cookie_len;
-        if ( s->ctx->app_gen_cookie_cb != NULL &&
-            s->ctx->app_gen_cookie_cb(s, s->d1->cookie, 
-                &(s->d1->cookie_len)) == 0)
-            {
+               if (s->ctx->app_gen_cookie_cb != NULL &&
+                   s->ctx->app_gen_cookie_cb(s, s->d1->cookie, 
+                   &(s->d1->cookie_len)) == 0)
+                       {
                        SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
-            return 0;
-            }
-        /* else the cookie is assumed to have 
-         * been initialized by the application */
+                       return 0;
+                       }
+               /* else the cookie is assumed to have 
+                * been initialized by the application */
 
+               *(p++) = (unsigned char) s->d1->cookie_len;
                memcpy(p, s->d1->cookie, s->d1->cookie_len);
                p += s->d1->cookie_len;
                msg_len = p - msg;
@@ -673,21 +679,26 @@ int dtls1_send_server_hello(SSL *s)
        {
        unsigned char *buf;
        unsigned char *p,*d;
-       int i,sl;
+       int i;
+       unsigned int sl;
        unsigned long l,Time;
 
        if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
                {
                buf=(unsigned char *)s->init_buf->data;
                p=s->s3->server_random;
-               Time=time(NULL);                        /* Time */
+               Time=(unsigned long)time(NULL);                 /* Time */
                l2n(Time,p);
                RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
                /* Do the message type and length last */
                d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
 
-               *(p++)=s->version>>8;
-               *(p++)=s->version&0xff;
+               if (s->client_version == DTLS1_BAD_VER)
+                       *(p++)=DTLS1_BAD_VER>>8,
+                       *(p++)=DTLS1_BAD_VER&0xff;
+               else
+                       *(p++)=s->version>>8,
+                       *(p++)=s->version&0xff;
 
                /* Random stuff */
                memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
@@ -707,7 +718,7 @@ int dtls1_send_server_hello(SSL *s)
                sl=s->session->session_id_length;
                if (sl > sizeof s->session->session_id)
                        {
-                       SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+                       SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
                        return -1;
                        }
                *(p++)=sl;
@@ -719,10 +730,14 @@ int dtls1_send_server_hello(SSL *s)
                p+=i;
 
                /* put the compression method */
+#ifdef OPENSSL_NO_COMP
+               *(p++)=0;
+#else
                if (s->s3->tmp.new_compression == NULL)
                        *(p++)=0;
                else
                        *(p++)=s->s3->tmp.new_compression->id;
+#endif
 
                /* do the header */
                l=(p-d);
@@ -730,7 +745,7 @@ int dtls1_send_server_hello(SSL *s)
 
                d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
 
-               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;
@@ -739,7 +754,7 @@ int dtls1_send_server_hello(SSL *s)
                dtls1_buffer_message(s, 0);
                }
 
-       /* SSL3_ST_CW_CLNT_HELLO_B */
+       /* SSL3_ST_SW_SRVR_HELLO_B */
        return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        }
 
@@ -763,7 +778,7 @@ int dtls1_send_server_done(SSL *s)
                dtls1_buffer_message(s, 0);
                }
 
-       /* SSL3_ST_CW_CLNT_HELLO_B */
+       /* SSL3_ST_SW_SRVR_DONE_B */
        return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        }
 
@@ -812,7 +827,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                if(rsa == NULL)
                                {
                                        al=SSL_AD_HANDSHAKE_FAILURE;
-                                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
+                                       SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
                                        goto f_err;
                                }
                                RSA_up_ref(rsa);
@@ -821,7 +836,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                        if (rsa == NULL)
                                {
                                al=SSL_AD_HANDSHAKE_FAILURE;
-                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
+                               SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
                                goto f_err;
                                }
                        r[0]=rsa->n;
@@ -841,20 +856,20 @@ int dtls1_send_server_key_exchange(SSL *s)
                        if (dhp == NULL)
                                {
                                al=SSL_AD_HANDSHAKE_FAILURE;
-                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
+                               SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
                                goto f_err;
                                }
 
                        if (s->s3->tmp.dh != NULL)
                                {
                                DH_free(dh);
-                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+                               SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
                                goto err;
                                }
 
                        if ((dh=DHparams_dup(dhp)) == NULL)
                                {
-                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
+                               SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
                                goto err;
                                }
 
@@ -865,7 +880,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                {
                                if(!DH_generate_key(dh))
                                    {
-                                   SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
+                                   SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                                           ERR_R_DH_LIB);
                                    goto err;
                                    }
@@ -877,7 +892,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                if ((dh->pub_key == NULL) ||
                                        (dh->priv_key == NULL))
                                        {
-                                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
+                                       SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
                                        goto err;
                                        }
                                }
@@ -889,7 +904,7 @@ int dtls1_send_server_key_exchange(SSL *s)
 #endif
                        {
                        al=SSL_AD_HANDSHAKE_FAILURE;
-                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+                       SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
                        goto f_err;
                        }
                for (i=0; r[i] != NULL; i++)
@@ -916,7 +931,7 @@ int dtls1_send_server_key_exchange(SSL *s)
 
                if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn))
                        {
-                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
+                       SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
                        goto err;
                        }
                d=(unsigned char *)s->init_buf->data;
@@ -955,7 +970,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                if (RSA_sign(NID_md5_sha1, md_buf, j,
                                        &(p[2]), &u, pkey->pkey.rsa) <= 0)
                                        {
-                                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
+                                       SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
                                        goto err;
                                        }
                                s2n(u,p);
@@ -974,7 +989,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                if (!EVP_SignFinal(&md_ctx,&(p[2]),
                                        (unsigned int *)&i,pkey))
                                        {
-                                       SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
+                                       SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
                                        goto err;
                                        }
                                s2n(i,p);
@@ -985,7 +1000,7 @@ int dtls1_send_server_key_exchange(SSL *s)
                                {
                                /* Is this error check actually needed? */
                                al=SSL_AD_HANDSHAKE_FAILURE;
-                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
+                               SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
                                goto f_err;
                                }
                        }
@@ -1019,6 +1034,7 @@ int dtls1_send_certificate_request(SSL *s)
        STACK_OF(X509_NAME) *sk=NULL;
        X509_NAME *name;
        BUF_MEM *buf;
+       unsigned int msg_len;
 
        if (s->state == SSL3_ST_SW_CERT_REQ_A)
                {
@@ -1047,7 +1063,7 @@ int dtls1_send_certificate_request(SSL *s)
                                j=i2d_X509_NAME(name,NULL);
                                if (!BUF_MEM_grow_clean(buf,DTLS1_HM_HEADER_LENGTH+n+j+2))
                                        {
-                                       SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+                                       SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
                                        goto err;
                                        }
                                p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+n]);
@@ -1075,7 +1091,7 @@ int dtls1_send_certificate_request(SSL *s)
                d=(unsigned char *)buf->data;
                *(d++)=SSL3_MT_CERTIFICATE_REQUEST;
                l2n3(n,d);
-               l2n(s->d1->handshake_write_seq,d);
+               s2n(s->d1->handshake_write_seq,d);
                s->d1->handshake_write_seq++;
 
                /* we should now have things packed up, so lets send
@@ -1096,6 +1112,10 @@ int dtls1_send_certificate_request(SSL *s)
 #endif
 
                /* XDTLS:  set message header ? */
+               msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
+               dtls1_set_message_header(s, (void *)s->init_buf->data,
+                       SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len);
+
                /* buffer the message to handle re-xmits */
                dtls1_buffer_message(s, 0);
 
@@ -1122,7 +1142,7 @@ int dtls1_send_server_certificate(SSL *s)
                                 & (SSL_MKEY_MASK|SSL_AUTH_MASK))
                         != (SSL_aKRB5|SSL_kKRB5))
                        {
-                       SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+                       SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
                        return(0);
                        }