]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
DESERIALIZER: Rethink password handling
authorRichard Levitte <levitte@openssl.org>
Mon, 27 Jul 2020 16:39:58 +0000 (18:39 +0200)
committerPauli <paul.dale@oracle.com>
Sat, 1 Aug 2020 01:51:18 +0000 (11:51 +1000)
The OSSL_DESERIALIZER API makes the incorrect assumption that the
caller must cipher and other pass phrase related parameters to the
individual desserializer implementations, when the reality is that
they only need a passphrase callback, and will be able to figure out
the rest themselves from the input they get.

We simplify it further by never passing any explicit passphrase to the
provider implementation, and simply have them call the passphrase
callback unconditionally when they need, leaving it to libcrypto code
to juggle explicit passphrases, cached passphrases and actual
passphrase callback calls.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12544)

13 files changed:
crypto/serializer/deserializer_lib.c
crypto/serializer/deserializer_meth.c
crypto/serializer/deserializer_pkey.c
crypto/serializer/serdes_pass.c
crypto/serializer/serializer_local.h
doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
include/openssl/deserializer.h
providers/implementations/serializers/deserialize_common.c
providers/implementations/serializers/deserialize_der2rsa.c
providers/implementations/serializers/deserialize_pem2der.c
providers/implementations/serializers/serializer_local.h
test/serdes_test.c
util/libcrypto.num

index 2fbb7782cf2e0af6f3ea9c6b88c53a67c6908d3b..d5401dcda325339c140a89c0ffe4d63168f69b58 100644 (file)
@@ -37,10 +37,11 @@ int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in)
 
     ok = deser_process(NULL, &data);
 
-    /* Clear any cached passphrase */
-    OPENSSL_clear_free(ctx->cached_passphrase, ctx->cached_passphrase_len);
-    ctx->cached_passphrase = NULL;
-    ctx->cached_passphrase_len = 0;
+    /* Clear any internally cached passphrase */
+    if (!ctx->flag_user_passphrase) {
+        OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0);
+        ctx->flag_user_passphrase = 0;
+    }
     return ok;
 }
 
@@ -426,7 +427,7 @@ static int deser_process(const OSSL_PARAM params[], void *arg)
         ok = new_deser->deserialize(new_deser_inst->deserctx,
                                     (OSSL_CORE_BIO *)bio,
                                     deser_process, &new_data,
-                                    NULL /* ossl_deserializer_passphrase_in_cb */,
+                                    ctx->passphrase_cb,
                                     new_data.ctx);
         if (ok)
             break;
index 54500716ecc4a86ca107bd51daa803321a139023..72da57707e7ed9d3c86c450203bfaf17b178315d 100644 (file)
@@ -490,6 +490,7 @@ OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void)
         return NULL;
     }
 
+    ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb;
     return ctx;
 }
 
@@ -542,7 +543,8 @@ void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx)
             ctx->cleaner(ctx->finalize_arg);
         sk_OSSL_DESERIALIZER_INSTANCE_pop_free(ctx->deser_insts,
                                                OSSL_DESERIALIZER_INSTANCE_free);
-        UI_destroy_method(ctx->allocated_ui_method);
+        OSSL_DESERIALIZER_CTX_set_passphrase_ui(ctx, NULL, NULL);
+        OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0);
         OPENSSL_free(ctx);
     }
 }
index 0fafdf31aa39e6cced6b2bf1f7c9cb1da3b079e5..fc77c6f005e1c094cf99eaf9cd5d1e65060c5f34 100644 (file)
 #include <openssl/evp.h>
 #include <openssl/ui.h>
 #include <openssl/deserializer.h>
-#include <openssl/core_names.h>
 #include <openssl/safestack.h>
 #include "crypto/evp.h"
 #include "serializer_local.h"
 
