Redesign the KEYMGMT libcrypto <-> provider interface - the basics
authorRichard Levitte <levitte@openssl.org>
Sun, 2 Feb 2020 17:56:07 +0000 (18:56 +0100)
committerRichard Levitte <levitte@openssl.org>
Fri, 7 Feb 2020 08:37:56 +0000 (09:37 +0100)
The KEYMGMT libcrypto <-> provider interface currently makes a few
assumptions:

1.  provider side domain parameters and key data isn't mutable. In
    other words, as soon as a key has been created in any (loaded,
    imported data, ...), it's set in stone.
2.  provider side domain parameters can be strictly separated from the
    key data.

This does work for the most part, but there are places where that's a
bit too rigid for the functionality that the EVP_PKEY API delivers.
Key data needs to be mutable to allow the flexibility that functions
like EVP_PKEY_copy_parameters promise, as well as to provide the
combinations of data that an EVP_PKEY is generally assumed to be able
to hold:

- domain parameters only
- public key only
- public key + private key
- domain parameters + public key
- domain parameters + public key + private key

To remedy all this, we:

1.  let go of the distinction between domain parameters and key
    material proper in the libcrypto <-> provider interface.

    As a consequence, functions that still need it gain a selection
    argument, which is a set of bits that indicate what parts of the
    key object are to be considered in a specific call.  This allows
    a reduction of very similar functions into one.

2.  Rework the libcrypto <-> provider interface so provider side key
    objects are created and destructed with a separate function, and
    get their data filled and extracted in through import and export.

(future work will see other key object constructors and other
functions to fill them with data)

Fixes #10979

squash! Redesign the KEYMGMT libcrypto <-> provider interface - the basics

Remedy 1 needs a rewrite:

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11006)

32 files changed:
crypto/dh/dh_ameth.c
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_lib.c
crypto/evp/evp_local.h
crypto/evp/exchange.c
crypto/evp/keymgmt_lib.c
crypto/evp/keymgmt_meth.c
crypto/evp/m_sigver.c
crypto/evp/p_lib.c
crypto/evp/pmeth_check.c
crypto/evp/pmeth_fn.c
crypto/evp/pmeth_gn.c
crypto/evp/signature.c
crypto/rsa/rsa_ameth.c
crypto/serializer/serializer_local.h
crypto/serializer/serializer_pkey.c
doc/internal/man3/evp_keymgmt_export_to_provider.pod [deleted file]
doc/internal/man3/evp_keymgmt_freekey.pod [deleted file]
doc/internal/man3/evp_keymgmt_newdata.pod [new file with mode: 0644]
doc/internal/man3/evp_keymgmt_util_export_to_provider.pod [new file with mode: 0644]
doc/internal/man3/evp_pkey_make_provided.pod
doc/man3/EVP_PKEY_check.pod
doc/man3/EVP_PKEY_fromdata.pod
doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod
doc/man3/d2i_PrivateKey.pod
doc/man7/provider-keymgmt.pod
doc/man7/provider-serializer.pod
include/crypto/asn1.h
include/crypto/evp.h
include/internal/property.h
include/openssl/core_numbers.h
include/openssl/serializer.h

index fd24183..4f74ab6 100644 (file)
@@ -482,51 +482,47 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
     return pkey->pkey.dh->dirty_cnt;
 }
 
-static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
-                               int want_domainparams)
+static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
+                             EVP_KEYMGMT *to_keymgmt)
 {
-    DH *dh = pk->pkey.dh;
+    DH *dh = from->pkey.dh;
     OSSL_PARAM_BLD tmpl;
     const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
     const BIGNUM *pub_key = DH_get0_pub_key(dh);
     const BIGNUM *priv_key = DH_get0_priv_key(dh);
     OSSL_PARAM *params;
-    void *provdata = NULL;
+    int rv;
 
     if (p == NULL || g == NULL)
-        return NULL;
+        return 0;
 
     ossl_param_bld_init(&tmpl);
     if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
         || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
-        return NULL;
+        return 0;
     if (q != NULL) {
         if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
-            return NULL;
+            return 0;
     }
-
-    if (!want_domainparams) {
-        /* A key must at least have a public part. */
-        if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY,
-                                    pub_key))
-            return NULL;
-
-        if (priv_key != NULL) {
-            if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY,
-                                        priv_key))
-                return NULL;
-        }
+    /* A key must at least have a public part. */
+    if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key))
+        return 0;
+    if (priv_key != NULL) {
+        if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY,
+                                    priv_key))
+            return 0;
     }
 
-    params = ossl_param_bld_to_param(&tmpl);
+    if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
+        return 0;
 
     /* We export, the provider imports */
-    provdata = want_domainparams
-        ? evp_keymgmt_importdomparams(keymgmt, params)
-        : evp_keymgmt_importkey(keymgmt, params);
+    rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
+                            params);
 
     ossl_param_bld_free(params);
-    return provdata;
+
+    return rv;
 }
 
 const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
index 510b204..9d1b897 100644 (file)
@@ -511,48 +511,44 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
     return pkey->pkey.dsa->dirty_cnt;
 }
 
-static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
-                                int want_domainparams)
+static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
+                              EVP_KEYMGMT *to_keymgmt)
 {
-    DSA *dsa = pk->pkey.dsa;
+    DSA *dsa = from->pkey.dsa;
     OSSL_PARAM_BLD tmpl;
     const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
     const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
     const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
     OSSL_PARAM *params;
-    void *provdata = NULL;
+    int rv;
 
     if (p == NULL || q == NULL || g == NULL)
-        return NULL;
+        return 0;
 
     ossl_param_bld_init(&tmpl);
     if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
         || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
         || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
-        return NULL;
-
-    if (!want_domainparams) {
-        /* A key must at least have a public part. */
-        if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
-                                    pub_key))
-            return NULL;
-
-        if (priv_key != NULL) {
-            if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY,
-                                        priv_key))
-                return NULL;
-        }
+        return 0;
+    if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
+                                pub_key))
+        return 0;
+    if (priv_key != NULL) {
+        if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY,
+                                    priv_key))
+            return 0;
     }
 
-    params = ossl_param_bld_to_param(&tmpl);
+    if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
+        return 0;
 
     /* We export, the provider imports */
-    provdata = want_domainparams
-        ? evp_keymgmt_importdomparams(keymgmt, params)
-        : evp_keymgmt_importkey(keymgmt, params);
+    rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
+                            params);
 
     ossl_param_bld_free(params);
-    return provdata;
+
+    return rv;
 }
 
 /* NB these are sorted in pkey_id order, lowest first */
index 469746e..334ee74 100644 (file)
@@ -75,31 +75,6 @@ DH *DSA_dup_DH(const DSA *r)
 }
 # endif /*  OPENSSL_NO_DH */
 
-const BIGNUM *DSA_get0_p(const DSA *d)
-{
-    return d->params.p;
-}
-
-const BIGNUM *DSA_get0_q(const DSA *d)
-{
-    return d->params.q;
-}
-
-const BIGNUM *DSA_get0_g(const DSA *d)
-{
-    return d->params.g;
-}
-
-const BIGNUM *DSA_get0_pub_key(const DSA *d)
-{
-    return d->pub_key;
-}
-
-const BIGNUM *DSA_get0_priv_key(const DSA *d)
-{
-    return d->priv_key;
-}
-
 void DSA_clear_flags(DSA *d, int flags)
 {
     d->flags &= ~flags;
@@ -278,6 +253,31 @@ int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
     return 1;
 }
 
+const BIGNUM *DSA_get0_p(const DSA *d)
+{
+    return d->params.p;
+}
+
+const BIGNUM *DSA_get0_q(const DSA *d)
+{
+    return d->params.q;
+}
+
+const BIGNUM *DSA_get0_g(const DSA *d)
+{
+    return d->params.g;
+}
+
+const BIGNUM *DSA_get0_pub_key(const DSA *d)
+{
+    return d->pub_key;
+}
+
+const BIGNUM *DSA_get0_priv_key(const DSA *d)
+{
+    return d->priv_key;
+}
+
 void DSA_get0_key(const DSA *d,
                   const BIGNUM **pub_key, const BIGNUM **priv_key)
 {
index 5f34aae..95dd1c0 100644 (file)
@@ -73,39 +73,24 @@ struct evp_keymgmt_st {
     CRYPTO_REF_COUNT refcnt;
     CRYPTO_RWLOCK *lock;
 
-    /* Domain parameter routines */
-    OSSL_OP_keymgmt_importdomparams_fn *importdomparams;
-    OSSL_OP_keymgmt_gendomparams_fn *gendomparams;
-    OSSL_OP_keymgmt_freedomparams_fn *freedomparams;
-    OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams;
-    OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types;
-    OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
-    OSSL_OP_keymgmt_get_domparam_params_fn *get_domparam_params;
-    OSSL_OP_keymgmt_gettable_domparam_params_fn *gettable_domparam_params;
-    OSSL_OP_keymgmt_validate_domparams_fn *validatedomparams;
-
-    /* Key routines */
-    OSSL_OP_keymgmt_importkey_fn *importkey;
-    OSSL_OP_keymgmt_genkey_fn *genkey;
-    OSSL_OP_keymgmt_loadkey_fn *loadkey;
-    OSSL_OP_keymgmt_freekey_fn *freekey;
-    OSSL_OP_keymgmt_exportkey_fn *exportkey;
-    OSSL_OP_keymgmt_importkey_types_fn *importkey_types;
-    OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types;
-    OSSL_OP_keymgmt_get_key_params_fn *get_key_params;
-    OSSL_OP_keymgmt_gettable_key_params_fn *gettable_key_params;
+    /* Constructor(s), destructor, information */
+    OSSL_OP_keymgmt_new_fn *new;
+    OSSL_OP_keymgmt_free_fn *free;
+    OSSL_OP_keymgmt_get_params_fn *get_params;
+    OSSL_OP_keymgmt_gettable_params_fn *gettable_params;
 
+    /* Key object checking */
     OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
-    OSSL_OP_keymgmt_validate_public_fn *validatepublic;
-    OSSL_OP_keymgmt_validate_private_fn *validateprivate;
-    OSSL_OP_keymgmt_validate_pairwise_fn *validatepairwise;
+    OSSL_OP_keymgmt_has_fn *has;
+    OSSL_OP_keymgmt_validate_fn *validate;
+
+    /* Import and export routines */
+    OSSL_OP_keymgmt_import_fn *import;
+    OSSL_OP_keymgmt_import_types_fn *import_types;
+    OSSL_OP_keymgmt_export_fn *export;
+    OSSL_OP_keymgmt_export_types_fn *export_types;
 } /* EVP_KEYMGMT */ ;
 
-struct keymgmt_data_st {
-    OPENSSL_CTX *ctx;
-    const char *properties;
-};
-
 struct evp_keyexch_st {
     int name_id;
     OSSL_PROVIDER *prov;
@@ -286,5 +271,4 @@ void evp_names_do_all(OSSL_PROVIDER *prov, int number,
                       void *data);
 int evp_cipher_cache_constants(EVP_CIPHER *cipher);
 void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
-                             EVP_KEYMGMT **keymgmt, const char *propquery,
-                             int domainparams);
+                             EVP_KEYMGMT **keymgmt, const char *propquery);
index fa93679..14ed4db 100644 (file)
@@ -187,7 +187,7 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
     /* Ensure that the key is provided.  If not, go legacy */
     tmp_keymgmt = ctx->keymgmt;
     provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx,
-                                     &tmp_keymgmt, ctx->propquery, 0);
+                                     &tmp_keymgmt, ctx->propquery);
     if (provkey == NULL)
         goto legacy;
     if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
@@ -293,7 +293,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
         return -2;
     }
 
