CORE: Add the key object generator libcrypto<->provider interface
authorRichard Levitte <levitte@openssl.org>
Sat, 26 Oct 2019 11:00:56 +0000 (13:00 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 12 Mar 2020 09:43:58 +0000 (10:43 +0100)
We introduce these dispatched functions:

-   OP_keymgmt_gen_init() to initialize the key object generation.
-   OP_keymgmt_gen_set_template() to set a template for key object
    generation.  The template is another key object, for example one
    with domain parameters.
-   OP_keymgmt_gen_set_params() to set other key object generation
    parameters.
-   OP_keymgmt_gen_settable_params() to find out what settable
    parameters there are.
-   OP_keymgmt_gen() to perform the key object generation.
-   OP_keymgmt_gen_cleanup() to clean up the key object generation.

Internal function for easy and consistent use of these ddispatched
functions are added.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10289)

crypto/evp/evp_local.h
crypto/evp/keymgmt_meth.c
doc/man7/provider-keymgmt.pod
include/crypto/evp.h
include/openssl/core_numbers.h

index 858f1c4..836dc33 100644 (file)
@@ -81,6 +81,14 @@ struct evp_keymgmt_st {
     OSSL_OP_keymgmt_set_params_fn *set_params;
     OSSL_OP_keymgmt_settable_params_fn *settable_params;
 
+    /* Generation, a complex constructor */
+    OSSL_OP_keymgmt_gen_init_fn *gen_init;
+    OSSL_OP_keymgmt_gen_set_template_fn *gen_set_template;
+    OSSL_OP_keymgmt_gen_set_params_fn *gen_set_params;
+    OSSL_OP_keymgmt_gen_settable_params_fn *gen_settable_params;
+    OSSL_OP_keymgmt_gen_fn *gen;
+    OSSL_OP_keymgmt_gen_cleanup_fn *gen_cleanup;
+
     /* Key object checking */
     OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
     OSSL_OP_keymgmt_has_fn *has;
index f80e6e2..07d52eb 100644 (file)
@@ -38,7 +38,8 @@ static void *keymgmt_from_dispatch(int name_id,
                                    OSSL_PROVIDER *prov)
 {
     EVP_KEYMGMT *keymgmt = NULL;
-    int setparamfncnt = 0, getparamfncnt = 0, importfncnt = 0, exportfncnt = 0;
+    int setparamfncnt = 0, getparamfncnt = 0, setgenparamfncnt = 0;
+    int importfncnt = 0, exportfncnt = 0;
 
     if ((keymgmt = keymgmt_new()) == NULL) {
         EVP_KEYMGMT_free(keymgmt);
@@ -52,6 +53,37 @@ static void *keymgmt_from_dispatch(int name_id,
             if (keymgmt->new == NULL)
                 keymgmt->new = OSSL_get_OP_keymgmt_new(fns);
             break;
+        case OSSL_FUNC_KEYMGMT_GEN_INIT:
+            if (keymgmt->gen_init == NULL)
+                keymgmt->gen_init = OSSL_get_OP_keymgmt_gen_init(fns);
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE:
+            if (keymgmt->gen_set_template == NULL)
+                keymgmt->gen_set_template =
+                    OSSL_get_OP_keymgmt_gen_set_template(fns);
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS:
+            if (keymgmt->gen_set_params == NULL) {
+                setgenparamfncnt++;
+                keymgmt->gen_set_params =
+                    OSSL_get_OP_keymgmt_gen_set_params(fns);
+            }
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS:
+            if (keymgmt->gen_settable_params == NULL) {
+                setgenparamfncnt++;
+                keymgmt->gen_settable_params =
+                    OSSL_get_OP_keymgmt_gen_settable_params(fns);
+            }
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN:
+            if (keymgmt->gen == NULL)
+                keymgmt->gen = OSSL_get_OP_keymgmt_gen(fns);
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN_CLEANUP:
+            if (keymgmt->gen_cleanup == NULL)
+                keymgmt->gen_cleanup = OSSL_get_OP_keymgmt_gen_cleanup(fns);
+            break;
         case OSSL_FUNC_KEYMGMT_FREE:
             if (keymgmt->free == NULL)
                 keymgmt->free = OSSL_get_OP_keymgmt_free(fns);
@@ -134,12 +166,16 @@ static void *keymgmt_from_dispatch(int name_id,
      * export if you can't import or export.
      */
     if (keymgmt->free == NULL
-        || keymgmt->new == NULL
+        || (keymgmt->new == NULL && keymgmt->gen == NULL)
         || keymgmt->has == NULL
         || (getparamfncnt != 0 && getparamfncnt != 2)
         || (setparamfncnt != 0 && setparamfncnt != 2)
+        || (setgenparamfncnt != 0 && setgenparamfncnt != 2)
         || (importfncnt != 0 && importfncnt != 2)
-        || (exportfncnt != 0 && exportfncnt != 2)) {
+        || (exportfncnt != 0 && exportfncnt != 2)
+        || (keymgmt->gen != NULL
+            && (keymgmt->gen_init == NULL
+                || keymgmt->gen_cleanup == NULL))) {
         EVP_KEYMGMT_free(keymgmt);
         EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
         return NULL;
@@ -249,6 +285,54 @@ void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata)
     keymgmt->free(keydata);
 }
 
+void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection)
+{
+    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
+
+    if (keymgmt->gen_init == NULL)
+        return NULL;
+    return keymgmt->gen_init(provctx, selection);
+}
+
+int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx,
+                                 void *template)
+{
+    if (keymgmt->gen_set_template == NULL)
+        return 0;
+    return keymgmt->gen_set_template(genctx, template);
+}
+
+int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
+                               const OSSL_PARAM params[])
+{
+    if (keymgmt->gen_set_params == NULL)
+        return 0;
+    return keymgmt->gen_set_params(genctx, params);
+}
+
+const OSSL_PARAM *evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt)
+{
+    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
+
+    if (keymgmt->gen_settable_params == NULL)
+        return NULL;
+    return keymgmt->gen_settable_params(provctx);
+}
+
+void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
+                      OSSL_CALLBACK *cb, void *cbarg)
+{
+    if (keymgmt->gen == NULL)
+        return NULL;
+    return keymgmt->gen(genctx, cb, cbarg);
+}
+
+void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)
+{
+    if (keymgmt->gen != NULL)
+        keymgmt->gen_cleanup(genctx);
+}
+
 int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata,
                            OSSL_PARAM params[])
 {
index 0a2768b..59e538d 100644 (file)
@@ -18,6 +18,13 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
  void *OP_keymgmt_new(void *provctx);
  void OP_keymgmt_free(void *keydata);
 
+ void *OP_keymgmt_gen_init(void *provctx, int selection);
+ int OP_keymgmt_gen_set_template(void *genctx, void *template);
+ int OP_keymgmt_gen_set_params(void *genctx, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keymgmt_gen_settable_params(void *provctx);
+ void *OP_keymgmt_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg);
+ void OP_keymgmt_gen_cleanup(void *genctx);
+
  /* Key object information */
  int OP_keymgmt_get_params(void *keydata, OSSL_PARAM params[]);
  const OSSL_PARAM *OP_keymgmt_gettable_params(void);
@@ -80,6 +87,13 @@ macros in L<openssl-core_numbers.h(7)>, as follows:
  OP_keymgmt_new                  OSSL_FUNC_KEYMGMT_NEW
  OP_keymgmt_free                 OSSL_FUNC_KEYMGMT_FREE
 
+ OP_keymgmt_gen_init             OSSL_FUNC_KEYMGMT_GEN_INIT
+ OP_keymgmt_gen_set_template     OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE
+ OP_keymgmt_gen_set_params       OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS
+ OP_keymgmt_gen_settable_params  OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS
+ OP_keymgmt_gen                  OSSL_FUNC_KEYMGMT_GEN
+ OP_keymgmt_gen_cleanup          OSSL_FUNC_KEYMGMT_GEN_CLEANUP
+
  OP_keymgmt_get_params           OSSL_FUNC_KEYMGMT_GET_PARAMS
  OP_keymgmt_gettable_params      OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS
  OP_keymgmt_set_params           OSSL_FUNC_KEYMGMT_SET_PARAMS
@@ -193,12 +207,41 @@ 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.
+OP_keymgmt_gen_init(), OP_keymgmt_gen_set_template(),
+OP_keymgmt_gen_set_params(), OP_keymgmt_gen_settable_params(),
+OP_keymgmt_gen() and OP_keymgmt_gen_cleanup() work together as a more
+elaborate context based key object constructor.
+
+OP_keymgmt_gen_init() should create the key object generation context
+and initialize it with I<selections>, which will determine what kind
+of contents the key object to be generated should get.
+
+OP_keymgmt_gen_set_template() should add I<template> to the context
+I<genctx>.  The I<template> is assumed to be a key object constructed
+with the same KEYMGMT, and from which content that the implementation
+chooses can be used as a template for the key object to be generated.
+Typically, the generation of a DSA or DH key would get the domain
+parameters from this I<template>.
+
+OP_keymgmt_gen_set_params() should set additional parameters from
+I<params> in the key object generation context I<genctx>.
+
+OP_keymgmt_gen_settable_params() should return a constant array of
+descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_gen_set_params() 
+can handle.
+
+OP_keymgmt_gen() should perform the key object generation itself, and
+return the result.  The callback I<cb> should be called at regular
+intervals with indications on how the key object generation
+progresses.
+
+OP_keymgmt_gen_cleanup() should clean up and free the key object
+generation context I<genctx>
 
-=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.
+At least one of OP_keymgmt_new() and OP_keymgmt_gen() are mandatory,
+as well as OP_keymgmt_free().  Additionally, if OP_keymgmt_gen() is
+present, OP_keymgmt_gen_init() and OP_keymgmt_gen_cleanup() must be
+present as well.
 
 =head2 Key Object Information Functions
 
index 7da0258..42ac56a 100644 (file)
@@ -636,6 +636,16 @@ int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt,
                            void *keydata, const OSSL_PARAM params[]);
 const OSSL_PARAM *evp_keymgmt_settable_params(const EVP_KEYMGMT *keymgmt);
 