-int OSSL_DESERIALIZER_CTX_set_cipher(OSSL_DESERIALIZER_CTX *ctx,
-                                     const char *cipher_name,
-                                     const char *propquery)
-{
-    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
-
-    params[0] =
-        OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_CIPHER,
-                                         (void *)cipher_name, 0);
-    params[1] =
-        OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_PROPERTIES,
-                                         (void *)propquery, 0);
-
-    return OSSL_DESERIALIZER_CTX_set_params(ctx, params);
-}
-
 int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
                                          const unsigned char *kstr,
                                          size_t klen)
 {
-    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
-
-    params[0] = OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_PASS,
-                                                  (void *)kstr, klen);
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
 
-    return OSSL_DESERIALIZER_CTX_set_params(ctx, params);
+    OPENSSL_clear_free(ctx->cached_passphrase, ctx->cached_passphrase_len);
+    ctx->cached_passphrase = NULL;
+    ctx->cached_passphrase_len = 0;
+    if (kstr != NULL) {
+        if (klen == 0) {
+            ctx->cached_passphrase = OPENSSL_zalloc(1);
+            ctx->cached_passphrase_len = 0;
+        } else {
+            ctx->cached_passphrase = OPENSSL_memdup(kstr, klen);
+            ctx->cached_passphrase_len = klen;
+        }
+        if (ctx->cached_passphrase == NULL) {
+            ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    ctx->flag_user_passphrase = 1;
+    return 1;
 }
 
 static void deserializer_ctx_reset_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx)
@@ -67,27 +67,36 @@ int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
     return 1;
 }
 
-int OSSL_DESERIALIZER_CTX_set_passphrase_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                            pem_password_cb *cb, void *cbarg)
+int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
+                                              pem_password_cb *cb, void *cbarg)
 {
+    UI_METHOD *ui_method = NULL;
+
     if (!ossl_assert(ctx != NULL)) {
         ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
 
-    deserializer_ctx_reset_passphrase_ui(ctx);
-    if (cb == NULL)
+    /*
+     * If |cb| is NULL, it means the caller wants to reset previous
+     * password callback info.  Otherwise, we only set the new data
+     * if a new UI_METHOD could be created for this sort of callback.
+     */
+    if (cb == NULL
+        || (ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) != NULL) {
+        deserializer_ctx_reset_passphrase_ui(ctx);
+        ctx->ui_method = ctx->allocated_ui_method = ui_method;
+        ctx->ui_data = cbarg;
+        ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb;
         return 1;
-    ctx->ui_method =
-        ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0);
-    ctx->ui_data = cbarg;
+    }
 
-    return ctx->ui_method != NULL;
+    return 0;
 }
 
 /*
  * Support for OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY:
- * Handle an object reference
+ * The construct data, and collecting keymgmt information for it
  */
 
 DEFINE_STACK_OF(EVP_KEYMGMT)
index 8a33af5e9a9e49247085ab4f84d35a2bcff83f1b..75200955b59d139020252f1cf1c87fd0f8aae73b 100644 (file)
@@ -48,8 +48,11 @@ static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len,
         return 0;
     }
 
-    UI_set_method(ui, ui_method);
-    UI_add_user_data(ui, ui_data);
+    if (ui_method != NULL) {
+        UI_set_method(ui, ui_method);
+        if (ui_data != NULL)
+            UI_add_user_data(ui, ui_data);
+    }
 
     /* Get an application constructed prompt */
     prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