-    provkey = evp_keymgmt_util_export_to_provider(peer, ctx->keymgmt, 0);
+    provkey = evp_keymgmt_util_export_to_provider(peer, ctx->keymgmt);
     /* If export failed, legacy may be able to pick it up */
     if (provkey == NULL)
         goto legacy;
index a63e5cd..812bdcb 100644 (file)
 #include "evp_local.h"
 
 struct import_data_st {
-    void *provctx;
-    void *(*importfn)(const EVP_KEYMGMT *keymgmt, const OSSL_PARAM params[]);
+    EVP_KEYMGMT *keymgmt;
+    void *keydata;
 
-    /* Result */
-    void *provdata;
+    int selection;
 };
 
 static int try_import(const OSSL_PARAM params[], void *arg)
 {
     struct import_data_st *data = arg;
 
-    data->provdata = data->importfn(data->provctx, params);
-    return data->provdata != NULL;
+    return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
+                              params);
 }
 
-void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
-                                          int want_domainparams)
+void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
 {
-    void *provdata = NULL;
+    void *keydata = NULL;
     size_t i, j;
 
     /*
@@ -61,25 +59,28 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
     for (i = 0;
          i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
          i++) {
-        if (keymgmt == pk->pkeys[i].keymgmt
-            && want_domainparams == pk->pkeys[i].domainparams)
-            return pk->pkeys[i].provdata;
+        if (keymgmt == pk->pkeys[i].keymgmt)
+            return pk->pkeys[i].keydata;
     }
 
+    if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL)
+        return NULL;
+
     if (pk->pkey.ptr != NULL) {
         /* There is a legacy key, try to export that one to the provider */
 
-        /* If the legacy key doesn't have an export function, give up */
-        if (pk->ameth->export_to == NULL)
+        /*
+         * If the legacy key doesn't have an export function or the export
+         * function fails, give up
+         */
+        if (pk->ameth->export_to == NULL
+            || !pk->ameth->export_to(pk, keydata, keymgmt)) {
+            evp_keymgmt_freedata(keymgmt, keydata);
             return NULL;
+        }
 
-        /* Otherwise, simply use it. */
-        provdata = pk->ameth->export_to(pk, keymgmt, want_domainparams);
-
-        /* Synchronize the dirty count, but only if we exported successfully */
-        if (provdata != NULL)
-            pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
-
+        /* Synchronize the dirty count */
+        pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
     } else {
         /*
          * Here, there is no legacy key, so we look at the already cached
@@ -91,42 +92,33 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
         /* Setup for the export callback */
         struct import_data_st import_data;
 
-        import_data.importfn =
-            want_domainparams
-            ? evp_keymgmt_importdomparams
-            : evp_keymgmt_importkey;
-        import_data.provdata = NULL;
-
-        /*
-         * If the given keymgmt doesn't have an import function, give up
-         */
-        if (import_data.importfn == NULL)
-            return NULL;
+        import_data.keydata = keydata;
+        import_data.keymgmt = keymgmt;
+        import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
 
         for (j = 0; j < i && pk->pkeys[j].keymgmt != NULL; j++) {
-            int (*exportfn)(const EVP_KEYMGMT *keymgmt, void *provdata,
-                            OSSL_CALLBACK *cb, void *cbarg) =
-                want_domainparams
-                ? evp_keymgmt_exportdomparams
-                : evp_keymgmt_exportkey;
-
-            if (exportfn != NULL) {
-                import_data.provctx =
-                    ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
-
-                /*
-                 * The export function calls the callback (try_import), which
-                 * does the import for us.
-                 * Even though we got a success return, we double check that
-                 * we actually got something, just in case some implementation
-                 * forgets to check the return value.
-
-                 */
-                if (exportfn(pk->pkeys[j].keymgmt, pk->pkeys[j].provdata,
-                             &try_import, &import_data)
-                    && (provdata = import_data.provdata) != NULL)
-                    break;
-            }
+            EVP_KEYMGMT *exp_keymgmt = pk->pkeys[i].keymgmt;
+            void *exp_keydata = pk->pkeys[i].keydata;
+
+            /*
+             * TODO(3.0) consider an evp_keymgmt_export() return value that
+             * indicates that the method is unsupported.
+             */
+            if (exp_keymgmt->export == NULL)
+                continue;
+
+            /*
+             * The export function calls the callback (try_import), which
+             * does the import for us.  If successful, we're done.
+             */
+            if (evp_keymgmt_export(exp_keymgmt, exp_keydata,
+                                   OSSL_KEYMGMT_SELECT_ALL,
+                                   &try_import, &import_data))
+                break;
+
+            /* If there was an error, bail out */
+            evp_keymgmt_freedata(keymgmt, keydata);
+            return NULL;
         }
     }
 
@@ -138,9 +130,9 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
     if (!ossl_assert(i < OSSL_NELEM(pk->pkeys)))
         return NULL;
 
-    evp_keymgmt_util_cache_pkey(pk, i, keymgmt, provdata, want_domainparams);
+    evp_keymgmt_util_cache_pkey(pk, i, keymgmt, keydata);
 
-    return provdata;
+    return keydata;
 }
 
 void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk)
@@ -152,14 +144,11 @@ void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk)
              i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
              i++) {
             EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt;
-            void *provdata = pk->pkeys[i].provdata;
+            void *keydata = pk->pkeys[i].keydata;
 
             pk->pkeys[i].keymgmt = NULL;
-            pk->pkeys[i].provdata = NULL;
-            if (pk->pkeys[i].domainparams)
-                evp_keymgmt_freedomparams(keymgmt, provdata);
-            else
-                evp_keymgmt_freekey(keymgmt, provdata);
+            pk->pkeys[i].keydata = NULL;
+            evp_keymgmt_freedata(keymgmt, keydata);
             EVP_KEYMGMT_free(keymgmt);
         }
 
@@ -170,23 +159,20 @@ void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk)
 }
 
 void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index,
