Further BUILDENV refinement, further fool-proofing of Makefiles and
[openssl.git] / ssl / s3_srvr.c
index ff2fd3082196cd9ca32257b5ad6e7de00eea96ab..4b1931a71fe1e0f016bf6087e4c4fb564819db11 100644 (file)
@@ -677,7 +677,7 @@ int ssl3_check_client_hello(SSL *s)
 int ssl3_get_client_hello(SSL *s)
        {
        int i,j,ok,al,ret= -1;
-       int cookie_len;
+       unsigned int cookie_len;
        long n;
        unsigned long id;
        unsigned char *p,*d,*q;
@@ -767,60 +767,60 @@ int ssl3_get_client_hello(SSL *s)
                /* cookie stuff */
                cookie_len = *(p++);
 
-        if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
-            s->d1->send_cookie == 0)
-            {
-            /* HelloVerifyMessage has already been sent */
-            if ( cookie_len != s->d1->cookie_len)
-                {
-                al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
-                goto f_err;
-                }
-            }
+               if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
+                       s->d1->send_cookie == 0)
+                       {
+                       /* HelloVerifyMessage has already been sent */
+                       if ( cookie_len != s->d1->cookie_len)
+                               {
+                               al = SSL_AD_HANDSHAKE_FAILURE;
+                               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
+                               goto f_err;
+                               }
+                       }
 
-        /* 
-         * The ClientHello may contain a cookie even if the
-         * HelloVerify message has not been sent--make sure that it
-         * does not cause an overflow.
-         */
+               /* 
+                * The ClientHello may contain a cookie even if the
+                * HelloVerify message has not been sent--make sure that it
+                * does not cause an overflow.
+                */
                if ( cookie_len > sizeof(s->d1->rcvd_cookie))
                        {
                        /* too much data */
-            al = SSL_AD_DECODE_ERROR;
+                       al = SSL_AD_DECODE_ERROR;
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
                        goto f_err;
                        }
 
-        /* verify the cookie if appropriate option is set. */
-        if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
-            cookie_len > 0)
-            {
-            memcpy(s->d1->rcvd_cookie, p, cookie_len);
+               /* verify the cookie if appropriate option is set. */
+               if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&
+                       cookie_len > 0)
+                       {
+                       memcpy(s->d1->rcvd_cookie, p, cookie_len);
 
-            if ( s->ctx->app_verify_cookie_cb != NULL)
-                {
-                if ( s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
-                    cookie_len) == 0)
-                    {
-                    al=SSL_AD_HANDSHAKE_FAILURE;
-                    SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
-                        SSL_R_COOKIE_MISMATCH);
-                    goto f_err;
-                    }
-                /* else cookie verification succeeded */
-                }
-            else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, 
-                          s->d1->cookie_len) != 0) /* default verification */
-                {
-                    al=SSL_AD_HANDSHAKE_FAILURE;
-                    SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
-                        SSL_R_COOKIE_MISMATCH);
-                    goto f_err;
-                }
-            }
+                       if ( s->ctx->app_verify_cookie_cb != NULL)
+                               {
+                               if ( s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
+                                       cookie_len) == 0)
+                                       {
+                                       al=SSL_AD_HANDSHAKE_FAILURE;
+                                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
+                                               SSL_R_COOKIE_MISMATCH);
+                                       goto f_err;
+                                       }
+                               /* else cookie verification succeeded */
+                               }
+                       else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, 
+                                                 s->d1->cookie_len) != 0) /* default verification */
+                               {
+                                       al=SSL_AD_HANDSHAKE_FAILURE;
+                                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 
+                                               SSL_R_COOKIE_MISMATCH);
+                                       goto f_err;
+                               }
+                       }
 
-        p += cookie_len;
+               p += cookie_len;
                }
 
        n2s(p,i);
