Adapt int_ctx_new() to use with providers
authorRichard Levitte <levitte@openssl.org>
Tue, 9 Jul 2019 15:31:24 +0000 (17:31 +0200)
committerRichard Levitte <levitte@openssl.org>
Mon, 22 Jul 2019 04:18:58 +0000 (06:18 +0200)
This affects all its callers: EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id().
They are now possible to called with "zero" values, i.e.:

    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(NULL, NULL);

or

    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(0, NULL);

This is suitable for provider use, as the key functionality is tied
with its keys, and the operation time is determined by the init
functions the EVP_PKEY_CTX is used with.

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

crypto/evp/pmeth_lib.c

index 169b0565a4d15db14f05bcd2f2b072d216340e84..cc26f06d9b5b9a420cf02f17c4ca68e028b3fce3 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
@@ -106,8 +107,17 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
 static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
 {
     EVP_PKEY_CTX *ret;
-    const EVP_PKEY_METHOD *pmeth;
+    const EVP_PKEY_METHOD *pmeth = NULL;
+
+    /*
+     * When using providers, the context is bound to the algo implementation
+     * later.
+     */
+    if (pkey == NULL && e == NULL && id == -1)
+        goto common;
 
+    /* TODO(3.0) Legacy code should be removed when all is provider based */
+    /* BEGIN legacy */
     if (id == -1) {
         if (pkey == NULL)
             return 0;
@@ -143,7 +153,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
         EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
         return NULL;
     }
+    /* END legacy */
 
+ common:
     ret = OPENSSL_zalloc(sizeof(*ret));
     if (ret == NULL) {
 #ifndef OPENSSL_NO_ENGINE
@@ -159,7 +171,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
     if (pkey != NULL)
         EVP_PKEY_up_ref(pkey);
 
-    if (pmeth->init) {
+    if (pmeth != NULL && pmeth->init) {
         if (pmeth->init(ret) <= 0) {
             ret->pmeth = NULL;
             EVP_PKEY_CTX_free(ret);