-                                 EVP_KEYMGMT *keymgmt, void *provdata,
-                                 int domainparams)
+                                 EVP_KEYMGMT *keymgmt, void *keydata)
 {
-    if (provdata != NULL) {
+    if (keydata != NULL) {
         EVP_KEYMGMT_up_ref(keymgmt);
+        pk->pkeys[index].keydata = keydata;
         pk->pkeys[index].keymgmt = keymgmt;
-        pk->pkeys[index].provdata = provdata;
-        pk->pkeys[index].domainparams = domainparams;
 
         /*
-         * Cache information about the domain parameters or key.  Only needed
-         * for the "original" provider side key.
+         * Cache information about the key object.  Only needed for the
+         * "original" provider side key.
          *
          * This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
          */
         if (index == 0) {
-            int ok;
             int bits = 0;
             int security_bits = 0;
             int size = 0;
@@ -198,10 +184,7 @@ void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index,
             params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE,
                                                  &size);
             params[3] = OSSL_PARAM_construct_end();
-            ok = domainparams
-                ? evp_keymgmt_get_domparam_params(keymgmt, provdata, params)
-                : evp_keymgmt_get_key_params(keymgmt, provdata, params);
-            if (ok) {
+            if (evp_keymgmt_get_params(keymgmt, keydata, params)) {
                 pk->cache.size = size;
                 pk->cache.bits = bits;
                 pk->cache.security_bits = security_bits;
@@ -211,14 +194,20 @@ void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index,
 }
 
 void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
-                           const OSSL_PARAM params[], int domainparams)
+                                int selection, const OSSL_PARAM params[])
 {
-    void *provdata = domainparams
-        ? evp_keymgmt_importdomparams(keymgmt, params)
-        : evp_keymgmt_importkey(keymgmt, params);
+    void *keydata = evp_keymgmt_newdata(keymgmt);
 
-    evp_keymgmt_util_clear_pkey_cache(target);
-    evp_keymgmt_util_cache_pkey(target, 0, keymgmt, provdata, domainparams);
+    if (keydata != NULL) {
+        if (!evp_keymgmt_import(keymgmt, keydata, selection, params)) {
+            evp_keymgmt_freedata(keymgmt, keydata);
+            return NULL;
+        }
+
+
+        evp_keymgmt_util_clear_pkey_cache(target);
+        evp_keymgmt_util_cache_pkey(target, 0, keymgmt, keydata);
+    }
 
-    return provdata;
+    return keydata;
 }
index ca5c9e8..bb05914 100644 (file)
@@ -47,154 +47,71 @@ static void *keymgmt_from_dispatch(int name_id,
 
     for (; fns->function_id != 0; fns++) {
         switch (fns->function_id) {
-        case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS:
-            if (keymgmt->importdomparams != NULL)
-                break;
-            keymgmt->importdomparams =
-                OSSL_get_OP_keymgmt_importdomparams(fns);
+        case OSSL_FUNC_KEYMGMT_NEW:
+            if (keymgmt->new == NULL)
+                keymgmt->new = OSSL_get_OP_keymgmt_new(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_GENDOMPARAMS:
-            if (keymgmt->gendomparams != NULL)
-                break;
-            keymgmt->gendomparams = OSSL_get_OP_keymgmt_gendomparams(fns);
+        case OSSL_FUNC_KEYMGMT_FREE:
+            if (keymgmt->free == NULL)
+                keymgmt->free = OSSL_get_OP_keymgmt_free(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS:
-            if (keymgmt->freedomparams != NULL)
-                break;
-            keymgmt->freedomparams = OSSL_get_OP_keymgmt_freedomparams(fns);
+        case OSSL_FUNC_KEYMGMT_GET_PARAMS:
+            if (keymgmt->get_params == NULL)
+                keymgmt->get_params = OSSL_get_OP_keymgmt_get_params(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS:
-            if (keymgmt->exportdomparams != NULL)
-                break;
-            keymgmt->exportdomparams =
-                OSSL_get_OP_keymgmt_exportdomparams(fns);
+        case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS:
+            if (keymgmt->gettable_params == NULL)
+                keymgmt->gettable_params =
+                    OSSL_get_OP_keymgmt_gettable_params(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES:
-            if (keymgmt->importdomparam_types != NULL)
-                break;
-            keymgmt->importdomparam_types =
-                OSSL_get_OP_keymgmt_importdomparam_types(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES:
-            if (keymgmt->exportdomparam_types != NULL)
-                break;
-            keymgmt->exportdomparam_types =
-                OSSL_get_OP_keymgmt_exportdomparam_types(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS:
-            if (keymgmt->get_domparam_params == NULL)
-                keymgmt->get_domparam_params =
-                    OSSL_get_OP_keymgmt_get_domparam_params(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS:
-            if (keymgmt->gettable_domparam_params == NULL)
-                keymgmt->gettable_domparam_params =
-                    OSSL_get_OP_keymgmt_gettable_domparam_params(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_IMPORTKEY:
-            if (keymgmt->importkey != NULL)
-                break;
-            keymgmt->importkey = OSSL_get_OP_keymgmt_importkey(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_GENKEY:
-            if (keymgmt->genkey != NULL)
-                break;
-            keymgmt->genkey = OSSL_get_OP_keymgmt_genkey(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_LOADKEY:
-            if (keymgmt->loadkey != NULL)
-                break;
-            keymgmt->loadkey = OSSL_get_OP_keymgmt_loadkey(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_FREEKEY:
-            if (keymgmt->freekey != NULL)
-                break;
-            keymgmt->freekey = OSSL_get_OP_keymgmt_freekey(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_EXPORTKEY:
-            if (keymgmt->exportkey != NULL)
-                break;
-            keymgmt->exportkey = OSSL_get_OP_keymgmt_exportkey(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES:
-            if (keymgmt->importkey_types != NULL)
-                break;
-            keymgmt->importkey_types =
-                OSSL_get_OP_keymgmt_importkey_types(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES:
-            if (keymgmt->exportkey_types != NULL)
-                break;
-            keymgmt->exportkey_types =
-                OSSL_get_OP_keymgmt_exportkey_types(fns);
-            break;
-        case OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS:
-            if (keymgmt->get_key_params == NULL)
-                keymgmt->get_key_params =
-                    OSSL_get_OP_keymgmt_get_key_params(fns);
+        case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
+            if (keymgmt->query_operation_name == NULL)
+                keymgmt->query_operation_name =
+                    OSSL_get_OP_keymgmt_query_operation_name(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS:
-            if (keymgmt->gettable_key_params == NULL)
-                keymgmt->gettable_key_params =
-                    OSSL_get_OP_keymgmt_gettable_key_params(fns);
+        case OSSL_FUNC_KEYMGMT_HAS:
+            if (keymgmt->has == NULL)
+                keymgmt->has = OSSL_get_OP_keymgmt_has(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
-            if (keymgmt->query_operation_name != NULL)
-                break;
-            keymgmt->query_operation_name =
-                OSSL_get_OP_keymgmt_query_operation_name(fns);
+        case OSSL_FUNC_KEYMGMT_VALIDATE:
+            if (keymgmt->validate == NULL)
+                keymgmt->validate = OSSL_get_OP_keymgmt_validate(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_VALIDATE_DOMPARAMS:
-            if (keymgmt->validatedomparams != NULL)
-                break;
-            keymgmt->validatedomparams =
-                OSSL_get_OP_keymgmt_validate_domparams(fns);
+        case OSSL_FUNC_KEYMGMT_IMPORT:
+            if (keymgmt->import == NULL)
+                keymgmt->import = OSSL_get_OP_keymgmt_import(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_VALIDATE_PUBLIC:
-            if (keymgmt->validatepublic != NULL)
-                break;
-            keymgmt->validatepublic =
-                OSSL_get_OP_keymgmt_validate_public(fns);
+        case OSSL_FUNC_KEYMGMT_IMPORT_TYPES:
+            if (keymgmt->import_types == NULL)
+                keymgmt->import_types = OSSL_get_OP_keymgmt_import_types(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_VALIDATE_PRIVATE:
-            if (keymgmt->validateprivate != NULL)
-                break;
-            keymgmt->validateprivate =
-                OSSL_get_OP_keymgmt_validate_private(fns);
+        case OSSL_FUNC_KEYMGMT_EXPORT:
+            if (keymgmt->export == NULL)
+                keymgmt->export = OSSL_get_OP_keymgmt_export(fns);
             break;
-        case OSSL_FUNC_KEYMGMT_VALIDATE_PAIRWISE:
-            if (keymgmt->validatepairwise != NULL)
-                break;
-            keymgmt->validatepairwise =
-                OSSL_get_OP_keymgmt_validate_pairwise(fns);
+        case OSSL_FUNC_KEYMGMT_EXPORT_TYPES:
+            if (keymgmt->export_types == NULL)
+                keymgmt->export_types = OSSL_get_OP_keymgmt_export_types(fns);
             break;
         }
     }
     /*
      * Try to check that the method is sensible.
+     * At least one constructor and the destructor are MANDATORY
+     * The functions 'has' is MANDATORY
      * It makes no sense being able to free stuff if you can't create it.
      * It makes no sense providing OSSL_PARAM descriptors for import and
      * export if you can't import or export.
      */
-    if ((keymgmt->freedomparams != NULL
-         && (keymgmt->importdomparams == NULL
-             && keymgmt->gendomparams == NULL))
-        || (keymgmt->freekey != NULL
-            && (keymgmt->importkey == NULL
-                && keymgmt->genkey == NULL
-                && keymgmt->loadkey == NULL))
-        || (keymgmt->importdomparam_types != NULL
-            && keymgmt->importdomparams == NULL)
-        || (keymgmt->exportdomparam_types != NULL
-            && keymgmt->exportdomparams == NULL)
-        || (keymgmt->gettable_domparam_params != NULL
-            && keymgmt->get_domparam_params == NULL)
-        || (keymgmt->importkey_types != NULL
-            && keymgmt->importkey == NULL)
-        || (keymgmt->exportkey_types != NULL
-            && keymgmt->exportkey == NULL)
-        || (keymgmt->gettable_key_params != NULL
-            && keymgmt->get_key_params == NULL)) {
+    if (keymgmt->free == NULL
+        || keymgmt->new == NULL
+        || keymgmt->has == NULL
+        || (keymgmt->gettable_params != NULL
+            && keymgmt->get_params == NULL)
+        || (keymgmt->import_types != NULL
+            && keymgmt->import == NULL)
+        || (keymgmt->export_types != NULL
+            && keymgmt->export == NULL)) {
         EVP_KEYMGMT_free(keymgmt);
         EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
         return NULL;
@@ -284,149 +201,84 @@ void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
 /*
  * Internal API that interfaces with the method function pointers
  */
-void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt,
-                                  const OSSL_PARAM params[])
+void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt)
 {
     void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
 
-    return keymgmt->importdomparams(provctx, params);
-}
-
-void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt,
-                               const OSSL_PARAM params[])
-{
-    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
-
-    return keymgmt->gendomparams(provctx, params);
-}
-
-void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt,
-                               void *provdomparams)
-{
-    keymgmt->freedomparams(provdomparams);
-}
-
-int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt,
-                                void *provdomparams,
-                                OSSL_CALLBACK *param_cb, void *cbarg)
-{
-    return keymgmt->exportdomparams(provdomparams, param_cb, cbarg);
-}
-
-const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt)
-{
-    return keymgmt->importdomparam_types();
+    /*
+     * TODO(3.0) 'new' is currently mandatory on its own, but when new
+     * constructors appear, it won't be quite as mandatory, so we have
+     * a check for future cases.
+     */
+    if (keymgmt->new == NULL)
+        return NULL;
+    return keymgmt->new(provctx);
 }
 
-/*
- * TODO(v3.0) investigate if we need this function.  'openssl provider' may
- * be a caller...
- */
-const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt)
+void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata)
 {
-    return keymgmt->exportdomparam_types();
+    /* This is mandatory, no need to check for its presence */
+    keymgmt->free(keydata);
 }
 
-int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt,
-                                     void *provdomparams, OSSL_PARAM params[])
+int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata,
+                           OSSL_PARAM params[])
 {
-    if (keymgmt->get_domparam_params == NULL)
+    if (keymgmt->get_params == NULL)
         return 1;
-    return keymgmt->get_domparam_params(provdomparams, params);
+    return keymgmt->get_params(keydata, params);
 }
 
-const OSSL_PARAM *
-evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt)
+const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt)
 {
-    if (keymgmt->gettable_domparam_params == NULL)
+    if (keymgmt->gettable_params == NULL)
         return NULL;
-    return keymgmt->gettable_domparam_params();
-}
-
-
-void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
-                            const OSSL_PARAM params[])
-{
-    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
-
-    return keymgmt->importkey(provctx, params);
+    return keymgmt->gettable_params();
 }
 
-void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams,
-                         const OSSL_PARAM params[])
+int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection)
 {
-    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
-
-    return keymgmt->genkey(provctx, domparams, params);
+    /* This is mandatory, no need to check for its presence */
+    return keymgmt->has(keydata, selection);
 }
 
-void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt,
-                          void *id, size_t idlen)
+int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
+                         int selection)
 {
-    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
-
-    return keymgmt->loadkey(provctx, id, idlen);
-}
-
-void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey)
-{
-    keymgmt->freekey(provkey);
-}
-
-int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey,
-                          OSSL_CALLBACK *param_cb, void *cbarg)
-{
-    return keymgmt->exportkey(provkey, param_cb, cbarg);
-}
-
-const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt)
-{
-    return keymgmt->importkey_types();
-}
-
-/*
- * TODO(v3.0) investigate if we need this function.  'openssl provider' may
- * be a caller...
- */
-const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt)
-{
-    return keymgmt->exportkey_types();
-}
-
-int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt,
-                               void *provkey, OSSL_PARAM params[])
-{
-    if (keymgmt->get_key_params == NULL)
+    /* We assume valid if the implementation doesn't have a function */
+    if (keymgmt->validate == NULL)
         return 1;
-    return keymgmt->get_key_params(provkey, params);
-}
-
-const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt)
-{
-    if (keymgmt->gettable_key_params == NULL)
-        return NULL;
-    return keymgmt->gettable_key_params();
+    return keymgmt->validate(keydata, selection);
 }
 
-int evp_keymgmt_validate_domparams(const EVP_KEYMGMT *keymgmt, void *provkey)
+int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
+                       int selection, const OSSL_PARAM params[])
 {
-    /* if domainparams are not supported - then pass */
-    if (keymgmt->validatedomparams == NULL)
-        return 1;
-    return keymgmt->validatedomparams(provkey);
+    if (keymgmt->import == NULL)
+        return 0;
+    return keymgmt->import(keydata, selection, params);
 }
 
-int evp_keymgmt_validate_public(const EVP_KEYMGMT *keymgmt, void *provkey)
+const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
+                                           int selection)
 {
-    return keymgmt->validatepublic(provkey);
+    if (keymgmt->import_types == NULL)
+        return NULL;
+    return keymgmt->import_types(selection);
 }
 
-int evp_keymgmt_validate_private(const EVP_KEYMGMT *keymgmt, void *provkey)
+int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
+                       int selection, OSSL_CALLBACK *param_cb, void *cbarg)
 {
-    return keymgmt->validateprivate(provkey);
+    if (keymgmt->export == NULL)
+        return 0;
+    return keymgmt->export(keydata, selection, param_cb, cbarg);
 }
 
-int evp_keymgmt_validate_pairwise(const EVP_KEYMGMT *keymgmt, void *provkey)
+const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
+                                           int selection)
 {
-    return keymgmt->validatepairwise(provkey);
+    if (keymgmt->export_types == NULL)
+        return NULL;
+    return keymgmt->export_types(selection);
 }
index 05dc46e..1ea5669 100644 (file)
@@ -67,7 +67,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
     /* Ensure that the key is provided.  If not, go legacy */
     tmp_keymgmt = locpctx->keymgmt;
     provkey = evp_pkey_make_provided(locpctx->pkey, locpctx->libctx,
-                                     &tmp_keymgmt, locpctx->propquery, 0);
+                                     &tmp_keymgmt, locpctx->propquery);
     if (provkey == NULL)
         goto legacy;
     if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
index 2c0ee83..95dd96e 100644 (file)
@@ -760,9 +760,9 @@ int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
                                              mdmandatory,
                                              sizeof(mdmandatory));
         params[2] = OSSL_PARAM_construct_end();
-        if (!evp_keymgmt_get_key_params(pkey->pkeys[0].keymgmt,
-                                        pkey->pkeys[0].provdata,
-                                        params))
+        if (!evp_keymgmt_get_params(pkey->pkeys[0].keymgmt,
+                                    pkey->pkeys[0].keydata,
+                                    params))
             return 0;
         if (mdmandatory[0] != '\0') {
             OPENSSL_strlcpy(mdname, mdmandatory, mdname_sz);
@@ -910,12 +910,11 @@ int EVP_PKEY_size(const EVP_PKEY *pkey)
 }
 
 void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
-                             EVP_KEYMGMT **keymgmt, const char *propquery,
-                             int domainparams)
+                             EVP_KEYMGMT **keymgmt, const char *propquery)
 {
     EVP_KEYMGMT *allocated_keymgmt = NULL;
     EVP_KEYMGMT *tmp_keymgmt = NULL;
-    void *provdata = NULL;
+    void *keydata = NULL;
 
     if (pk == NULL)
         return NULL;
@@ -935,20 +934,20 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
     }
 
     if (tmp_keymgmt != NULL)