+void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection);
+int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx,
+                                 void *template);
+int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
+                               const OSSL_PARAM params[]);
+const OSSL_PARAM *
+evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt);
+void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
+                      OSSL_CALLBACK *cb, void *cbarg);
+void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx);
 
 int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
 int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
index c650418..dfca646 100644 (file)
@@ -380,10 +380,31 @@ OSSL_CORE_MAKE_FUNC(int, OP_kdf_set_ctx_params,
 # define OSSL_KEYMGMT_SELECT_ALL                \
     ( OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
 
-/* Basic key object creation, destruction */
+/* Basic key object creation */
 # define OSSL_FUNC_KEYMGMT_NEW                         1
-# define OSSL_FUNC_KEYMGMT_FREE                        9
 OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_new, (void *provctx))
+
+/* Generation, a more complex constructor */
+# define OSSL_FUNC_KEYMGMT_GEN_INIT                    3
+# define OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE            4
+# define OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS              5
+# define OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS         6
+# define OSSL_FUNC_KEYMGMT_GEN                         7
+# define OSSL_FUNC_KEYMGMT_GEN_CLEANUP                 8
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_gen_init,
+                    (void *provctx, int selection))
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_gen_set_template,
+                    (void *genctx, void *templ))
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_gen_set_params,
+                    (void *genctx, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,
+                    OP_keymgmt_gen_settable_params, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_gen,
+                    (void *genctx, OSSL_CALLBACK *cb, void *cbarg))
+OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_gen_cleanup, (void *genctx))
+
+/* Basic key object destruction */
+# define OSSL_FUNC_KEYMGMT_FREE                        9
 OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_free, (void *keydata))
 
 /* Key object information, with discovery */