summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-07-27 18:39:58 +0200
committerPauli <paul.dale@oracle.com>2020-08-01 11:51:18 +1000
commit4701f0a9a0ff08b354142c9f3b4797ff225d7c84 (patch)
tree2fa4c9cc64badbf7499b41e9f333dcc95c1a53a5
parenta6495479adfb8dc0b500030d4eeb007d9af4572a (diff)
DESERIALIZER: Rethink password handling
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)
-rw-r--r--crypto/serializer/deserializer_lib.c11
-rw-r--r--crypto/serializer/deserializer_meth.c4
-rw-r--r--crypto/serializer/deserializer_pkey.c71
-rw-r--r--crypto/serializer/serdes_pass.c7
-rw-r--r--crypto/serializer/serializer_local.h13
-rw-r--r--doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod46
-rw-r--r--include/openssl/deserializer.h8
-rw-r--r--providers/implementations/serializers/deserialize_common.c22
-rw-r--r--providers/implementations/serializers/deserialize_der2rsa.c81
-rw-r--r--providers/implementations/serializers/deserialize_pem2der.c73
-rw-r--r--providers/implementations/serializers/serializer_local.h2
-rw-r--r--test/serdes_test.c18
-rw-r--r--util/libcrypto.num3
13 files changed, 127 insertions, 232 deletions
diff --git a/crypto/serializer/deserializer_lib.c b/crypto/serializer/deserializer_lib.c
index 2fbb7782cf..d5401dcda3 100644
--- a/crypto/serializer/deserializer_lib.c
+++ b/crypto/serializer/deserializer_lib.c
@@ -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;
diff --git a/crypto/serializer/deserializer_meth.c b/crypto/serializer/deserializer_meth.c
index 54500716ec..72da57707e 100644
--- a/crypto/serializer/deserializer_meth.c
+++ b/crypto/serializer/deserializer_meth.c
@@ -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);
}
}
diff --git a/crypto/serializer/deserializer_pkey.c b/crypto/serializer/deserializer_pkey.c
index 0fafdf31aa..fc77c6f005 100644
--- a/crypto/serializer/deserializer_pkey.c
+++ b/crypto/serializer/deserializer_pkey.c
@@ -11,37 +11,37 @@
#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)
diff --git a/crypto/serializer/serdes_pass.c b/crypto/serializer/serdes_pass.c
index 8a33af5e9a..75200955b5 100644
--- a/crypto/serializer/serdes_pass.c
+++ b/crypto/serializer/serdes_pass.c
@@ -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);
diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h
index acf600c285..0417801248 100644
--- a/crypto/serializer/serializer_local.h
+++ b/crypto/serializer/serializer_local.h
@@ -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 */
diff --git a/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
index 9ed4e5992e..c8466657c9 100644
--- a/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
+++ b/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
@@ -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
diff --git a/include/openssl/deserializer.h b/include/openssl/deserializer.h
index d54e47915d..7ac7496066 100644
--- a/include/openssl/deserializer.h
+++ b/include/openssl/deserializer.h
@@ -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);
diff --git a/providers/implementations/serializers/deserialize_common.c b/providers/implementations/serializers/deserialize_common.c
index 449d57b0a3..1a9d3d4a77 100644
--- a/providers/implementations/serializers/deserialize_common.c
+++ b/providers/implementations/serializers/deserialize_common.c
@@ -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;
diff --git a/providers/implementations/serializers/deserialize_der2rsa.c b/providers/implementations/serializers/deserialize_der2rsa.c
index 75066546ba..80be281ec9 100644
--- a/providers/implementations/serializers/deserialize_der2rsa.c
+++ b/providers/implementations/serializers/deserialize_der2rsa.c
@@ -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,
diff --git a/providers/implementations/serializers/deserialize_pem2der.c b/providers/implementations/serializers/deserialize_pem2der.c
index a46ec681a1..cbd0867da9 100644
--- a/providers/implementations/serializers/deserialize_pem2der.c
+++ b/providers/implementations/serializers/deserialize_pem2der.c
@@ -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 }
};
diff --git a/providers/implementations/serializers/serializer_local.h b/providers/implementations/serializers/serializer_local.h
index f1d2fe743c..d1359f7f4d 100644
--- a/providers/implementations/serializers/serializer_local.h
+++ b/providers/implementations/serializers/serializer_local.h
@@ -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);
diff --git a/test/serdes_test.c b/test/serdes_test.c
index 0fc5cb7b4d..d5ba3940e9 100644
--- a/test/serdes_test.c
+++ b/test/serdes_test.c
@@ -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;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 1a59d81624..11f230ae1c 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -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