-        provdata =
-            evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt, domainparams);
+        keydata =
+            evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
 
     /*
      * If nothing was exported, |tmp_keymgmt| might point at a freed
      * EVP_KEYMGMT, so we clear it to be safe.  It shouldn't be useful for
      * the caller either way in that case.
      */
-    if (provdata == NULL)
+    if (keydata == NULL)
         tmp_keymgmt = NULL;
 
     if (keymgmt != NULL)
         *keymgmt = tmp_keymgmt;
 
     EVP_KEYMGMT_free(allocated_keymgmt);
-    return provdata;
+    return keydata;
 }
index 19f200a..1186ad2 100644 (file)
@@ -29,10 +29,11 @@ int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
     }
 
     keymgmt = pkey->pkeys[0].keymgmt;
-    key = pkey->pkeys[0].provdata;
+    key = pkey->pkeys[0].keydata;
 
     if (key != NULL && keymgmt != NULL)
-        return evp_keymgmt_validate_public(keymgmt, key);
+        return evp_keymgmt_validate(keymgmt, key,
+                                    OSSL_KEYMGMT_SELECT_PUBLIC_KEY);
 
     /* legacy */
     /* call customized public key check function first */
@@ -61,10 +62,11 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
     }
 
     keymgmt = pkey->pkeys[0].keymgmt;
-    key = pkey->pkeys[0].provdata;
+    key = pkey->pkeys[0].keydata;
 
     if (key != NULL && keymgmt != NULL)
-        return evp_keymgmt_validate_domparams(keymgmt, key);
+        return evp_keymgmt_validate(keymgmt, key,
+                                    OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
 
     /* call customized param check function first */
     if (ctx->pmeth->param_check != NULL)
@@ -93,10 +95,11 @@ int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
     }
 
     keymgmt = pkey->pkeys[0].keymgmt;
-    key = pkey->pkeys[0].provdata;
+    key = pkey->pkeys[0].keydata;
 
     if (key != NULL && keymgmt != NULL)
-        return evp_keymgmt_validate_private(keymgmt, key);
+        return evp_keymgmt_validate(keymgmt, key,
+                                    OSSL_KEYMGMT_SELECT_PRIVATE_KEY);
     /* not supported for legacy keys */
     return -2;
 }
@@ -113,10 +116,10 @@ int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx)
     }
 
     keymgmt = pkey->pkeys[0].keymgmt;
-    key = pkey->pkeys[0].provdata;
+    key = pkey->pkeys[0].keydata;
 
     if (key != NULL && keymgmt != NULL)
-        return evp_keymgmt_validate_pairwise(keymgmt, key);
+        return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_KEYPAIR);
     /* not supported for legacy keys */
     return -2;
 }
@@ -133,14 +136,11 @@ int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
     }
 
     keymgmt = pkey->pkeys[0].keymgmt;
-    key = pkey->pkeys[0].provdata;
+    key = pkey->pkeys[0].keydata;
+
+    if (key != NULL && keymgmt != NULL)
+        return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_ALL);
 
-    if (key != NULL && keymgmt != NULL) {
-        return evp_keymgmt_validate_domparams(keymgmt, key)
-               && evp_keymgmt_validate_public(keymgmt, key)
-               && evp_keymgmt_validate_private(keymgmt, key)
-               && evp_keymgmt_validate_pairwise(keymgmt, key);
-    }
     /* legacy */
     /* call customized check function first */
     if (ctx->pmeth->check != NULL)
index 34cde67..0b5af8e 100644 (file)
@@ -44,7 +44,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation)
     /* Ensure that the key is provided.  If not, go legacy */
     tmp_keymgmt = ctx->keymgmt;
     provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx,
-                                     &tmp_keymgmt, ctx->propquery, 0);
+                                     &tmp_keymgmt, ctx->propquery);
     if (provkey == NULL)
         goto legacy;
     if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
index 904b36e..4bea1a1 100644 (file)
@@ -208,7 +208,8 @@ int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx)
 
 int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
 {
-    void *provdata = NULL;
+    void *keydata = NULL;
+    int selection;
 
     if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) {
         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
@@ -226,13 +227,16 @@ int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
         return -1;
     }
 
-    provdata =
-        evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, params,
-                                  ctx->operation == EVP_PKEY_OP_PARAMFROMDATA);
+    if (ctx->operation == EVP_PKEY_OP_PARAMFROMDATA)
+        selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
+    else
+        selection = OSSL_KEYMGMT_SELECT_KEYPAIR;
+    keydata = evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, selection,
+                                        params);
 
-    if (provdata == NULL)
+    if (keydata == NULL)
         return 0;
-    /* provdata is cached in *ppkey, so we need not bother with it further */
+    /* keydata is cached in *ppkey, so we need not bother with it further */
     return 1;
 }
 
@@ -247,7 +251,8 @@ const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx)
 {
     /* We call fromdata_init to get ctx->keymgmt populated */
     if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
-        return evp_keymgmt_importdomparam_types(ctx->keymgmt);
+        return evp_keymgmt_import_types(ctx->keymgmt,
+                                        OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
     return NULL;
 }
 
@@ -255,6 +260,7 @@ const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
 {
     /* We call fromdata_init to get ctx->keymgmt populated */
     if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
-        return evp_keymgmt_importdomparam_types(ctx->keymgmt);
+        return evp_keymgmt_import_types(ctx->keymgmt,
+                                        OSSL_KEYMGMT_SELECT_KEYPAIR);
     return NULL;
 }
index 7c6828b..ca9d91e 100644 (file)
@@ -345,7 +345,7 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation)
     /* Ensure that the key is provided.  If not, go legacy */
     tmp_keymgmt = ctx->keymgmt;
     provkey = evp_pkey_make_provided(ctx->pkey, ctx->libctx,
-                                     &tmp_keymgmt, ctx->propquery, 0);
+                                     &tmp_keymgmt, ctx->propquery);
     if (provkey == NULL)
         goto legacy;
     if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
index 485ac35..a94cb54 100644 (file)
@@ -1074,40 +1074,42 @@ static size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
 
 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
 
-static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
-                                int want_domainparams)
+static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
+                              EVP_KEYMGMT *to_keymgmt)
 {
-    RSA *rsa = pk->pkey.rsa;
+    RSA *rsa = from->pkey.rsa;
     OSSL_PARAM_BLD tmpl;
     const BIGNUM *n = RSA_get0_n(rsa), *e = RSA_get0_e(rsa);
     const BIGNUM *d = RSA_get0_d(rsa);
     STACK_OF(BIGNUM_const) *primes = NULL, *exps = NULL, *coeffs = NULL;
     int numprimes = 0, numexps = 0, numcoeffs = 0;
     OSSL_PARAM *params = NULL;
-    void *provkey = NULL;
+    int rv = 0;
 
-    /*
-     * There are no domain parameters for RSA keys, or rather, they are
-     * included in the key data itself.
-     */
-    if (want_domainparams)
+    /* Public parameters must always be present */
+    if (n == NULL || e == NULL)
         goto err;
 
-    /* Get all the primes and CRT params */
-    if ((primes = sk_BIGNUM_const_new_null()) == NULL
-        || (exps = sk_BIGNUM_const_new_null()) == NULL
-        || (coeffs = sk_BIGNUM_const_new_null()) == NULL)
-        goto err;
+    ossl_param_bld_init(&tmpl);
 
-    if (!rsa_get0_all_params(rsa, primes, exps, coeffs))
+    /* |e| and |n| are always present */
+    if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_E, e))
         goto err;
-
-    /* Public parameters must always be present */
-    if (n == NULL || e == NULL)
+    if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_N, n))
         goto err;
 
     if (d != NULL) {
-        /* It's a private key, so we should have everything else too */
+        int i;
+
+        /* Get all the primes and CRT params */
+        if ((primes = sk_BIGNUM_const_new_null()) == NULL
+            || (exps = sk_BIGNUM_const_new_null()) == NULL
+            || (coeffs = sk_BIGNUM_const_new_null()) == NULL)
+            goto err;
+
+        if (!rsa_get0_all_params(rsa, primes, exps, coeffs))
+            goto err;
+
         numprimes = sk_BIGNUM_const_num(primes);
         numexps = sk_BIGNUM_const_num(exps);
         numcoeffs = sk_BIGNUM_const_num(coeffs);
@@ -1120,15 +1122,6 @@ static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
                          + numprimes + numexps + numcoeffs
                          <= OSSL_PARAM_BLD_MAX))
             goto err;
-    }
-
-    ossl_param_bld_init(&tmpl);
-    if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_N, n)
-        || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_E, e))
-        goto err;
-
-    if (d != NULL) {
-        int i;
 
         if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_RSA_D, d))
             goto err;
@@ -1162,14 +1155,15 @@ static void *rsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
         goto err;
 
     /* We export, the provider imports */
-    provkey = evp_keymgmt_importkey(keymgmt, params);
+    rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
+                            params);
 
  err:
     sk_BIGNUM_const_free(primes);
     sk_BIGNUM_const_free(exps);
     sk_BIGNUM_const_free(coeffs);
     ossl_param_bld_free(params);