index acf600c285653596ffbc7761cec5e2b6475540b5..041780124899ff3097736b4384f1874d04be4640 100644 (file)
@@ -103,10 +103,11 @@ struct ossl_deserializer_ctx_st {
     void *finalize_arg;
 
     /* For any function that needs a passphrase reader */
+    OSSL_PASSPHRASE_CALLBACK *passphrase_cb;
     const UI_METHOD *ui_method;
     void *ui_data;
     /*
-     * if caller used OSSL_SERIALIZER_CTX_set_passphrase_cb(), we need
+     * if caller used OSSL_SERIALIZER_CTX_set_pem_password_cb(), we need
      * intermediary storage.
      */
     UI_METHOD *allocated_ui_method;
@@ -117,6 +118,16 @@ struct ossl_deserializer_ctx_st {
      */
     unsigned char *cached_passphrase;
     size_t cached_passphrase_len;
+
+    /*
+     * Flag section.  Keep these together
+     */
+
+    /*
+     * The passphrase was passed to us by the user.  In that case, it
+     * should only be freed when freeing this context.
+     */
+    unsigned int flag_user_passphrase:1;
 };
 
 /* Passphrase callbacks, found in serdes_pass.c */
index 9ed4e5992e9da4a5bd79115772ac49e0e6f30880..c8466657c969d25194750ac566ba4d0a6878b7ab 100644 (file)
@@ -3,9 +3,8 @@
 =head1 NAME
 
 OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY,
-OSSL_DESERIALIZER_CTX_set_cipher,
 OSSL_DESERIALIZER_CTX_set_passphrase,
-OSSL_DESERIALIZER_CTX_set_passphrase_cb,
+OSSL_DESERIALIZER_CTX_set_pem_password_cb,
 OSSL_DESERIALIZER_CTX_set_passphrase_ui
 - Deserializer routines to deserialize EVP_PKEYs
 
@@ -19,14 +18,12 @@ OSSL_DESERIALIZER_CTX_set_passphrase_ui
                                        OPENSSL_CTX *libctx,
                                        const char *propquery);
 
- int OSSL_DESERIALIZER_CTX_set_cipher(OSSL_DESERIALIZER_CTX *ctx,
-                                      const char *cipher_name,
-                                      const char *propquery);
  int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
                                           const unsigned char *kstr,
                                           size_t klen);
- int OSSL_DESERIALIZER_CTX_set_passphrase_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                             pem_password_cb *cb, void *cbarg);
+ int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
+                                               pem_password_cb *cb,
+                                               void *cbarg);
  int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
                                              const UI_METHOD *ui_method,
                                              void *ui_data);
@@ -55,38 +52,35 @@ zero).  This helps the caller distinguish between an error when
 creating the B<OSSL_DESERIALIZER_CTX>, and the lack the deserializer
 support and act accordingly.
 
-OSSL_DESERIALIZER_CTX_set_cipher() tells the implementation what cipher
-should be used to decrypt serialized keys.  The cipher is given by
-name I<cipher_name>.  The interpretation of that I<cipher_name> is
-implementation dependent.  The implementation may implement the cipher
-directly itself, or it may choose to fetch it.  If the implementation
-supports fetching the cipher, then it may use I<propquery> as
-properties to be queried for when fetching.  I<cipher_name> may also
-be NULL, which will result in failure if the serialized input is an
-encrypted key.
-
 OSSL_DESERIALIZER_CTX_set_passphrase() gives the implementation a
 pass phrase to use when decrypting the serialized private key.
 Alternatively, a pass phrase callback may be specified with the
 following functions.
 
-OSSL_DESERIALIZER_CTX_set_passphrase_cb() and
-OSSL_DESERIALIZER_CTX_set_passphrase_ui() sets up a callback method that
-the implementation can use to prompt for a pass phrase.
+OSSL_DESERIALIZER_CTX_set_pem_password_cb() and
+OSSL_DESERIALIZER_CTX_set_passphrase_ui() set up a callback method that
+the implementation can use to prompt for a pass phrase, giving the caller
+the choice of prefered pass phrase callback form.  These are called
+indirectly, through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
+
+The internal B<OSSL_PASSPHRASE_CALLBACK> function caches the pass phrase, to
+be re-used in all deserializations that are performed in the same
+deserialization run
+(for example, within one L<OSSL_DESERIALIZER_from_bio(3)> call).
 
-=for comment Note that the callback method is called indirectly,
-through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
+=for comment the name OSSL_DESERIALIZER_CTX_set_pem_password_cb() leaves
+open the future possibility of having a function where the caller can set a
+B<OSSL_PASSPHRASE_CALLBACK> method as another option.
 
 =head1 RETURN VALUES
 
 OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() returns a pointer to a
 B<OSSL_DESERIALIZER_CTX>, or NULL if it couldn't be created.
 