@@ -872,8 +872,7 @@ int ssl3_get_client_hello(SSL *s)
                        if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
                                {
                                /* Very bad for multi-threading.... */
-                               s->session->cipher=sk_SSL_CIPHER_value(ciphers,
-                                                                      0);
+                               s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0);
                                }
                        else
                                {
@@ -1049,7 +1048,8 @@ int ssl3_send_server_hello(SSL *s)
                p=s->s3->server_random;
                Time=time(NULL);                        /* Time */
                l2n(Time,p);
-               RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
+               if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+                       return -1;
                /* Do the message type and length last */
                d=p= &(buf[4]);
 
@@ -1261,6 +1261,8 @@ int ssl3_send_server_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_ECDH
                        if (type & SSL_kECDHE)
                        {
+                       const EC_GROUP *group;
+
                        ecdhp=cert->ecdh_tmp;
                        if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
                                {
@@ -1290,14 +1292,14 @@ int ssl3_send_server_key_exchange(SSL *s)
                                }
                        if (!EC_KEY_up_ref(ecdhp))
                                {
-                               SSLerr(SSL_F_SSL3_CTRL,ERR_R_ECDH_LIB);
+                               SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
                                goto err;
                                }
                        ecdh = ecdhp;
 
                        s->s3->tmp.ecdh=ecdh;
-                       if ((ecdh->pub_key == NULL) ||
-                           (ecdh->priv_key == NULL) ||
+                       if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
+                           (EC_KEY_get0_private_key(ecdh) == NULL) ||
                            (s->options & SSL_OP_SINGLE_ECDH_USE))
                                {
                                if(!EC_KEY_generate_key(ecdh))
@@ -1307,16 +1309,16 @@ int ssl3_send_server_key_exchange(SSL *s)
                                    }
                                }
 
-                       if ((ecdh->group == NULL) ||
-                           (ecdh->pub_key == NULL) ||
-                           (ecdh->priv_key == NULL))
+                       if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
+                           (EC_KEY_get0_public_key(ecdh)  == NULL) ||
+                           (EC_KEY_get0_private_key(ecdh) == NULL))
                                {
                                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
                                goto err;
                                }
 
                        if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
-                           (EC_GROUP_get_degree(ecdh->group) > 163)) 
+                           (EC_GROUP_get_degree(group) > 163)) 
                                {
                                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
                                goto err;
@@ -1327,7 +1329,7 @@ int ssl3_send_server_key_exchange(SSL *s)
                         * supported named curves, curve_id is non-zero.
                         */
                        if ((curve_id = 
-                           nid2curve_id(EC_GROUP_get_nid(ecdh->group)))
+                           nid2curve_id(EC_GROUP_get_curve_name(group)))
                            == 0)
                                {
                                SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
@@ -1338,8 +1340,8 @@ int ssl3_send_server_key_exchange(SSL *s)
                         * First check the size of encoding and
                         * allocate memory accordingly.
                         */
-                       encodedlen = EC_POINT_point2oct(ecdh->group, 
-                           ecdh->pub_key, 
+                       encodedlen = EC_POINT_point2oct(group, 
+                           EC_KEY_get0_public_key(ecdh),
                            POINT_CONVERSION_UNCOMPRESSED, 
                            NULL, 0, NULL);
 
@@ -1353,8 +1355,8 @@ int ssl3_send_server_key_exchange(SSL *s)
                                }
 
 
-                       encodedlen = EC_POINT_point2oct(ecdh->group, 
-                           ecdh->pub_key
+                       encodedlen = EC_POINT_point2oct(group, 
+                           EC_KEY_get0_public_key(ecdh)
                            POINT_CONVERSION_UNCOMPRESSED, 
                            encodedPoint, encodedlen, bn_ctx);
 
@@ -1785,7 +1787,8 @@ int ssl3_get_client_key_exchange(SSL *s)
                        i = SSL_MAX_MASTER_KEY_LENGTH;
                        p[0] = s->client_version >> 8;
                        p[1] = s->client_version & 0xff;
-                       RAND_pseudo_bytes(p+2, i-2); /* should be RAND_bytes, but we cannot work around a failure */
+                       if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
+                               goto err;
                        }
        
                s->session->master_key_length=
@@ -1882,11 +1885,27 @@ int ssl3_get_client_key_exchange(SSL *s)
 
                n2s(p,i);
                enc_ticket.length = i;
+
+               if (n < enc_ticket.length + 6)
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               SSL_R_DATA_LENGTH_TOO_LONG);
+                       goto err;
+                       }
+
                enc_ticket.data = (char *)p;
                p+=enc_ticket.length;
 
                n2s(p,i);
                authenticator.length = i;
+
+               if (n < enc_ticket.length + authenticator.length + 6)
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               SSL_R_DATA_LENGTH_TOO_LONG);
+                       goto err;
+                       }
+
                authenticator.data = (char *)p;
                p+=authenticator.length;
 
@@ -1922,7 +1941,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                         if (kssl_err.text)
                                 printf("kssl_err text= %s\n", kssl_err.text);
 #endif /* KSSL_DEBUG */
-                        SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                 kssl_err.reason);
                         goto err;
                         }