-    return provkey;
+    return rv;
 }
 
 const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = {
index 9ee0eb8..7a66472 100644 (file)
@@ -32,6 +32,8 @@ struct ossl_serializer_ctx_st {
     OSSL_SERIALIZER *ser;
     void *serctx;
 
+    int selection;
+
     /*
      * |object| is the libcrypto object to handle.
      * |do_output| must have intimate knowledge of this object.
index d3c3362..3b0cc3a 100644 (file)
@@ -96,13 +96,6 @@ struct selected_serializer_st {
     const OSSL_PROVIDER *desired_provider;
     const char *propquery;
 
-    /*
-     * When selecting serializers, we need to check the intended use.
-     * This is governed by the |domainparams| flag in the EVP_PKEY,
-     * we must just make sure to filter on 'type=domainparams' accordingly.
-     */
-    int want_domainparams;
-
     /*
      * Serializers offer two functions, one that handles object data in
      * the form of a OSSL_PARAM array, and one that directly handles a
@@ -122,36 +115,12 @@ static void select_serializer(const char *name, void *data)
 {
     struct selected_serializer_st *d = data;
     OSSL_SERIALIZER *s = NULL;
-    OSSL_PROPERTY_LIST *check =
-        d->want_domainparams
-        ? ossl_parse_query(d->libctx, "type=domainparams")
-        : NULL;
 
     /* No need to look further if we already have the more desirable option */
     if (d->desired != NULL)
         return;
 
     if ((s = OSSL_SERIALIZER_fetch(d->libctx, name, d->propquery)) != NULL) {
-        /*
-         * Extra check if domain parameters are explicitly specified:
-         * only accept serializers that have the "type=domainparams"
-         * property.
-         *
-         * For data that isn't marked as domain parameters, a domain
-         * parameters serializer is still acceptable, because a key
-         * may hold domain parameters too.
-         */
-        if (d->want_domainparams) {
-            OSSL_PROPERTY_LIST *current_props =
-                ossl_parse_property(d->libctx, OSSL_SERIALIZER_properties(s));
-            int check_cnt = ossl_property_match_count(check, current_props);
-
-            if (check_cnt == 0) {
-                OSSL_SERIALIZER_free(s);
-                return;
-            }
-        }
-
         if (d->first == NULL && s->serialize_data != NULL) {
             d->first = s;
         } else if (OSSL_SERIALIZER_provider(s) == d->desired_provider
@@ -298,8 +267,7 @@ static int serializer_write_cb(const OSSL_PARAM params[], void *arg)
 static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
 {
     const EVP_PKEY *pkey = ctx->object;
-    void *provdata = pkey->pkeys[0].provdata;
-    int domainparams = pkey->pkeys[0].domainparams;
+    void *keydata = pkey->pkeys[0].keydata;
     EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt;
 
     /*
@@ -319,15 +287,11 @@ static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
         write_data.ctx = ctx;
         write_data.out = out;
 
-        if (domainparams)
-            return evp_keymgmt_exportdomparams(keymgmt, provdata,
-                                               serializer_write_cb,
-                                               &write_data);
-        return evp_keymgmt_exportkey(keymgmt, provdata,
-                                     serializer_write_cb, &write_data);
+        return evp_keymgmt_export(keymgmt, keydata, ctx->selection,
+                                  &serializer_write_cb, &write_data);
     }
 
-    return ctx->ser->serialize_object(ctx->serctx, provdata, out,
+    return ctx->ser->serialize_object(ctx->serctx, keydata, out,
                                       serializer_passphrase_out_cb, ctx);
 }
 
@@ -343,6 +307,7 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
     OSSL_SERIALIZER_CTX *ctx = NULL;
     OSSL_SERIALIZER *ser = NULL;
     EVP_KEYMGMT *keymgmt = pkey->pkeys[0].keymgmt;
+    int selection = OSSL_KEYMGMT_SELECT_ALL;
 
     if (!ossl_assert(pkey != NULL && propquery != NULL)) {
         ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
@@ -353,12 +318,14 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
         const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt);
         OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov);
         struct selected_serializer_st sel_data;
+        OSSL_PROPERTY_LIST *check =
+            ossl_parse_query(libctx, "type=parameters");
+        OSSL_PROPERTY_LIST *current_props = NULL;
 
         memset(&sel_data, 0, sizeof(sel_data));
         sel_data.libctx = libctx;
         sel_data.desired_provider = desired_prov;
         sel_data.propquery = propquery;
-        sel_data.want_domainparams = pkey->pkeys[0].domainparams;
         EVP_KEYMGMT_names_do_all(keymgmt, select_serializer, &sel_data);
 
         if (sel_data.desired != NULL) {
@@ -370,6 +337,14 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
         }
         OSSL_SERIALIZER_free(sel_data.first);
         OSSL_SERIALIZER_free(sel_data.desired);
+
+        current_props =
+            ossl_parse_property(libctx, OSSL_SERIALIZER_properties(ser));
+        if (ossl_property_match_count(check, current_props) > 0)
+            selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
+
+        ossl_property_free(current_props);
+        ossl_property_free(check);
     }
 
     ctx = OSSL_SERIALIZER_CTX_new(ser); /* refcnt(ser)++ */
@@ -377,6 +352,7 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
 
     if (ctx != NULL) {
         /* Setup for OSSL_SERIALIZE_to_bio() */
+        ctx->selection = selection;
         ctx->object = pkey;
         ctx->do_output = serializer_EVP_PKEY_to_bio;
     }
diff --git a/doc/internal/man3/evp_keymgmt_export_to_provider.pod b/doc/internal/man3/evp_keymgmt_export_to_provider.pod
deleted file mode 100644 (file)
index 2cb4094..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-=pod
-
-=head1 NAME
-
-evp_keymgmt_export_to_provider,
-evp_keymgmt_clear_pkey_cache
-- key material provider export for EVP
-
-=head1 SYNOPSIS
-
- #include "crypto/evp.h"
-
- void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
- void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk);
-
-=head1 DESCRIPTION
-
-evp_keymgmt_export_to_provider() exports the key material from the
-given key I<pk> to a provider via a B<EVP_KEYMGMT> interface, if this
-hasn't already been done.
-It maintains a cache of provider key references in I<pk> to keep track
-of all such exports.
-
-If I<pk> has an assigned legacy key, a check is done to see if any of
-its key material has changed since last export, i.e. the legacy key's
-is_dirty() method returns 1.
-If it has, the cache of already exported keys is cleared, and a new
-export is made with the new key material.
-
-evp_keymgmt_clear_pkey_cache() can be used to explicitly clear the
-cache of provider key references.
-
-=head1 RETURN VALUES
-
-evp_keymgmt_export_to_provider() returns a pointer to the appropriate
-provider side key (created or found again), or NULL on error.
-
-=head1 NOTES
-
-"Legacy key" is the term used for any key that has been assigned to an
-B<EVP_PKEY> with EVP_PKEY_assign_RSA() and similar functions.
-
-=head1 SEE ALSO
-
-L<EVP_PKEY_ASN1_METHOD(3)>, L<EVP_PKEY_assign_RSA(3)>
-
-=head1 COPYRIGHT
-
-Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/internal/man3/evp_keymgmt_freekey.pod b/doc/internal/man3/evp_keymgmt_freekey.pod
deleted file mode 100644 (file)
index 8be73ae..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-=pod
-
-=head1 NAME
-
-evp_keymgmt_importdomparams, evp_keymgmt_gendomparams,
-evp_keymgmt_freedomparams,
-evp_keymgmt_exportdomparams,
-evp_keymgmt_importdomparams_types, evp_keymgmt_exportdomparams_types,
-evp_keymgmt_importkey, evp_keymgmt_genkey, evp_keymgmt_loadkey,
-evp_keymgmt_freekey,
-evp_keymgmt_exportkey,
-evp_keymgmt_importkey_types, evp_keymgmt_exportkey_types
-- internal KEYMGMT support functions
-
-=head1 SYNOPSIS
-
- #include "crypto/evp.h"
-
- void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt,
-                                const OSSL_PARAM params[]);
- void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt,
-                             const OSSL_PARAM params[]);
- void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt, void *provdomparams);
- int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt,
-                              void *provdomparams, OSSL_PARAM params[]);
- const OSSL_PARAM *evp_keymgmt_importdomparams_types(const EVP_KEYMGMT *keymgmt);
- const OSSL_PARAM *evp_keymgmt_exportdomparams_types(const EVP_KEYMGMT *keymgmt);
-
- void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
-                             const OSSL_PARAM params[]);
- void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams,
-                          const OSSL_PARAM params[]);
- void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt,
-                           void *id, size_t idlen);
- void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey);
- int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey,
-                           OSSL_PARAM params[]);
- const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt);
- const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt);
-
-=head1 DESCRIPTION
-
-All these functions are helpers to call the provider's corresponding
-function.
-
-evp_keymgmt_importdomparams() calls the method's importdomparams() function.
-
-evp_keymgmt_gendomparams() calls the method's gendomparams() function.
-
-evp_keymgmt_freedomparams() calls the method's freedomparams() function.
-
-evp_keymgmt_exportdomparams() calls the method's exportdomparams()
-function.
-
-evp_keymgmt_importdomparams_types() calls the method's
-importdomparams_types() function.
-
-evp_keymgmt_exportdomparams_types() calls the method's
-exportdomparams_types() function.
-
-evp_keymgmt_importkey() calls the method's importkey()
-function.
-
-evp_keymgmt_genkey() calls the method's genkey() function.
-
-evp_keymgmt_loadkey() calls the method's loadkey() function.
-
-evp_keymgmt_freekey() calls the method's freekey() function.
-
-evp_keymgmt_exportkey() calls the method's exportkey()
-function.
-
-evp_keymgmt_importkey_types() calls the method's importkey_types() function.
-
-evp_keymgmt_exportkey_types() calls the method's exportkey_types() function.
-
-=head1 RETURN VALUES
-
-evp_keymgmt_importdomparams(), evp_keymgmt_gendomparams() return a pointer
-to a provider owned set of domparams parameters, or NULL on error.
-
-evp_keymgmt_importkey(), evp_keymgmt_genkey(), evp_keymgmt_loadkey() return
-a pointer to a provider owned key, or NULL on error.
-
-evp_keymgmt_exportdomparams() and evp_keymgmt_exportkey() return 1 on success,
-or 0 on error.
-
-evp_keymgmt_importdomparams_types(), evp_keymgmt_exportdomparams_types()
-return parameter descriptor for importing and exporting domparams
-parameters, or NULL if there are no such descriptors.
-
-evp_keymgmt_importkey_types() and evp_keymgmt_exportkey_types()
-return parameter descriptor for importing and exporting keys, or NULL
-if there are no such descriptors.
-
-=head1 HISTORY
-
-The functions described here were all added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/internal/man3/evp_keymgmt_newdata.pod b/doc/internal/man3/evp_keymgmt_newdata.pod
new file mode 100644 (file)
index 0000000..861f57f
--- /dev/null
@@ -0,0 +1,93 @@
+=pod
+
+=head1 NAME
+
+evp_keymgmt_newdata, evp_keymgmt_freedata,
+evp_keymgmt_get_params, evp_keymgmt_gettable_params,
+evp_keymgmt_has, evp_keymgmt_validate,
+evp_keymgmt_import, evp_keymgmt_import_types,
+evp_keymgmt_export, evp_keymgmt_export_types
+- internal KEYMGMT interface functions
+
+=head1 SYNOPSIS
+
+ #include "crypto/evp.h"
+
+ void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt);
+ void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata);
+ int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt,
+                            void *keydata, OSSL_PARAM params[]);
+ const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt);
+ int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
+ int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
+                          int selection);
+ int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
+                        int selection, const OSSL_PARAM params[]);
+ const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
+                                            int selection);
+ int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
+                        int selection, OSSL_CALLBACK *param_cb, void *cbarg);
+ const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
+                                            int selection);
+
+=head1 DESCRIPTION
+
+All these functions are helpers to call the provider's corresponding
+function.  They all have in common that they take a B<EVP_KEYMGMT> as
+first argument, which they also retrieve a provider context from when
+needed.  The rest of the arguments are simply passed on to the
+function they wrap around.
+
+evp_keymgmt_newdata() calls the method's new() function.
+
+evp_keymgmt_freedata() calls the method's free() function.
+
+(the name evp_keymgmt_freedata() was chosen to avoid a clash with
+EVP_KEYMGMT_free() on case insensitive systems, the name
+evp_keymgmt_newdata() was chosen for consistency)
+
+evp_keymgmt_get_params() calls the method's get_params() function.
+
+evp_keymgmt_gettable_params() calls the method's gettable_params()
+function.
+
+evp_keymgmt_has() calls the method's has() function.
+
+evp_keymgmt_validate() calls the method's validate() function.
+
+evp_keymgmt_import() calls the method's import() function.
+
+evp_keymgmt_import_types() calls the method's import_types() function.
+
+evp_keymgmt_export() calls the method's export() function.
+
+evp_keymgmt_export_types() calls the method's export_types() function.
+
+=head1 RETURN VALUES
+
+evp_keymgmt_newdata() returns a pointer to a provider side key object,
+or NULL on error.
+
+evp_keymgmt_gettable_params(), evp_keymgmt_import_types(), and
+evp_keymgmt_export_types() return parameter descriptor for importing
+and exporting key data, or NULL if there are no such descriptors.
+
+All other functions return 1 on success and 0 on error.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod b/doc/internal/man3/evp_keymgmt_util_export_to_provider.pod
new file mode 100644 (file)
index 0000000..38e7133
--- /dev/null
@@ -0,0 +1,71 @@
+=pod
+
+=head1 NAME
+
+evp_keymgmt_util_export_to_provider,
+evp_keymgmt_util_clear_pkey_cache,
+evp_keymgmt_util_cache_pkey,
+evp_keymgmt_util_fromdata
+- internal KEYMGMT utility functions
+
+=head1 SYNOPSIS
+
+ #include "crypto/evp.h"
+
+ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
+ void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk);
+ void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index,
+                                  EVP_KEYMGMT *keymgmt, void *keydata);
+ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
+                                 int selection, const OSSL_PARAM params[]);
+
+=head1 DESCRIPTION
+
+evp_keymgmt_util_export_to_provider() exports the key material from
+the given key I<pk> to a provider via a B<EVP_KEYMGMT> interface, if
+this hasn't already been done.
+It maintains a cache of provider key references in I<pk> to keep track
+of all such exports.
+
+If I<pk> has an assigned legacy key, a check is done to see if any of
+its key material has changed since last export, i.e. the legacy key's
+is_dirty() method returns 1.
+If it has, the cache of already exported keys is cleared, and a new
+export is made with the new key material.
+
+evp_keymgmt_util_clear_pkey_cache() can be used to explicitly clear
+the cache of provider key references.
+
+evp_keymgmt_util_cache_pkey() can be used to assign a provider key
+object to a specific cache slot in the given I<target>.
+I<Use with extreme care>.
+
+evp_keymgmt_util_fromdata() can be used to add key object data to a
+given key I<target> via a B<EVP_KEYMGMT> interface.  This is used as a
+helper for L<EVP_PKEY_fromdata(3)>.
+
+=head1 RETURN VALUES
+
+evp_keymgmt_export_to_provider() and evp_keymgmt_util_fromdata()
+return a pointer to the appropriate provider side key (created or
+found again), or NULL on error.
+
+=head1 NOTES
+
+"Legacy key" is the term used for any key that has been assigned to an
+B<EVP_PKEY> with EVP_PKEY_assign_RSA() and similar functions.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_ASN1_METHOD(3)>, L<EVP_PKEY_assign_RSA(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index e5dde78..12cbe0c 100644 (file)
@@ -10,8 +10,7 @@ evp_pkey_make_provided - internal EVP_PKEY support functions for providers
  #include "evp_local.h"
 
  void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
-                              EVP_KEYMGMT **keymgmt, const char *propquery,
-                              int domainparams);
+                              EVP_KEYMGMT **keymgmt, const char *propquery);
 
 =head1 DESCRIPTION
 