-OSSL_DESERIALIZER_CTX_set_cipher(),
 OSSL_DESERIALIZER_CTX_set_passphrase(),
-OSSL_DESERIALIZER_CTX_set_passphrase_cb(), and
-OSSL_DESERIALIZER_CTX_set_passphrase_ui() all return 1 on success, or 0
-on failure.
+OSSL_DESERIALIZER_CTX_set_pem_password_cb() and
+OSSL_DESERIALIZER_CTX_set_passphrase_ui()
+all return 1 on success, or 0 on failure.
 
 =head1 NOTES
 
index d54e47915da20db908f3042f148b0ffefde2dcbd..7ac74960666c946c6f211d168c77f38a08391833 100644 (file)
@@ -55,14 +55,12 @@ int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
 void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx);
 
 /* Utilities that help set specific parameters */
-int OSSL_DESERIALIZER_CTX_set_cipher(OSSL_DESERIALIZER_CTX *ctx,
-                                     const char *cipher_name,
-                                     const char *propquery);
 int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
                                          const unsigned char *kstr,
                                          size_t klen);
-int OSSL_DESERIALIZER_CTX_set_passphrase_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                            pem_password_cb *cb, void *cbarg);
+int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
+                                              pem_password_cb *cb,
+                                              void *cbarg);
 int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
                                             const UI_METHOD *ui_method,
                                             void *ui_data);
index 449d57b0a330c7d58872ae7f8e3e5758882c5837..1a9d3d4a7774263a6ac198efbb786f6c706089b2 100644 (file)
@@ -47,7 +47,7 @@ int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
 
 int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
                           unsigned char *input_der, long input_der_len,
-                          struct pkcs8_encrypt_ctx_st *ctx)
+                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
     const unsigned char *derp;
     X509_SIG *p8 = NULL;
@@ -57,30 +57,20 @@ int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
         || !ossl_assert(new_der_len != NULL))
         return 0;
 
-    if (ctx->cipher == NULL)
-        return 0;
-
     derp = input_der;
     if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
         char pbuf[PEM_BUFSIZE];
-        const void *pstr = ctx->cipher_pass;
-        size_t plen = ctx->cipher_pass_length;
-
-        if (pstr == NULL) {
-            pstr = pbuf;
-            if (!ctx->cb(pbuf, sizeof(pbuf), &plen, NULL, ctx->cbarg)) {
-                ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
-                pstr = NULL;
-            }
-        }
+        size_t plen = 0;
 
-        if (pstr != NULL) {
+        if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
+        } else {
             const X509_ALGOR *alg = NULL;
             const ASN1_OCTET_STRING *oct = NULL;
             int len = 0;
 
             X509_SIG_get0(p8, &alg, &oct);
-            if (PKCS12_pbe_crypt(alg, pstr, plen, oct->data, oct->length,
+            if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
                                  new_der, &len, 0) != NULL)
                 ok = 1;
             *new_der_len = len;
index 75066546ba8ed0510e50e089592bf670deb2eefd..80be281ec9431e8471cfbea5d38293581edbfa4c 100644 (file)
@@ -28,8 +28,6 @@ static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx;
 static OSSL_FUNC_deserializer_freectx_fn der2rsa_freectx;
 static OSSL_FUNC_deserializer_gettable_params_fn der2rsa_gettable_params;
 static OSSL_FUNC_deserializer_get_params_fn der2rsa_get_params;
-static OSSL_FUNC_deserializer_settable_ctx_params_fn der2rsa_settable_ctx_params;
-static OSSL_FUNC_deserializer_set_ctx_params_fn der2rsa_set_ctx_params;
 static OSSL_FUNC_deserializer_deserialize_fn der2rsa_deserialize;
 static OSSL_FUNC_deserializer_export_object_fn der2rsa_export_object;
 
@@ -40,19 +38,14 @@ struct der2rsa_ctx_st {
     PROV_CTX *provctx;
 
     int type;
-
-    struct pkcs8_encrypt_ctx_st sc;
 };
 
 static struct der2rsa_ctx_st *der2rsa_newctx_int(void *provctx)
 {
     struct der2rsa_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
 
-    if (ctx != NULL) {
+    if (ctx != NULL)
         ctx->provctx = provctx;
-        /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
-        ctx->sc.pbe_nid = -1;
-    }
     return ctx;
 }
 
@@ -76,11 +69,7 @@ static void *der2rsapss_newctx(void *provctx)
 
 static void der2rsa_freectx(void *vctx)
 {
-    struct der2rsa_ctx_st *ctx = vctx;
-
-    EVP_CIPHER_free(ctx->sc.cipher);
-    OPENSSL_clear_free(ctx->sc.cipher_pass, ctx->sc.cipher_pass_length);
-    OPENSSL_free(ctx);
+    OPENSSL_free(vctx);
 }
 
 static const OSSL_PARAM *der2rsa_gettable_params(void)
@@ -104,56 +93,6 @@ static int der2rsa_get_params(OSSL_PARAM params[])
     return 1;
 }
 