@@ -1939,14 +1958,14 @@ int ssl3_get_client_key_exchange(SSL *s)
                         if (kssl_err.text)
                                 printf("kssl_err text= %s\n", kssl_err.text);
 #endif /* KSSL_DEBUG */
-                        SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                 kssl_err.reason);
                         goto err;
                        }
 
                if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
                        {
-                       SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc);
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
                         goto err;
                        }
 
@@ -2023,6 +2042,9 @@ int ssl3_get_client_key_exchange(SSL *s)
                {
                int ret = 1;
                int field_size = 0;
+               const EC_KEY   *tkey;
+               const EC_GROUP *group;
+               const BIGNUM *priv_key;
 
                 /* initialize structures for server's ECDH key pair */
                if ((srvr_ecdh = EC_KEY_new()) == NULL) 
@@ -2036,23 +2058,29 @@ int ssl3_get_client_key_exchange(SSL *s)
                if (l & SSL_kECDH) 
                        { 
                         /* use the certificate */
-                       srvr_ecdh->group = s->cert->key->privatekey-> \
-                           pkey.eckey->group;
-                       srvr_ecdh->priv_key = s->cert->key->privatekey-> \
-                           pkey.eckey->priv_key;
+                       tkey = s->cert->key->privatekey->pkey.ec;
                        }
                else
                        {
                        /* use the ephermeral values we saved when
                         * generating the ServerKeyExchange msg.
                         */
-                       srvr_ecdh->group = s->s3->tmp.ecdh->group;
-                       srvr_ecdh->priv_key = s->s3->tmp.ecdh->priv_key;
+                       tkey = s->s3->tmp.ecdh;
+                       }
+
+               group    = EC_KEY_get0_group(tkey);
+               priv_key = EC_KEY_get0_private_key(tkey);
+
+               if (!EC_KEY_set_group(srvr_ecdh, group) ||
+                   !EC_KEY_set_private_key(srvr_ecdh, priv_key))
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                              ERR_R_EC_LIB);
+                       goto err;
                        }
 
                /* Let's get client's public key */
-               if ((clnt_ecpoint = EC_POINT_new(srvr_ecdh->group))
-                   == NULL) 
+               if ((clnt_ecpoint = EC_POINT_new(group)) == NULL)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                            ERR_R_MALLOC_FAILURE);
@@ -2091,7 +2119,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                                }
 
                        EC_POINT_copy(clnt_ecpoint,
-                           clnt_pub_pkey->pkey.eckey->pub_key);
+                           EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec));
                         ret = 2; /* Skip certificate verify processing */
                         }
                 else
@@ -2109,7 +2137,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                         /* Get encoded point length */
                         i = *p; 
                        p += 1;
-                        if (EC_POINT_oct2point(srvr_ecdh->group, 
+                        if (EC_POINT_oct2point(group, 
                            clnt_ecpoint, p, i, bn_ctx) == 0)
                                {
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
@@ -2123,7 +2151,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                         }
 
                /* Compute the shared pre-master secret */
-               field_size = EC_GROUP_get_degree(srvr_ecdh->group);
+               field_size = EC_GROUP_get_degree(group);
                if (field_size <= 0)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, 
@@ -2148,11 +2176,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                EVP_PKEY_free(clnt_pub_pkey);
                EC_POINT_free(clnt_ecpoint);
                if (srvr_ecdh != NULL) 
-                       {
-                       srvr_ecdh->priv_key = NULL;
-                       srvr_ecdh->group = NULL;
                        EC_KEY_free(srvr_ecdh);
-                       }
                BN_CTX_free(bn_ctx);
 
                /* Compute the master secret */
@@ -2181,11 +2205,7 @@ err:
        EVP_PKEY_free(clnt_pub_pkey);
        EC_POINT_free(clnt_ecpoint);
        if (srvr_ecdh != NULL) 
-               {
-               srvr_ecdh->priv_key = NULL;
-               srvr_ecdh->group = NULL;
                EC_KEY_free(srvr_ecdh);
-               }
        BN_CTX_free(bn_ctx);
 #endif
        return(-1);
@@ -2316,7 +2336,7 @@ int ssl3_get_cert_verify(SSL *s)
                {
                j=ECDSA_verify(pkey->save_type,
                        &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
-                       SHA_DIGEST_LENGTH,p,i,pkey->pkey.eckey);
+                       SHA_DIGEST_LENGTH,p,i,pkey->pkey.ec);
                if (j <= 0)
                        {
                        /* bad signature */