@@ -24,8 +23,6 @@ used for exporting.  If not (I<*keymgmt> is NULL), then this function will
 fetch an B<EVP_KEYMGMT> implicitly, using I<propquery> as property query string.
 As output from this function, I<*keymgmt> will be assigned the B<EVP_KEYMGMT>
 that was used, if the export was successful, otherwise it will be assigned NULL.
-I<domainparams> decides if I<pk> should be considered domain parameters or the
-actual key.
 
 =head1 RETURN VALUES
 
index 95b57a3..2398b61 100644 (file)
@@ -18,7 +18,7 @@ EVP_PKEY_private_check, EVP_PKEY_pairwise_check
 
 =head1 DESCRIPTION
 
-EVP_PKEY_param_check() validates the domain parameters component of the key
+EVP_PKEY_param_check() validates the parameters component of the key
 given by B<ctx>.
 
 EVP_PKEY_public_check() validates the public component of the key given by B<ctx>.
index 0e3dc5c..ed8c668 100644 (file)
@@ -4,7 +4,7 @@
 
 EVP_PKEY_param_fromdata_init, EVP_PKEY_key_fromdata_init, EVP_PKEY_fromdata,
 EVP_PKEY_param_fromdata_settable, EVP_PKEY_key_fromdata_settable
-- functions to create domain parameters and keys from user data
+- functions to create key parameters and keys from user data
 
 =head1 SYNOPSIS
 
@@ -19,12 +19,12 @@ EVP_PKEY_param_fromdata_settable, EVP_PKEY_key_fromdata_settable
 =head1 DESCRIPTION
 
 EVP_PKEY_param_fromdata_init() initializes a public key algorithm context
-for creating domain parameters from user data.
+for creating key parameters from user data.
 
 EVP_PKEY_key_fromdata_init() initializes a public key algorithm context for
 creating a key from user data.
 
-EVP_PKEY_fromdata() creates domain parameters or a key, given data from
+EVP_PKEY_fromdata() creates key parameters or a key, given data from
 I<params> and a context that's been initialized with
 EVP_PKEY_param_fromdata_init() or EVP_PKEY_key_fromdata_init().  The result is
 written to I<*ppkey>.
index caa9294..8cc7cfb 100644 (file)
@@ -36,11 +36,11 @@ OSSL_SERIALIZER_Parameters_TO_TEXT_PQ
 
  #define OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
  #define OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=domainparams"
+ #define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
 
  #define OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
  #define OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=domainparams"
+ #define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
 
 =head1 DESCRIPTION
 
index dc3618e..4b7a326 100644 (file)
@@ -36,7 +36,7 @@ use any key specific format or PKCS#8 unencrypted PrivateKeyInfo format. The
 B<type> parameter should be a public key algorithm constant such as
 B<EVP_PKEY_RSA>. An error occurs if the decoded key does not match B<type>.
 d2i_PublicKey() does the same for public keys.
-d2i_KeyParams() does the same for domain parameter keys.
+d2i_KeyParams() does the same for key parameters.
 
 d2i_AutoPrivateKey() is similar to d2i_PrivateKey() except it attempts to
 automatically detect the private key format.
@@ -44,7 +44,7 @@ automatically detect the private key format.
 i2d_PrivateKey() encodes B<key>. It uses a key specific format or, if none is
 defined for that key type, PKCS#8 unencrypted PrivateKeyInfo format.
 i2d_PublicKey() does the same for public keys.
-i2d_KeyParams() does the same for domain parameter keys.
+i2d_KeyParams() does the same for key parameters.
 These functions are similar to the d2i_X509() functions; see L<d2i_X509(3)>.
 
 =head1 NOTES
index 94427de..e9e4de5 100644 (file)
@@ -14,47 +14,29 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
   * pointers in OSSL_DISPATCH arrays.
   */
 
- /* Key domain parameter creation and destruction */
- void *OP_keymgmt_importdomparams(void *provctx, const OSSL_PARAM params[]);
- void *OP_keymgmt_gendomparams(void *provctx, const OSSL_PARAM params[]);
- void OP_keymgmt_freedomparams(void *domparams);
+ /* Key object (keydata) creation and destruction */
+ void *OP_keymgmt_new(void *provctx);
+ void OP_keymgmt_free(void *keydata);
 