-
-static const OSSL_PARAM *der2rsa_settable_ctx_params(void)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_DESERIALIZER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_DESERIALIZER_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_DESERIALIZER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int der2rsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct der2rsa_ctx_st *ctx = vctx;
-    OPENSSL_CTX *libctx = PROV_CTX_get0_library_context(ctx->provctx);
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_CIPHER))
-        != NULL) {
-        const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_PROPERTIES);
-        const char *props = NULL;
-
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        props = (propsp != NULL ? propsp->data : NULL);
-
-        EVP_CIPHER_free(ctx->sc.cipher);
-        ctx->sc.cipher = NULL;
-        ctx->sc.cipher_intent = p->data != NULL;
-        if (p->data != NULL
-            && ((ctx->sc.cipher = EVP_CIPHER_fetch(libctx, p->data, props))
-                == NULL))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_PASS))
-        != NULL) {
-        OPENSSL_clear_free(ctx->sc.cipher_pass, ctx->sc.cipher_pass_length);
-        ctx->sc.cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
-                                         &ctx->sc.cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
 static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
                                OSSL_CALLBACK *data_cb, void *data_cbarg,
                                OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
@@ -169,9 +108,6 @@ static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
     EVP_PKEY *pkey = NULL;
     int ok = 0;
 
-    ctx->sc.cb = pw_cb;
-    ctx->sc.cbarg = pw_cbarg;
-
     if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len))
         return 0;
 
@@ -179,9 +115,8 @@ static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
      * Opportunistic attempt to decrypt.  If it doesn't work, we try to
      * decode our input unencrypted.
      */
-    if (ctx->sc.cipher_intent
-        && ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len,
-                                 &ctx->sc)) {
+    if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len,
+                              pw_cb, pw_cbarg)) {
         OPENSSL_free(der);
         der = new_der;
         der_len = new_der_len;
@@ -279,10 +214,6 @@ const OSSL_DISPATCH der_to_rsa_deserializer_functions[] = {
       (void (*)(void))der2rsa_gettable_params },
     { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
       (void (*)(void))der2rsa_get_params },
-    { OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))der2rsa_settable_ctx_params },
-    { OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS,
-      (void (*)(void))der2rsa_set_ctx_params },
     { OSSL_FUNC_DESERIALIZER_DESERIALIZE,
       (void (*)(void))der2rsa_deserialize },
     { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,
@@ -297,10 +228,6 @@ const OSSL_DISPATCH der_to_rsapss_deserializer_functions[] = {
       (void (*)(void))der2rsa_gettable_params },
     { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
       (void (*)(void))der2rsa_get_params },
-    { OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))der2rsa_settable_ctx_params },
-    { OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS,
-      (void (*)(void))der2rsa_set_ctx_params },
     { OSSL_FUNC_DESERIALIZER_DESERIALIZE,
       (void (*)(void))der2rsa_deserialize },
     { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,
index a46ec681a10bec027255b00a8a2e93c8c2e47fbf..cbd0867da995cd8b5c5dada9100c38c4b5b8e6f2 100644 (file)
@@ -37,19 +37,6 @@ static OSSL_FUNC_deserializer_deserialize_fn pem2der_deserialize;
  */
 struct pem2der_ctx_st {
     PROV_CTX *provctx;
-
-    /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
-    int cipher_intent;
-
-    EVP_CIPHER *cipher;
-
-    /* Passphrase that was passed by the caller */
-    void *cipher_pass;
-    size_t cipher_pass_length;
-
-    /* This callback is only used if |cipher_pass| is NULL */
-    OSSL_PASSPHRASE_CALLBACK *cb;
-    void *cbarg;
 };
 
 static void *pem2der_newctx(void *provctx)
@@ -65,8 +52,6 @@ static void pem2der_freectx(void *vctx)
 {
     struct pem2der_ctx_st *ctx = vctx;
 
-    EVP_CIPHER_free(ctx->cipher);
-    OPENSSL_clear_free(ctx->cipher_pass, ctx->cipher_pass_length);
     OPENSSL_free(ctx);
 }
 
@@ -91,50 +76,22 @@ static int pem2der_get_params(OSSL_PARAM params[])
     return 1;
 }
 
