Change EVP_PKEY_CTX_new_provided() to take a library context too.
authorRichard Levitte <levitte@openssl.org>
Fri, 1 Nov 2019 15:56:31 +0000 (16:56 +0100)
committerRichard Levitte <levitte@openssl.org>
Sun, 3 Nov 2019 17:33:43 +0000 (18:33 +0100)
With provided algorithms, the library context is ever present, so of
course it should be specified alongside the algorithm name and
property query string.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10308)

crypto/evp/pmeth_lib.c
doc/man3/EVP_PKEY_CTX_new.pod
include/crypto/evp.h
include/openssl/evp.h

index 5ba844f53e808d4f1fb153d5b55733bbf7657a6f..d547e5a69dcb2866b5aa6adc43c570b1888dee75 100644 (file)
@@ -111,7 +111,8 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
     return (**ret)();
 }
 
-static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
+static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
+                                 EVP_PKEY *pkey, ENGINE *e,
                                  const char *name, const char *propquery,
                                  int id)
 {
@@ -149,6 +150,16 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
     if (e == NULL)
         name = OBJ_nid2sn(id);
     propquery = NULL;
+    /*
+     * We were called using legacy data, or an EVP_PKEY, but an EVP_PKEY
+     * isn't tied to a specific library context, so we fall back to the
+     * default library context.
+     * TODO(v3.0): an EVP_PKEY that doesn't originate from a leagacy key
+     * structure only has the pkeys[] cache, where the first element is
+     * considered the "origin".  Investigate if that could be a suitable
+     * way to find a library context.
+     */
+    libctx = NULL;
 
 #ifndef OPENSSL_NO_ENGINE
     if (e == NULL && pkey != NULL)
@@ -191,6 +202,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
         EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
+    ret->libctx = libctx;
     ret->algorithm = name;
     ret->propquery = propquery;
     ret->engine = e;
@@ -303,18 +315,19 @@ void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
 
 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
 {
-    return int_ctx_new(pkey, e, NULL, NULL, -1);
+    return int_ctx_new(NULL, pkey, e, NULL, NULL, -1);
 }
 
 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
 {
-    return int_ctx_new(NULL, e, NULL, NULL, id);
+    return int_ctx_new(NULL, NULL, e, NULL, NULL, id);
 }
 
-EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name,
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx,
+                                        const char *name,
                                         const char *propquery)
 {
-    return int_ctx_new(NULL, NULL, name, propquery, -1);
+    return int_ctx_new(libctx, NULL, NULL, name, propquery, -1);
 }
 
 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
@@ -344,6 +357,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
         EVP_PKEY_up_ref(pctx->pkey);
     rctx->pkey = pctx->pkey;
     rctx->operation = pctx->operation;
+    rctx->libctx = pctx->libctx;
     rctx->algorithm = pctx->algorithm;
     rctx->propquery = pctx->propquery;
 
index de7f439da549cf57a254065d2cea2f0a1b4d4f11..5d18a043444243dc936fa47b0b8682545538bb09 100644 (file)
@@ -12,7 +12,8 @@ EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free
 
  EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
  EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
- EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name,
+ EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx,
+                                         const char *name,
                                          const char *propquery);
  EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
  void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
@@ -25,11 +26,11 @@ the algorithm specified in I<pkey> and ENGINE I<e>.
 The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
 using the algorithm specified by I<id> and ENGINE I<e>.
 
-The EVP_PKEY_CTX_new_provided() function allocates a public key
-algorithm context using the algorithm specified by I<name> and the
-property query I<propquery>.  The strings aren't duplicated, so they
-must remain unchanged for the lifetime of the returned B<EVP_PKEY_CTX>
-or of any of its duplicates.
+The EVP_PKEY_CTX_new_provided() function allocates a public key algorithm
+context using the library context I<libctx> (see L<OPENSSL_CTX(3)>), the
+algorithm specified by I<name> and the property query I<propquery>.  None
+of the arguments are duplicated, so they  must remain unchanged for the
+lifetime of the returned B<EVP_PKEY_CTX> or of any of its duplicates.
 
 EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_new_provided() are normally
 used when no B<EVP_PKEY> structure is associated with the operations,
index dad7174bc532cb57532ab073932622988ec992ea..32ae121eeadf92383d964f9b859d9c6793b3a1e2 100644 (file)
@@ -21,7 +21,11 @@ struct evp_pkey_ctx_st {
     /* Actual operation */
     int operation;
 
-    /* Algorithm name and properties associated with this context */
+    /*
+     * Library context, Algorithm name and properties associated
+     * with this context
+     */
+    OPENSSL_CTX *libctx;
     const char *algorithm;
     const char *propquery;
 
index a0190c8b08e38f677111f1b9a4d442788c1f9526..baa1ce8c6c559b7ad5dfb01a7dc5080705d2f2fa 100644 (file)
@@ -1461,7 +1461,8 @@ void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
 
 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
-EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name,
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx,
+                                        const char *name,
                                         const char *propquery);
 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);