- /* Key domain parameter export */
- int OP_keymgmt_exportdomparams(void *domparams, OSSL_PARAM params[]);
+ /* Key object information */
+ int OP_keymgmt_get_params(void *keydata, OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keymgmt_gettable_params(void);
 
- /* Key domain parameter discovery */
- const OSSL_PARAM *OP_keymgmt_importdomparam_types(void);
- const OSSL_PARAM *OP_keymgmt_exportdomparam_types(void);
+ /* Key object content checks */
+ int OP_keymgmt_has(void *keydata, int selection);
 
- /* Key domain parameter information */
- int OP_keymgmt_get_domparam_params(void *domparams, OSSL_PARAM params[]);
- const OSSL_PARAM *OP_keymgmt_gettable_domparam_params(void);
-
- /* Key domain parameter validation */
- int OP_keymgmt_validate_domparams(void *key);
-
- /* Key creation and destruction */
- void *OP_keymgmt_importkey(void *provctx, const OSSL_PARAM params[]);
- void *OP_keymgmt_genkey(void *provctx,
-                         void *domparams, const OSSL_PARAM genkeyparams[]);
- void *OP_keymgmt_loadkey(void *provctx, void *id, size_t idlen);
- void OP_keymgmt_freekey(void *key);
-
- /* Key export */
- int OP_keymgmt_exportkey(void *key, OSSL_PARAM params[]);
-
- /* Key discovery */
- const OSSL_PARAM *OP_keymgmt_importkey_types(void);
- const OSSL_PARAM *OP_keymgmt_exportkey_types(void);
+ /* Discovery of supported operations */
+ const char *OP_keymgmt_query_operation_name(int operation_id);
 
- /* Key information */
- int OP_keymgmt_get_key_params(void *key, OSSL_PARAM params[]);
- const OSSL_PARAM *OP_keymgmt_gettable_key_params(void);
+ /* Key object import and export functions */
+ int OP_keymgmt_import(int selection, void *keydata, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keymgmt_import_types, (int selection);
+ int OP_keymgmt_export(int selection, void *keydata,
+                       OSSL_CALLBACK *param_cb, void *cbarg);
+ const OSSL_PARAM *OP_keymgmt_export_types(int selection);
 
- /* Key validation */
- int OP_keymgmt_validate_public(void *key);
- int OP_keymgmt_validate_private(void *key);
- int OP_keymgmt_validate_pairwise(void *key);
+ /* Key object validation */
+ int OP_keymgmt_validate(void *keydata, int selection);
 
  /* Discovery of supported operations */
  const char *OP_keymgmt_query_operation_name(int operation_id);
@@ -70,8 +52,7 @@ works with in tandem, they must belong to the same provider.
 The OpenSSL libraries will ensure that they do.
 
 The primary responsibility of the KEYMGMT operation is to hold the
-provider side domain parameters and keys for the OpenSSL library
-EVP_PKEY structure.
+provider side key data for the OpenSSL library EVP_PKEY structure.
 
 All "functions" mentioned here are passed as function pointers between
 F<libcrypto> and the provider in B<OSSL_DISPATCH> arrays via
@@ -83,133 +64,147 @@ All these "functions" have a corresponding function type definition
 named B<OSSL_{name}_fn>, and a helper function to retrieve the
 function pointer from a B<OSSL_DISPATCH> element named
 B<OSSL_get_{name}>.
-For example, the "function" OP_keymgmt_importdomparams() has these:
+For example, the "function" OP_keymgmt_new() has these:
 
- typedef void *
-     (OSSL_OP_keymgmt_importdomparams_fn)(void *provctx,
-                                          const OSSL_PARAM params[]);
- static ossl_inline OSSL_OP_keymgmt_importdomparams_fn
-     OSSL_get_OP_keymgmt_importdomparams(const OSSL_DISPATCH *opf);
+ typedef void *(OSSL_OP_keymgmt_new_fn)(void *provctx);
+ static ossl_inline OSSL_OP_keymgmt_new_fn
+     OSSL_get_OP_keymgmt_new(const OSSL_DISPATCH *opf);
 
 B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
 macros in L<openssl-core_numbers.h(7)>, as follows:
 
- OP_keymgmt_importdomparams      OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS
- OP_keymgmt_gendomparams         OSSL_FUNC_KEYMGMT_GENDOMPARAMS
- OP_keymgmt_freedomparams        OSSL_FUNC_KEYMGMT_FREEDOMPARAMS
- OP_keymgmt_exportdomparams      OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS
- OP_keymgmt_importdomparam_types OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES
- OP_keymgmt_exportdomparam_types OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES
- OP_keymgmt_get_domparam_params  OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS
- OP_keymgmt_gettable_domparam_params
-                                 OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS
-
- OP_keymgmt_importkey            OSSL_FUNC_KEYMGMT_IMPORTKEY
- OP_keymgmt_genkey               OSSL_FUNC_KEYMGMT_GENKEY
- OP_keymgmt_loadkey              OSSL_FUNC_KEYMGMT_LOADKEY
- OP_keymgmt_freekey              OSSL_FUNC_KEYMGMT_FREEKEY
- OP_keymgmt_exportkey            OSSL_FUNC_KEYMGMT_EXPORTKEY
- OP_keymgmt_importkey_types      OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES
- OP_keymgmt_exportkey_types      OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES
- OP_keymgmt_get_key_params       OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS
- OP_keymgmt_gettable_key_params  OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS
+ OP_keymgmt_new                  OSSL_FUNC_KEYMGMT_NEW
+ OP_keymgmt_free                 OSSL_FUNC_KEYMGMT_FREE
+
+ OP_keymgmt_get_params           OSSL_FUNC_KEYMGMT_GET_PARAMS
+ OP_keymgmt_gettable_params      OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS
 
  OP_keymgmt_query_operation_name OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME
 
- OP_keymgmt_validate_domparams   OSSL_FUNC_KEYMGMT_VALIDATE_DOMPARAMS
- OP_keymgmt_validate_public      OSSL_FUNC_KEYMGMT_VALIDATE_PUBLIC
- OP_keymgmt_validate_private     OSSL_FUNC_KEYMGMT_VALIDATE_PRIVATE
- OP_keymgmt_validate_pairwise    OSSL_FUNC_KEYMGMT_VALIDATE_PAIRWISE
+ OP_keymgmt_has                  OSSL_FUNC_KEYMGMT_HAS
+ OP_keymgmt_validate             OSSL_FUNC_KEYMGMT_VALIDATE
 
-=head2 Domain Parameter Functions
+ OP_keymgmt_import               OSSL_FUNC_KEYMGMT_IMPORT
+ OP_keymgmt_import_types         OSSL_FUNC_KEYMGMT_IMPORT_TYPES
+ OP_keymgmt_export               OSSL_FUNC_KEYMGMT_EXPORT
+ OP_keymgmt_export_types         OSSL_FUNC_KEYMGMT_EXPORT_TYPES
 
-OP_keymgmt_importdomparams() should create a provider side structure
-for domain parameters, with values taken from the passed B<OSSL_PARAM>
-array I<params>.
 
-OP_keymgmt_gendomparams() should generate domain parameters and create
-a provider side structure for them.
-Values of the passed B<OSSL_PARAM> array I<params> should be used as
-input for parameter generation.
+=head2 Key Objects
 
-OP_keymgmt_freedomparams() should free the passed provider side domain
-parameter structure I<domparams>.
+A key object is a collection of data for an asymmetric key, and is
+represented as I<keydata> in this manual.
 
-OP_keymgmt_exportdomparams() should extract values from the passed
-provider side domain parameter structure I<domparams> into the passed
-B<OSSL_PARAM> I<params>.
-Only the values specified in I<params> should be extracted.
+The exact contents of a key object are defined by the provider, and it
+is assumed that different operations in one and the same provider use
+the exact same structure to represent this collection of data, so that
+for example, a key object that has been created using the KEYMGMT
+interface that we document here can be passed as is to other provider
+operations, such as OP_signature_sign_init() (see
+L<provider-signature(7)>).
 
-OP_keymgmt_importdomparam_types() should return a constant array of
-descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_importdomparams()
-can handle.
+With some of the KEYMGMT functions, it's possible to select a specific
+subset of data to handle, governed by the bits in a I<selection>
+indicator.  The bits are:
+
+=over 4
 
-OP_keymgmt_exportdomparam_types() should return a constant array of
-descriptor B<OSSL_PARAM>, for parameters that can be exported with
-OP_keymgmt_exportdomparams().
+=item B<OSSL_KEYMGMT_SELECT_PRIVATE_KEY>
 
-OP_keymgmt_get_domparam_params() should extract information data
-associated with the given I<domparams>,
-see L</Information Parameters>.
+Indicating that the private key data in a key object should be
+considered.
 
-OP_keymgmt_gettable_domparam_params() should return a constant array
-of descriptor B<OSSL_PARAM>, for parameters that
-OP_keymgmt_get_domparam_params() can handle.
+=item B<OSSL_KEYMGMT_SELECT_PUBLIC_KEY>
 
-OP_keymgmt_validate_domparams() should return a value of 1 if the
-domain parameters are valid, or 0 for invalid.
+Indicating that the public key data in a key object should be
+considered.
 
-=head2 Key functions
+=item B<OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS>
 
-OP_keymgmt_importkey() should create a provider side structure
-for keys, with values taken from the passed B<OSSL_PARAM> array
-I<params>.
+Indicating that the domain parameters in a key object should be
+considered.
 
-OP_keymgmt_genkey() should generate keys and create a provider side
-structure for them.
-Values from the passed domain parameters I<domparams> as well as from
-the passed B<OSSL_PARAM> array I<params> should be used as input for
-key generation.
+=item B<OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS>
 
-OP_keymgmt_loadkey() should return a provider side key structure with
-a key loaded from a location known only to the provider, identitified
-with the identity I<id> of size I<idlen>.
-This identity is internal to the provider and is retrieved from the
-provider through other means.
+Indicating that other parameters in a key object should be
+considered.
 
-=for comment Right now, OP_keymgmt_loadkey is useless, but will be
-useful as soon as we have a OSSL_STORE interface
+Other parameters are key parameters that don't fit any other
+classification.  In other words, this particular selector bit works as
+a last resort bit bucket selector.
 
-OP_keymgmt_freekey() should free the passed I<key>.
+=back
 
-OP_keymgmt_exportkey() should extract values from the passed
-provider side key I<key> into the passed B<OSSL_PARAM> I<params>.
-Only the values specified in I<params> should be extracted.
+Some selector bits have also been combined for easier use:
 
-OP_keymgmt_importkey_types() should return a constant array of
-descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_importkey()
-can handle.
+=over 4
+
+=item B<OSSL_KEYMGMT_SELECT_ALL_PARAMETERS>
+
+Indicating that all key object parameters should be considered,
+regardless of their more granular classification.
 
-OP_keymgmt_exportkey_types() should return a constant array of
-descriptor B<OSSL_PARAM>, for parameters that can be exported with
-OP_keymgmt_exportkeys().
+=for comment This should used by EVP functions such as
+EVP_PKEY_copy_parameters() and EVP_PKEY_cmp_parameters()
 
-OP_keymgmt_get_key_params() should extract information data associated
-with the given I<key>, see L</Information Parameters>.
+This is a combination of B<OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS> and
+B<OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS>.
 
-OP_keymgmt_gettable_key_params() should return a constant array of
-descriptor B<OSSL_PARAM>, for parameters that
-OP_keymgmt_get_key_params() can handle.
+=for comment If more parameter categories are added, they should be
+mentioned here too.
 
-OP_keymgmt_validate_public() should return 1 if the public component of the
-key is valid, or 0 if invalid.
-OP_keymgmt_validate_private() should return 1 if the private component of the
-key is valid, or 0 if invalid.
-OP_keymgmt_validate_pairwise() should return 1 if the the pairwise consistency
-of the key is valid, or 0 if invalid.
+=item B<OSSL_KEYMGMT_SELECT_KEYPAIR>
 
+Indicating that both the whole key pair in a key object should be
+considered, i.e. the combination of public and private key.
+
+This is a combination of B<OSSL_KEYMGMT_SELECT_PRIVATE_KEY> and
+B<OSSL_KEYMGMT_SELECT_PUBLIC_KEY>.
+
+=item B<OSSL_KEYMGMT_SELECT_ALL>
+
+Indicating that everything in a key object should be considered.
+
+=back
 
-=head2 Supported operations
+The exact interpretation of those bits or how they combine is left to
+each function where you can specify a selector.
+
+=for comment One might think that a combination of bits means that all
+the selected data subsets must be considered, but then you have to
+consider that when comparing key objects (future function), an
+implementation might opt to not compare the private key if it has
+compared the public key, since a match of one half implies a match of
+the other half.
+
+=head2 Constructing and Destructing Functions
+
+OP_keymgmt_new() should create a provider side key object.  The
+provider context I<provctx> is passed and may be incorporated in the
+key object, but that is not mandatory.
+
+OP_keymgmt_free() should free the passed I<keydata>.
+
+The constructor and destructor are mandatory, a KEYMGMT implementation
+without them will not be accepted.
+
+=for comment when new constructors appear, it's sufficient if only one
+of them is present.  The remark above will have to change to reflect
+that.
+
+=head2 Key Object Information Functions
+
+OP_keymgmt_get_params() should extract information data associated
+with the given I<keydata>, see L</Information Parameters>.
+
+OP_keymgmt_gettable_params() should return a constant array of
+descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_get_params()
+can handle.
+
+If OP_keymgmt_gettable_params() is present, OP_keymgmt_get_params()
+must also be present.
+
+=head2 Key Object Checking Functions
 
 OP_keymgmt_query_operation_name() should return the name of the
 supported algorithm for the operation I<operation_id>.  This is
@@ -219,13 +214,43 @@ returns NULL, the caller is free to assume that there's an algorithm
 from the same provider, of the same name as the one used to fetch the
 keymgmt and try to use that.
 
+OP_keymgmt_has() should check whether the given I<keydata> the subsets
+of data indicated by the I<selector>.  A combination of several
+selector bits must consider all those subsets, not just one.  An
+implementation is, however, free to consider an empty subset of data
+to still be a valid subset.
+
+OP_keymgmt_validate() should check if the I<keydata> contains valid
+data subsets indicated by I<selection>.  Some combined selections of
+data subsets may cause validation of the combined data.
+For example, the combination of B<OSSL_KEYMGMT_SELECT_PRIVATE_KEY> and
+B<OSSL_KEYMGMT_SELECT_PUBLIC_KEY> (or B<OSSL_KEYMGMT_SELECT_KEYPAIR>
+for short) is expected to check that the pairwise consistency of
+I<keydata> is valid.
+
+=head2 Key Object Import and Export Functions
+
+OP_keymgmt_import() should import data indicated by I<selection> into
+I<keydata> with values taken from the B<OSSL_PARAM> array I<params>.
+
+OP_keymgmt_export() should extract values indicated by I<selection>
+from I<keydata>, create an B<OSSL_PARAM> array with them and call
+I<param_cb> with that array as well as the given I<cbarg>.
+
+OP_keymgmt_import_types() should return a constant array of descriptor
+B<OSSL_PARAM> for data indicated by I<selection>, for parameters that
+OP_keymgmt_import() can handle.
+
+OP_keymgmt_export_types() should return a constant array of descriptor
+B<OSSL_PARAM> for data indicated by I<selection>, that the
+OP_keymgmt_export() callback can expect to receive.
+
 =head2 Information Parameters
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure.
 
 Parameters currently recognised by built-in keymgmt algorithms'
-OP_keymgmt_get_domparams_params() and OP_keymgmt_get_key_params()
-are:
+OP_keymgmt_get_params:
 
 =over 4
 
index b23a8b6..121eb33 100644 (file)
@@ -127,7 +127,7 @@ formatted data.
 
 With objects that have multiple purposes, this can be used to specify
 the purpose type.  The currently known use cases are asymmetric keys
-and domain parameters, where the type can be one of:
+and key parameters, where the type can be one of:
 
 =over 4
 
@@ -141,9 +141,9 @@ key.
 An implementation with that format property value outputs a public
 key.
 
-=item domainparams
+=item parameters
 
-An implementation with that format property value outputs domain
+An implementation with that format property value outputs key
 parameters.
 
 =back
index 2581619..0e7e9ba 100644 (file)
@@ -70,8 +70,8 @@ struct evp_pkey_asn1_method_st {
      */
     /* Exports to providers */
     size_t (*dirty_cnt) (const EVP_PKEY *pk);
-    void *(*export_to) (const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
-                        int want_domainparams);
+    int (*export_to) (const EVP_PKEY *pk, void *to_keydata,
+                      EVP_KEYMGMT *to_keymgmt);
 } /* EVP_PKEY_ASN1_METHOD */ ;
 
 DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
index cafb465..6903cc6 100644 (file)
@@ -548,17 +548,15 @@ struct evp_pkey_st {
 
     /* == Provider attributes == */
     /*
-     * To support transparent export/import between providers that
-     * support the methods for it, and still not having to do the
-     * export/import every time a key or domain params are used, we
-     * maintain a cache of imported key / domain params, indexed by
-     * provider address.  pkeys[0] is *always* the "original" data.
+     * To support transparent export/import between providers that support
+     * the methods for it, and still not having to do the export/import
+     * every time a key object is changed, we maintain a cache of imported
+     * key objects, indexed by keymgmt address.  pkeys[0] is *always* the
+     * "original" data unless we have a legacy key attached.
      */
     struct {
         EVP_KEYMGMT *keymgmt;
-        void *provdata;
-        /* 0 = provdata is a key, 1 = provdata is domain params */
-        int domainparams;
+        void *keydata;
     } pkeys[10];
     /*
      * If there is a legacy key assigned to this structure, we keep
@@ -566,7 +564,7 @@ struct evp_pkey_st {
      */
     size_t dirty_cnt_copy;
 
-    /* Cache of domain parameter / key information */
+    /* Cache of key object information */
     struct {
         int bits;
         int security_bits;
@@ -596,57 +594,36 @@ void evp_app_cleanup_int(void);
 /*
  * KEYMGMT utility functions
  */
-void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
-                                          int domainparams);
+void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
 void evp_keymgmt_util_clear_pkey_cache(EVP_PKEY *pk);
 void evp_keymgmt_util_cache_pkey(EVP_PKEY *pk, size_t index,
-                                 EVP_KEYMGMT *keymgmt, void *provdata,
-                                 int domainparams);
+                                 EVP_KEYMGMT *keymgmt, void *keydata);
 void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
-                                const OSSL_PARAM params[], int domainparams);
+                                int selection, const OSSL_PARAM params[]);
 
 
 /*
  * KEYMGMT provider interface functions
  */