-static const OSSL_PARAM *pem2der_settable_ctx_params(void)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_octet_string(OSSL_DESERIALIZER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int pem2der_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct pem2der_ctx_st *ctx = vctx;
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_PASS))
-        != NULL) {
-        OPENSSL_clear_free(ctx->cipher_pass, ctx->cipher_pass_length);
-        ctx->cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->cipher_pass, 0,
-                                         &ctx->cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
 /* pem_password_cb compatible function */
+struct pem2der_pass_data_st {
+    OSSL_PASSPHRASE_CALLBACK *cb;
+    void *cbarg;
+};
+
 static int pem2der_pass_helper(char *buf, int num, int w, void *data)
 {
-    struct pem2der_ctx_st *ctx = data;
+    struct pem2der_pass_data_st *pass_data = data;
     size_t plen;
 
-    if (ctx->cipher_pass != NULL) {
-        if (ctx->cipher_pass_length < (size_t)num - 1) {
-            strncpy(buf, ctx->cipher_pass, ctx->cipher_pass_length);
-            buf[ctx->cipher_pass_length] = '\0';
-        } else {
-            OPENSSL_strlcpy(buf, ctx->cipher_pass, num);
-        }
-    } else if (ctx->cb == NULL
-               || !ctx->cb(buf, num, &plen, NULL, ctx->cbarg)) {
+    if (pass_data == NULL
+        || pass_data->cb == NULL
+        || !pass_data->cb(buf, num, &plen, NULL, pass_data->cbarg))
         return -1;
-    }
-    return (int)ctx->cipher_pass_length;
+    return (int)plen;
 }
 
 static int pem2der_deserialize(void *vctx, OSSL_CORE_BIO *cin,
@@ -159,9 +116,13 @@ static int pem2der_deserialize(void *vctx, OSSL_CORE_BIO *cin,
      */
     if (strlen(pem_header) > 10) {
         EVP_CIPHER_INFO cipher;
+        struct pem2der_pass_data_st pass_data;
 
+        pass_data.cb = pw_cb;
+        pass_data.cbarg = pw_cbarg;
         if (!PEM_get_EVP_CIPHER_INFO(pem_header, &cipher)
-            || !PEM_do_header(&cipher, der, &der_len, pem2der_pass_helper, ctx))
+            || !PEM_do_header(&cipher, der, &der_len,
+                              pem2der_pass_helper, &pass_data))
             goto end;
     }
 
@@ -193,10 +154,6 @@ const OSSL_DISPATCH pem_to_der_deserializer_functions[] = {
       (void (*)(void))pem2der_gettable_params },
     { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
       (void (*)(void))pem2der_get_params },
-    { OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))pem2der_settable_ctx_params },
-    { OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS,
-      (void (*)(void))pem2der_set_ctx_params },
     { OSSL_FUNC_DESERIALIZER_DESERIALIZE, (void (*)(void))pem2der_deserialize },
     { 0, NULL }
 };
