Fix no-ec
authorDr. Stephen Henson <steve@openssl.org>
Mon, 15 Aug 2016 13:07:33 +0000 (14:07 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 15 Aug 2016 13:07:33 +0000 (14:07 +0100)
Fix no-ec builds by having separate functions to create keys based on
an existing EVP_PKEY and a curve id.

Reviewed-by: Rich Salz <rsalz@openssl.org>
ssl/s3_lib.c
ssl/ssl_locl.h
ssl/statem/statem_clnt.c
ssl/statem/statem_srvr.c

index f1363ca..eea75a3 100644 (file)
@@ -3982,41 +3982,51 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
     return s->session->master_key_length >= 0;
 }
 
-/* Generate a private key from parameters or a curve ID */
-EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int id)
+/* Generate a private key from parameters */
+EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm)
 {
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
-    int nid;
-    if (pm != NULL) {
-        pctx = EVP_PKEY_CTX_new(pm, NULL);
+
+    if (pm == NULL)
+        return NULL;
+    pctx = EVP_PKEY_CTX_new(pm, NULL);
+    if (pctx == NULL)
+        goto err;
+    if (EVP_PKEY_keygen_init(pctx) <= 0)
+        goto err;
+    if (EVP_PKEY_keygen(pctx, &pkey) <= 0) {
+        EVP_PKEY_free(pkey);
+        pkey = NULL;
+    }
+
+    err:
+    EVP_PKEY_CTX_free(pctx);
+    return pkey;
+}
+#ifndef OPENSSL_NO_EC
+/* Generate a private key a curve ID */
+EVP_PKEY *ssl_generate_pkey_curve(int id)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned int curve_flags;
+    int nid = tls1_ec_curve_id2nid(id, &curve_flags);
+
+    if (nid == 0)
+        goto err;
+    if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
+        pctx = EVP_PKEY_CTX_new_id(nid, NULL);
         nid = 0;
     } else {
-        unsigned int curve_flags;
-        nid = tls1_ec_curve_id2nid(id, &curve_flags);
-        if (nid == 0)
-            goto err;
-        /*
-         * Generate a new key for this curve.
-         * Should not be called if EC is disabled: if it is it will
-         * fail with an unknown algorithm error.
-         */
-        if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
-            pctx = EVP_PKEY_CTX_new_id(nid, NULL);
-            nid = 0;
-        } else {
-            pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
-        }
+        pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
     }
     if (pctx == NULL)
         goto err;
     if (EVP_PKEY_keygen_init(pctx) <= 0)
         goto err;
-#ifndef OPENSSL_NO_EC
     if (nid != 0 && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0)
         goto err;
-#endif
-
     if (EVP_PKEY_keygen(pctx, &pkey) <= 0) {
         EVP_PKEY_free(pkey);
         pkey = NULL;
@@ -4026,6 +4036,7 @@ EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int id)
     EVP_PKEY_CTX_free(pctx);
     return pkey;
 }
+#endif
 /* Derive premaster or master secret for ECDH/DH */
 int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey)
 {
index 3c230d1..8566760 100644 (file)
@@ -1857,7 +1857,7 @@ void ssl_load_ciphers(void);
 __owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
 __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
                                       int free_pms);
-__owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int nid);
+__owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm);
 __owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey);
 __owur EVP_PKEY *ssl_dh_to_pkey(DH *dh);
 
@@ -2002,6 +2002,7 @@ __owur int tls1_set_curves(unsigned char **pext, size_t *pextlen,
 __owur int tls1_set_curves_list(unsigned char **pext, size_t *pextlen,
                          const char *str);
 __owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id);
+__owur EVP_PKEY *ssl_generate_pkey_curve(int id);
 #  endif                        /* OPENSSL_NO_EC */
 
 __owur int tls1_shared_list(SSL *s,
index 6f4c8ff..338a23b 100644 (file)
@@ -2250,7 +2250,7 @@ static int tls_construct_cke_dhe(SSL *s, unsigned char **p, int *len, int *al)
         SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
         return 0;
     }
-    ckey = ssl_generate_pkey(skey, NID_undef);
+    ckey = ssl_generate_pkey(skey);
     dh_clnt = EVP_PKEY_get0_DH(ckey);
 
     if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
@@ -2288,7 +2288,7 @@ static int tls_construct_cke_ecdhe(SSL *s, unsigned char **p, int *len, int *al)
         return 0;
     }
 
-    ckey = ssl_generate_pkey(skey, NID_undef);
+    ckey = ssl_generate_pkey(skey);
 
     if (ssl_derive(s, ckey, skey) == 0) {
         SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_EVP_LIB);
index a5fe752..d662163 100644 (file)
@@ -1703,7 +1703,7 @@ int tls_construct_server_key_exchange(SSL *s)
             goto err;
         }
 
-        s->s3->tmp.pkey = ssl_generate_pkey(pkdhp, NID_undef);
+        s->s3->tmp.pkey = ssl_generate_pkey(pkdhp);
 
         if (s->s3->tmp.pkey == NULL) {
             SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EVP_LIB);
@@ -1737,7 +1737,7 @@ int tls_construct_server_key_exchange(SSL *s)
                    SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
             goto err;
         }
-        s->s3->tmp.pkey = ssl_generate_pkey(NULL, curve_id);
+        s->s3->tmp.pkey = ssl_generate_pkey_curve(curve_id);
         /* Generate a new key for this curve */
         if (s->s3->tmp.pkey == NULL) {
             al = SSL_AD_INTERNAL_ERROR;