Explicitly cache the X509v3_extensions in one more place in libssl
[openssl.git] / ssl / s3_lib.c
index f5e313b21f1741558ab8893e3b71f8819d6c686e..9902fa38116461f42a18959b2c006f247823d6d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
  *
@@ -17,6 +17,7 @@
 #include <openssl/dh.h>
 #include <openssl/rand.h>
 #include <openssl/trace.h>
+#include <openssl/x509v3.h>
 #include "internal/cryptlib.h"
 
 #define TLS13_NUM_CIPHERS       OSSL_NELEM(tls13_ciphers)
@@ -2636,7 +2637,23 @@ static SSL_CIPHER ssl3_ciphers[] = {
      },
     {
      1,
-     "GOST2012-GOST8912-GOST8912",
+     "IANA-GOST2012-GOST8912-GOST8912",
+     NULL,
+     0x0300c102,
+     SSL_kGOST,
+     SSL_aGOST12 | SSL_aGOST01,
+     SSL_eGOST2814789CNT12,
+     SSL_GOST89MAC12,
+     TLS1_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC,
+     256,
+     256,
+     },
+    {
+     1,
+     "LEGACY-GOST2012-GOST8912-GOST8912",
      NULL,
      0x0300ff85,
      SSL_kGOST,
@@ -3947,6 +3964,10 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
                 return 0;
             }
         }
+        if (!X509v3_cache_extensions((X509 *)parg, ctx->libctx, ctx->propq)) {
+            SSLerr(0, ERR_LIB_X509);
+            return 0;
+        }
         if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) {
             SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE);
             return 0;
@@ -4642,7 +4663,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
         OPENSSL_clear_free(s->s3.tmp.psk, psklen);
         s->s3.tmp.psk = NULL;
         if (!s->method->ssl3_enc->generate_master_secret(s,
-                    s->session->master_key,pskpms, pskpmslen,
+                    s->session->master_key, pskpms, pskpmslen,
                     &s->session->master_key_length)) {
             OPENSSL_clear_free(pskpms, pskpmslen);
             /* SSLfatal() already called */
@@ -4676,14 +4697,14 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
 }
 
 /* Generate a private key from parameters */
-EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm)
+EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm)
 {
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
 
     if (pm == NULL)
         return NULL;
-    pctx = EVP_PKEY_CTX_new(pm, NULL);
+    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pm, s->ctx->propq);
     if (pctx == NULL)
         goto err;
     if (EVP_PKEY_keygen_init(pctx) <= 0)
@@ -4716,21 +4737,40 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
         goto err;
     }
     gtype = ginf->flags & TLS_GROUP_TYPE;
+    /*
+     * TODO(3.0): Convert these EVP_PKEY_CTX_new_id calls to ones that take
+     * s->ctx->libctx and s->ctx->propq when keygen has been updated to be
+     * provider aware.
+     */
 # ifndef OPENSSL_NO_DH
     if (gtype == TLS_GROUP_FFDHE)
+#  if 0
+        pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq);
+#  else
         pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
+#  endif
 #  ifndef OPENSSL_NO_EC
     else
-#  endif
-# endif
+#  endif /* OPENSSL_NO_EC */
+# endif /* OPENSSL_NO_DH */
 # ifndef OPENSSL_NO_EC
     {
+        /*
+         * TODO(3.0): When provider based EC key gen is present we can enable
+         * this code.
+         */
         if (gtype == TLS_GROUP_CURVE_CUSTOM)
             pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL);
         else
+#  if 0
+            pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "EC",
+                                              s->ctx->propq);
+#  else
             pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+#  endif
+
     }
-# endif
+# endif /* OPENSSL_NO_EC */
     if (pctx == NULL) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP,
                  ERR_R_MALLOC_FAILURE);
@@ -4747,7 +4787,7 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
                 || (dh = DH_new_by_nid(ginf->nid)) == NULL
                 || !EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP,
-                    ERR_R_EVP_LIB);
+                     ERR_R_EVP_LIB);
             DH_free(dh);
             EVP_PKEY_free(pkey);
             pkey = NULL;
@@ -4755,7 +4795,7 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
         }
         if (EVP_PKEY_CTX_set_dh_nid(pctx, ginf->nid) <= 0) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP,
-                    ERR_R_EVP_LIB);
+                     ERR_R_EVP_LIB);
             EVP_PKEY_free(pkey);
             pkey = NULL;
             goto err;
@@ -4791,12 +4831,16 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
 /*
  * Generate parameters from a group ID
  */
-EVP_PKEY *ssl_generate_param_group(uint16_t id)
+EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id)
 {
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
     const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id);
+#if 0
+    const char *pkey_ctx_name;
+#else
     int pkey_ctx_id;
+#endif
 
     if (ginf == NULL)
         goto err;
@@ -4809,9 +4853,21 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id)
         return NULL;
     }
 
+    /*
+     * TODO(3.0): Convert this EVP_PKEY_CTX_new_id call to one that takes
+     * s->ctx->libctx and s->ctx->propq when paramgen has been updated to be
+     * provider aware.
+     */
+#if 0
+    pkey_ctx_name = (ginf->flags & TLS_GROUP_FFDHE) != 0 ? "DH" : "EC";
+    pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, pkey_ctx_name,
+                                      s->ctx->propq);
+#else
     pkey_ctx_id = (ginf->flags & TLS_GROUP_FFDHE)
                         ? EVP_PKEY_DH : EVP_PKEY_EC;
     pctx = EVP_PKEY_CTX_new_id(pkey_ctx_id, NULL);
+#endif
+
     if (pctx == NULL)
         goto err;
     if (EVP_PKEY_paramgen_init(pctx) <= 0)
@@ -4855,7 +4911,7 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
         return 0;
     }
 
-    pctx = EVP_PKEY_CTX_new(privkey, NULL);
+    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq);
 
     if (EVP_PKEY_derive_init(pctx) <= 0
         || EVP_PKEY_derive_set_peer(pctx, pubkey) <= 0