index f1d2fe743c6e2f6a8c0c8ac277f05c00ed82b635..d1359f7f4d9c4c4526a943102895f03915e2dbf8 100644 (file)
@@ -170,5 +170,5 @@ int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
 
 int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
                           unsigned char *input_der, long input_der_len,
-                          struct pkcs8_encrypt_ctx_st *ctx);
+                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
 
index 0fc5cb7b4dfcf7f456bcc54014566ed0fa1a8b4b..d5ba3940e90cfd9168faddb9c1584431ac9b9de3 100644 (file)
@@ -55,13 +55,19 @@ static EVP_PKEY *make_RSA(const char *rsa_type, int make_legacy)
 
 /* Main test driver */
 
+/*
+ * TODO(3.0) For better error output, changed the callbacks to take __FILE__
+ * and __LINE__ as first two arguments, and have them use the lower case
+ * functions, such as test_strn_eq(), rather than the uppercase macros
+ * (TEST_strn2_eq(), for example).
+ */
+
 typedef int (serializer)(void **serialized, long *serialized_len,
-                         void *object,
-                         const char *pass, const char *pcipher,
+                         void *object, const char *pass, const char *pcipher,
                          const char *ser_propq);
 typedef int (deserializer)(void **object,
                            void *serialized, long serialized_len,
-                           const char *pass, const char *pcipher);
+                           const char *pass);
 typedef int (checker)(const char *type, const void *data, size_t data_len);
 typedef void (dumper)(const char *label, const void *data, size_t data_len);
 
@@ -83,7 +89,7 @@ static int test_serialize_deserialize(const char *type, EVP_PKEY *pkey,
                       pass, pcipher, ser_propq)
         || !check_cb(type, serialized, serialized_len)
         || !deserialize_cb((void **)&pkey2, serialized, serialized_len,
-                           pass, pcipher)
+                           pass)
         || !TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
         goto end;
 
@@ -157,7 +163,7 @@ static int serialize_EVP_PKEY_prov(void **serialized, long *serialized_len,
 
 static int deserialize_EVP_PKEY_prov(void **object,
                                      void *serialized, long serialized_len,
-                                     const char *pass, const char *pcipher)
+                                     const char *pass)
 {
     EVP_PKEY *pkey = NULL;
     OSSL_DESERIALIZER_CTX *dctx = NULL;
@@ -170,8 +176,6 @@ static int deserialize_EVP_PKEY_prov(void **object,
         || (pass != NULL
             && !OSSL_DESERIALIZER_CTX_set_passphrase(dctx, upass,
                                                      strlen(pass)))
-        || (pcipher != NULL
-            && !OSSL_DESERIALIZER_CTX_set_cipher(dctx, pcipher, NULL))
         || !TEST_ptr(mem_deser = BIO_new_mem_buf(serialized, serialized_len))
         || !TEST_true(OSSL_DESERIALIZER_from_bio(dctx, mem_deser)))
         goto end;
index 1a59d816249fd79b44c7a99373ceaaf52a80abb7..11f230ae1cff39baff1e007aced4ca4b79cedf8c 100644 (file)
@@ -5163,9 +5163,8 @@ OSSL_DESERIALIZER_settable_ctx_params   ? 3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_CTX_new               ?      3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_CTX_set_params        ?      3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_CTX_free              ?      3_0_0   EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_cipher        ?      3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_CTX_set_passphrase    ?      3_0_0   EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_passphrase_cb ?      3_0_0   EXIST::FUNCTION:
+OSSL_DESERIALIZER_CTX_set_pem_password_cb ?    3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_CTX_set_passphrase_ui ?      3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_from_bio              ?      3_0_0   EXIST::FUNCTION:
 OSSL_DESERIALIZER_from_fp               ?      3_0_0   EXIST::FUNCTION:STDIO