-void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt,
-                                  const OSSL_PARAM params[]);
-void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt,
-                            const OSSL_PARAM params[]);
-void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt,
-                               void *provdomparams);
-int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt,
-                                void *provdomparams,
-                                OSSL_CALLBACK *param_cb, void *cbarg);
-const OSSL_PARAM *
-evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt);
-const OSSL_PARAM *
-evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt);
-int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt,
-                                    void *provdomparam, OSSL_PARAM params[]);
-const OSSL_PARAM *
-evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt);
-
-void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
-                            const OSSL_PARAM params[]);
-void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams,
-                         const OSSL_PARAM params[]);
-void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt,
-                          void *id, size_t idlen);
-void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey);
-int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey,
-                          OSSL_CALLBACK *param_cb, void *cbarg);
-const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt);
-const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt);
-int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt,
-                               void *provkey, OSSL_PARAM params[]);
-const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt);
-
-int evp_keymgmt_validate_domparams(const EVP_KEYMGMT *keymgmt, void *provkey);
-int evp_keymgmt_validate_public(const EVP_KEYMGMT *keymgmt, void *provkey);
-int evp_keymgmt_validate_private(const EVP_KEYMGMT *keymgmt, void *provkey);
-int evp_keymgmt_validate_pairwise(const EVP_KEYMGMT *keymgmt, void *provkey);
-
+void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt);
+void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata);
+int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt,
+                           void *keydata, OSSL_PARAM params[]);
+const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt);
+
+
+int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
+int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
+                         int selection);
+
+int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata,
+                       int selection, const OSSL_PARAM params[]);
+const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt,
+                                           int selection);
+int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
+                       int selection, OSSL_CALLBACK *param_cb, void *cbarg);
+const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
+                                           int selection);
 
 /* Pulling defines out of C source files */
 
index 1c40351..b84e180 100644 (file)
@@ -26,6 +26,9 @@ OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s);
 /* Property checker of query vs definition */
 int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
                               const OSSL_PROPERTY_LIST *defn);
+/* Free a parsed property list */
+void ossl_property_free(OSSL_PROPERTY_LIST *p);
+
 
 /* Implementation store functions */
 OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx);
index ecee173..547aeb5 100644 (file)
@@ -333,109 +333,93 @@ OSSL_CORE_MAKE_FUNC(int, OP_kdf_set_ctx_params,
 /*-
  * Key management
  *
- * Key domain parameter references can be created in several manners:
- * - by importing the domain parameter material via an OSSL_PARAM array.
- * - by generating key domain parameters, given input via an OSSL_PARAM
- *   array.
+ * The Key Management takes care of provider side key objects, and includes
+ * all current functionality to create them, destroy them, set parameters
+ * and key material, etc, essentially everything that manipulates the keys
+ * themselves and their parameters.
  *
- * Key references can be created in several manners:
- * - by importing the key material via an OSSL_PARAM array.
- * - by generating a key, given optional domain parameters and
- *   additional keygen parameters.
- *   If domain parameters are given, they must have been generated using
- *   the domain parameter generator functions.
- *   If the domain parameters comes from a different provider, results
- *   are undefined.
- *   THE CALLER MUST ENSURE THAT CORRECT DOMAIN PARAMETERS ARE USED.
- * - by loading an internal key, given a binary blob that forms an identity.
- *   THE CALLER MUST ENSURE THAT A CORRECT IDENTITY IS USED.
+ * The key objects are commonly refered to as |keydata|, and it MUST be able
+ * to contain parameters if the key has any, the public key and the private
+ * key.  All parts are optional, but their presence determines what can be
+ * done with the key object in terms of encryption, signature, and so on.
+ * The assumption from libcrypto is that the key object contains any of the
+ * following data combinations:
+ *
+ * - parameters only
+ * - public key only
+ * - public key + private key
+ * - parameters + public key
+ * - parameters + public key + private key
+ *
+ * What "parameters", "public key" and "private key" means in detail is left
+ * to the implementation.  In the case of DH and DSA, they would typically
+ * include domain parameters, while for certain variants of RSA, they would
+ * typically include PSS or OAEP parameters.
+ *
+ * Key objects are created with OP_keymgmt_new() and destroyed with
+ * Op_keymgmt_free().  Key objects can have data filled in with
+ * OP_keymgmt_import().
+ *
+ * Three functions are made available to check what selection of data is
+ * present in a key object: OP_keymgmt_has_parameters(),
+ * OP_keymgmt_has_public_key(), and OP_keymgmt_has_private_key(),
  */
 
-/* Key domain parameter creation and destruction */
-# define OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS           1
-# define OSSL_FUNC_KEYMGMT_GENDOMPARAMS              2
-# define OSSL_FUNC_KEYMGMT_FREEDOMPARAMS             3
-OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_importdomparams,
-                    (void *provctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_gendomparams,
-                    (void *provctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_freedomparams, (void *domparams))
-
-/* Key domain parameter export */
-# define OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS           4
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_exportdomparams,
-                    (void *domparams, OSSL_CALLBACK *param_cb, void *cbarg))
-
-/* Key domain parameter discovery */
-/*
- * TODO(v3.0) investigate if we need OP_keymgmt_exportdomparam_types.
- * 'openssl provider' may be a caller...
- */
-# define OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES      5
-# define OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES      6
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_importdomparam_types,
-                    (void))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportdomparam_types,
-                    (void))
-
-/* Key domain parameter information */
-#define OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS        7
-#define OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS   8
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_get_domparam_params,
-                    (void *domparam, OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_gettable_domparam_params,
-                    (void))
-
-/* Key creation and destruction */
-# define OSSL_FUNC_KEYMGMT_IMPORTKEY                20
-# define OSSL_FUNC_KEYMGMT_GENKEY                   21
-# define OSSL_FUNC_KEYMGMT_LOADKEY                  22
-# define OSSL_FUNC_KEYMGMT_FREEKEY                  23
-OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_importkey,
-                    (void *provctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_genkey,
-                    (void *provctx,
-                     void *domparams, const OSSL_PARAM genkeyparams[]))
-OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_loadkey,
-                    (void *provctx, void *id, size_t idlen))
-OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_freekey, (void *key))
-
-/* Key export */
-# define OSSL_FUNC_KEYMGMT_EXPORTKEY                24
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_exportkey,
-                    (void *key, OSSL_CALLBACK *param_cb, void *cbarg))
-
-/* Key discovery */
-/*
- * TODO(v3.0) investigate if we need OP_keymgmt_exportkey_types.
- * 'openssl provider' may be a caller...
- */
-# define OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES          25
-# define OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES          26
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_importkey_types, (void))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_exportkey_types, (void))
-
-/* Key information */
-# define OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS           27
-# define OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS      28
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_get_key_params,
-                    (void *key, OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_gettable_key_params, (void))
-
-/* Discovery of supported operations */
-# define OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME     40
-OSSL_CORE_MAKE_FUNC(const char *,OP_keymgmt_query_operation_name,
+/* Key data subset selection - individual bits */
+# define OSSL_KEYMGMT_SELECT_PRIVATE_KEY            0x01
+# define OSSL_KEYMGMT_SELECT_PUBLIC_KEY             0x02
+# define OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS      0x04
+# define OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS       0x80
+
+/* Key data subset selection - combinations */
+# define OSSL_KEYMGMT_SELECT_ALL_PARAMETERS     \
+    ( OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS     \
+      | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
+# define OSSL_KEYMGMT_SELECT_KEYPAIR            \
+    ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY | OSSL_KEYMGMT_SELECT_PUBLIC_KEY )
+# define OSSL_KEYMGMT_SELECT_ALL                \
+    ( OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
+
+/* Basic key object creation, destruction */
+# define OSSL_FUNC_KEYMGMT_NEW                         1
+# define OSSL_FUNC_KEYMGMT_FREE                        9
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_new, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_free, (void *keydata))
+
+/* Key object information, with discovery */
+#define OSSL_FUNC_KEYMGMT_GET_PARAMS                  10
+#define OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS             11
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_get_params,
+                    (void *keydata, OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_gettable_params, (void))
+
+/* Key checks - discovery of supported operations */
+# define OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME       20
+OSSL_CORE_MAKE_FUNC(const char *, OP_keymgmt_query_operation_name,
                     (int operation_id))
 
-/* Key validation */
-# define OSSL_FUNC_KEYMGMT_VALIDATE_DOMPARAMS       29
-# define OSSL_FUNC_KEYMGMT_VALIDATE_PUBLIC          30
-# define OSSL_FUNC_KEYMGMT_VALIDATE_PRIVATE         31
-# define OSSL_FUNC_KEYMGMT_VALIDATE_PAIRWISE        32
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_validate_domparams, (void *key))
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_validate_public, (void *key))
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_validate_private, (void *key))
-OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_validate_pairwise, (void *key))
+/* Key checks - key data content checks */
+# define OSSL_FUNC_KEYMGMT_HAS                        21
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_has, (void *keydata, int selection))
+
+/* Key checks - validation */
+# define OSSL_FUNC_KEYMGMT_VALIDATE                   22
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_validate, (void *keydata, int selection))
+
+/* Import and export functions, with ddiscovery */
+# define OSSL_FUNC_KEYMGMT_IMPORT                     40
+# define OSSL_FUNC_KEYMGMT_IMPORT_TYPES               41
+# define OSSL_FUNC_KEYMGMT_EXPORT                     42
+# define OSSL_FUNC_KEYMGMT_EXPORT_TYPES               43
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_import,
+                    (void *keydata, int selection, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_import_types,
+                    (int selection))
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_export,
+                    (void *keydata, int selection,
+                     OSSL_CALLBACK *param_cb, void *cbarg))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_export_types,
+                    (int selection))
 
 /* Key Exchange */
 
index 2629a13..c37939f 100644 (file)
@@ -87,12 +87,12 @@ OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
  */
 # define OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
 # define OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
-# define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=domainparams"
+# define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
 
 /* Corresponding macros for text output */
 # define OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
 # define OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
-# define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=domainparams"
+# define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
 
 # ifdef __cplusplus
 }