Have ssl3_ssl3_send_client_verify() change the state to SSL3_ST_SW_CERT_VRFY_B.
[openssl.git] / ssl / s3_clnt.c
index 2f12695377066da040bbd42ab874773c507ca998..b27a1deaa77bb9e44b65ea02b8b81184326ecb98 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1574,6 +1574,19 @@ static int ssl3_get_server_done(SSL *s)
        return(ret);
        }
 
+
+static const int KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(void *in, size_t inlen, void *out, size_t outlen)
+       {
+#ifndef OPENSSL_NO_SHA
+       if (outlen != SHA_DIGEST_LENGTH)
+               return NULL;
+       return SHA1(in, inlen, out);
+#else
+       return NULL;
+#endif
+       }
+
 static int ssl3_send_client_key_exchange(SSL *s)
        {
        unsigned char *p,*d;
@@ -1857,6 +1870,7 @@ static int ssl3_send_client_key_exchange(SSL *s)
                        {
                        EC_GROUP *srvr_group = NULL;
                        int ecdh_clnt_cert = 0;
+                       int field_size = 0;
 
                        /* Did we send out the client's
                         * ECDH share for use in premaster
@@ -1949,7 +1963,21 @@ static int ssl3_send_client_key_exchange(SSL *s)
                         * make sure to clear it out afterwards
                         */
 
-                       n=ECDH_compute_key(p, srvr_ecpoint, clnt_ecdh);
+                       field_size = EC_GROUP_get_degree(clnt_ecdh->group);
+                       if (field_size <= 0)
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 
+                                      ERR_R_ECDH_LIB);
+                               goto err;
+                               }
+                       /* If field size is not more than 24 octets, then use SHA-1 hash of result;
+                        * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt;
+                        * this is new with this version of the Internet Draft).
+                        */
+                       if (field_size <= 24 * 8)
+                               n=ECDH_compute_key(p, KDF1_SHA1_len, srvr_ecpoint, clnt_ecdh, KDF1_SHA1);
+                       else
+                               n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
                        if (n <= 0)
                                {
                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, 
@@ -2133,6 +2161,7 @@ static int ssl3_send_client_verify(SSL *s)
                *(d++)=SSL3_MT_CERTIFICATE_VERIFY;
                l2n3(n,d);
 
+               s->state=SSL3_ST_CW_CERT_VRFY_B;
                s->init_num=(int)n+4;
                s->init_off=0;
                }
@@ -2362,7 +2391,8 @@ err:
 /* This is the complement of nid2curve_id in s3_srvr.c. */
 static int curve_id2nid(int curve_id)
 {
-       /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */
+       /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001)
+        * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */
        static int nid_list[26] =
        {
                0,