summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/store/store_result.c2
-rw-r--r--providers/implementations/storemgmt/build.info2
-rw-r--r--providers/implementations/storemgmt/file_store.c52
-rw-r--r--providers/implementations/storemgmt/file_store_any2obj.c261
-rw-r--r--providers/implementations/storemgmt/file_store_der2obj.c109
-rw-r--r--providers/implementations/storemgmt/file_store_local.h2
6 files changed, 289 insertions, 139 deletions
diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c
index 91c679718c..3a0dc9dfba 100644
--- a/crypto/store/store_result.c
+++ b/crypto/store/store_result.c
@@ -268,7 +268,7 @@ static EVP_PKEY *try_key_value(struct extracted_param_data_st *data,
}
decoderctx =
- OSSL_DECODER_CTX_new_for_pkey(&pk, "DER", data->data_structure,
+ OSSL_DECODER_CTX_new_for_pkey(&pk, NULL, data->data_structure,
data->data_type, selection, libctx,
propq);
(void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg);
diff --git a/providers/implementations/storemgmt/build.info b/providers/implementations/storemgmt/build.info
index ad47fb1fe8..8e6445a4e7 100644
--- a/providers/implementations/storemgmt/build.info
+++ b/providers/implementations/storemgmt/build.info
@@ -3,4 +3,4 @@
$STORE_GOAL=../../libdefault.a
-SOURCE[$STORE_GOAL]=file_store.c file_store_der2obj.c
+SOURCE[$STORE_GOAL]=file_store.c file_store_any2obj.c
diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c
index 02d0e29502..6ccda2b33f 100644
--- a/providers/implementations/storemgmt/file_store.c
+++ b/providers/implementations/storemgmt/file_store.c
@@ -420,8 +420,7 @@ void file_load_cleanup(void *construct_data)
static int file_setup_decoders(struct file_ctx_st *ctx)
{
OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx);
- OSSL_DECODER *to_obj = NULL; /* Last resort decoder */
- OSSL_DECODER_INSTANCE *to_obj_inst = NULL;
+ const OSSL_ALGORITHM *to_algo = NULL;
int ok = 0;
/* Setup for this session, so only if not already done */
@@ -438,32 +437,32 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
goto err;
}
- /*
- * Create the internal last resort decoder implementation together
- * with a "decoder instance".
- * The decoder doesn't need any identification or to be attached to
- * any provider, since it's only used locally.
- */
- to_obj = ossl_decoder_from_algorithm(0, &ossl_der_to_obj_algorithm,
- NULL);
- if (to_obj == NULL)
- goto err;
- to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx);
- if (to_obj_inst == NULL)
- goto err;
+ for (to_algo = ossl_any_to_obj_algorithm;
+ to_algo->algorithm_names != NULL;
+ to_algo++) {
+ OSSL_DECODER *to_obj = NULL;
+ OSSL_DECODER_INSTANCE *to_obj_inst = NULL;
- if (!ossl_decoder_ctx_add_decoder_inst(ctx->_.file.decoderctx,
- to_obj_inst)) {
- ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
- goto err;
+ /*
+ * Create the internal last resort decoder implementation
+ * together with a "decoder instance".
+ * The decoder doesn't need any identification or to be
+ * attached to any provider, since it's only used locally.
+ */
+ to_obj = ossl_decoder_from_algorithm(0, to_algo, NULL);
+ if (to_obj != NULL)
+ to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx);
+ OSSL_DECODER_free(to_obj);
+ if (to_obj_inst == NULL)
+ goto err;
+
+ if (!ossl_decoder_ctx_add_decoder_inst(ctx->_.file.decoderctx,
+ to_obj_inst)) {
+ ossl_decoder_instance_free(to_obj_inst);
+ ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
+ goto err;
+ }
}
-
- /*
- * OSSL_DECODER_INSTANCE shouldn't be freed from this point on.
- * That's going to happen whenever the OSSL_DECODER_CTX is freed.
- */
- to_obj_inst = NULL;
-
/* Add on the usual extra decoders */
if (!OSSL_DECODER_CTX_add_extra(ctx->_.file.decoderctx,
libctx, ctx->_.file.propq)) {
@@ -486,7 +485,6 @@ static int file_setup_decoders(struct file_ctx_st *ctx)
ok = 1;
err:
- OSSL_DECODER_free(to_obj);
return ok;
}
diff --git a/providers/implementations/storemgmt/file_store_any2obj.c b/providers/implementations/storemgmt/file_store_any2obj.c
new file mode 100644
index 0000000000..28601683bf
--- /dev/null
+++ b/providers/implementations/storemgmt/file_store_any2obj.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2020-2021 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
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This is a decoder that's completely internal to the 'file:' store
+ * implementation. Only code in file_store.c know about this one. Because
+ * of this close relationship, we can cut certain corners, such as making
+ * assumptions about the "provider context", which is currently simply the
+ * provider context that the file_store.c code operates within.
+ *
+ * All this does is to read known binary encodings (currently: DER, MSBLOB,
+ * PVK) from the input if it can, and passes it on to the data callback as
+ * an object abstraction, leaving it to the callback to figure out what it
+ * actually is.
+ *
+ * This MUST be made the last decoder in a chain, leaving it to other more
+ * specialized decoders to recognise and process their stuff first.
+ */
+
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/core_object.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/asn1err.h>
+#include <openssl/params.h>
+#include "internal/asn1.h"
+#include "crypto/pem.h" /* For internal PVK and "blob" headers */
+#include "prov/bio.h"
+#include "file_store_local.h"
+
+/*
+ * newctx and freectx are not strictly necessary. However, the method creator,
+ * ossl_decoder_from_algorithm(), demands that they exist, so we make sure to
+ * oblige.
+ */
+
+static OSSL_FUNC_decoder_newctx_fn any2obj_newctx;
+static OSSL_FUNC_decoder_freectx_fn any2obj_freectx;
+
+static void *any2obj_newctx(void *provctx)
+{
+ return provctx;
+}
+
+static void any2obj_freectx(void *vctx)
+{
+}
+
+static int any2obj_decode_final(void *provctx, int objtype, BUF_MEM *mem,
+ OSSL_CALLBACK *data_cb, void *data_cbarg)
+{
+ /*
+ * 1 indicates that we successfully decoded something, or not at all.
+ * Ending up "empty handed" is not an error.
+ */
+ int ok = 1;
+
+ if (mem != NULL) {
+ OSSL_PARAM params[3];
+
+ params[0] =
+ OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
+ params[1] =
+ OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
+ mem->data, mem->length);
+ params[2] = OSSL_PARAM_construct_end();
+
+ ok = data_cb(params, data_cbarg);
+ BUF_MEM_free(mem);
+ }
+ return ok;
+}
+
+static OSSL_FUNC_decoder_decode_fn der2obj_decode;
+static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
+ OSSL_CALLBACK *data_cb, void *data_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+ BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
+ BUF_MEM *mem = NULL;
+ int ok;
+
+ if (in == NULL)
+ return 0;
+
+ ERR_set_mark();
+ ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+ ERR_pop_to_mark();
+ if (!ok && mem != NULL) {
+ BUF_MEM_free(mem);
+ mem = NULL;
+ }
+ BIO_free(in);
+
+ /* any2obj_decode_final() frees |mem| for us */
+ return any2obj_decode_final(provctx, OSSL_OBJECT_UNKNOWN, mem,
+ data_cb, data_cbarg);
+}
+
+static OSSL_FUNC_decoder_decode_fn msblob2obj_decode;
+static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
+ OSSL_CALLBACK *data_cb, void *data_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+ BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
+ BUF_MEM *mem = NULL;
+ size_t mem_len = 0, mem_want;
+ const unsigned char *p;
+ unsigned int bitlen, magic;
+ int isdss = -1;
+ int ispub = -1;
+ int ok = 0;
+
+ if (in == NULL)
+ goto err;
+
+ mem_want = 16; /* The size of the MSBLOB header */
+ if ((mem = BUF_MEM_new()) == NULL
+ || !BUF_MEM_grow(mem, mem_want)) {
+ ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ERR_set_mark();
+ ok = BIO_read(in, &mem->data[0], mem_want) == (int)mem_want;
+ mem_len += mem_want;
+ ERR_pop_to_mark();
+ if (!ok)
+ goto next;
+
+
+ ERR_set_mark();
+ p = (unsigned char *)&mem->data[0];
+ ok = ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) > 0;
+ ERR_pop_to_mark();
+ if (!ok)
+ goto next;
+
+ ok = 0;
+ mem_want = ossl_blob_length(bitlen, isdss, ispub);
+ if (!BUF_MEM_grow(mem, mem_len + mem_want)) {
+ ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ERR_set_mark();
+ ok = BIO_read(in, &mem->data[mem_len], mem_want) == (int)mem_want;
+ mem_len += mem_want;
+ ERR_pop_to_mark();
+
+ next:
+ /* Free resources we no longer need. */
+ BIO_free(in);
+ if (!ok && mem != NULL) {
+ BUF_MEM_free(mem);
+ mem = NULL;
+ }
+
+ /* any2obj_decode_final() frees |mem| for us */
+ return any2obj_decode_final(provctx, OSSL_OBJECT_PKEY, mem,
+ data_cb, data_cbarg);
+
+ err:
+ BIO_free(in);
+ BUF_MEM_free(mem);
+ return 0;
+}
+
+static OSSL_FUNC_decoder_decode_fn pvk2obj_decode;
+static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
+ OSSL_CALLBACK *data_cb, void *data_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+ BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
+ BUF_MEM *mem = NULL;
+ size_t mem_len = 0, mem_want;
+ const unsigned char *p;
+ unsigned int saltlen, keylen;
+ int ok = 0;
+
+ if (in == NULL)
+ goto err;
+
+ mem_want = 24; /* The size of the PVK header */
+ if ((mem = BUF_MEM_new()) == NULL
+ || !BUF_MEM_grow(mem, mem_want)) {
+ ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ERR_set_mark();
+ ok = BIO_read(in, &mem->data[0], mem_want) == (int)mem_want;
+ mem_len += mem_want;
+ ERR_pop_to_mark();
+ if (!ok)
+ goto next;
+
+
+ ERR_set_mark();
+ p = (unsigned char *)&mem->data[0];
+ ok = ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen) > 0;
+ ERR_pop_to_mark();
+ if (!ok)
+ goto next;
+
+ ok = 0;
+ mem_want = saltlen + keylen;
+ if (!BUF_MEM_grow(mem, mem_len + mem_want)) {
+ ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ERR_set_mark();
+ ok = BIO_read(in, &mem->data[mem_len], mem_want) == (int)mem_want;
+ mem_len += mem_want;
+ ERR_pop_to_mark();
+
+ next:
+ /* Free resources we no longer need. */
+ BIO_free(in);
+ if (!ok && mem != NULL) {
+ BUF_MEM_free(mem);
+ mem = NULL;
+ }
+
+ /* any2obj_decode_final() frees |mem| for us */
+ return any2obj_decode_final(provctx, OSSL_OBJECT_PKEY, mem,
+ data_cb, data_cbarg);
+
+ err:
+ BIO_free(in);
+ BUF_MEM_free(mem);
+ return 0;
+}
+
+#define MAKE_DECODER(fromtype, objtype) \
+ static const OSSL_DISPATCH fromtype##_to_obj_decoder_functions[] = { \
+ { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))any2obj_newctx }, \
+ { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))any2obj_freectx }, \
+ { OSSL_FUNC_DECODER_DECODE, (void (*)(void))fromtype##2obj_decode }, \
+ { 0, NULL } \
+ }
+
+MAKE_DECODER(der, OSSL_OBJECT_UNKNOWN);
+MAKE_DECODER(msblob, OSSL_OBJECT_PKEY);
+MAKE_DECODER(pvk, OSSL_OBJECT_PKEY);
+
+const OSSL_ALGORITHM ossl_any_to_obj_algorithm[] = {
+ { "obj", "input=DER", der_to_obj_decoder_functions },
+ { "obj", "input=MSBLOB", msblob_to_obj_decoder_functions },
+ { "obj", "input=PVK", pvk_to_obj_decoder_functions },
+ { NULL, }
+};
diff --git a/providers/implementations/storemgmt/file_store_der2obj.c b/providers/implementations/storemgmt/file_store_der2obj.c
deleted file mode 100644
index 5f71ea500d..0000000000
--- a/providers/implementations/storemgmt/file_store_der2obj.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2020-2021 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
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * This is a decoder that's completely internal to the 'file:' store
- * implementation. Only code in file_store.c know about this one. Because
- * of this close relationship, we can cut certain corners, such as making
- * assumptions about the "provider context", which is currently simply the
- * provider context that the file_store.c code operates within.
- *
- * All this does is to read DER from the input if it can, and passes it on
- * to the data callback as an object abstraction, leaving it to the callback
- * to figure out what it actually is.
- *
- * This MUST be made the last decoder in a chain, leaving it to other more
- * specialized decoders to recognise and process their stuff first.
- */
-
-#include <openssl/core_dispatch.h>
-#include <openssl/core_names.h>
-#include <openssl/core_object.h>
-#include <openssl/bio.h>
-#include <openssl/buffer.h>
-#include <openssl/err.h>
-#include <openssl/asn1err.h>
-#include <openssl/params.h>
-#include "internal/asn1.h"
-#include "prov/bio.h"
-#include "file_store_local.h"
-
-/*
- * newctx and freectx are not strictly necessary. However, the method creator,
- * ossl_decoder_from_algorithm(), demands that they exist, so we make sure to
- * oblige.
- */
-
-static OSSL_FUNC_decoder_newctx_fn der2obj_newctx;
-static OSSL_FUNC_decoder_freectx_fn der2obj_freectx;
-
-static void *der2obj_newctx(void *provctx)
-{
- return provctx;
-}
-
-static void der2obj_freectx(void *vctx)
-{
-}
-
-static OSSL_FUNC_decoder_decode_fn der2obj_decode;
-
-static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
- OSSL_CALLBACK *data_cb, void *data_cbarg,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
-{
- /*
- * We're called from file_store.c, so we know that OSSL_CORE_BIO is a
- * BIO in this case.
- */
- BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
- BUF_MEM *mem = NULL;
- int ok;
-
- if (in == NULL)
- return 0;
-
- ERR_set_mark();
- ok = (asn1_d2i_read_bio(in, &mem) >= 0);
- ERR_pop_to_mark();
- if (!ok && mem != NULL) {
- OPENSSL_free(mem->data);
- OPENSSL_free(mem);
- mem = NULL;
- }
-
- ok = 1;
- if (mem != NULL) {
- OSSL_PARAM params[3];
- int object_type = OSSL_OBJECT_UNKNOWN;
-
- params[0] =
- OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
- params[1] =
- OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
- mem->data, mem->length);
- params[2] = OSSL_PARAM_construct_end();
-
- ok = data_cb(params, data_cbarg);
- OPENSSL_free(mem->data);
- OPENSSL_free(mem);
- }
- BIO_free(in);
- return ok;
-}
-
-static const OSSL_DISPATCH der_to_obj_decoder_functions[] = {
- { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))der2obj_newctx },
- { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))der2obj_freectx },
- { OSSL_FUNC_DECODER_DECODE, (void (*)(void))der2obj_decode },
- { 0, NULL }
-};
-
-const OSSL_ALGORITHM ossl_der_to_obj_algorithm =
- { "obj", "input=DER", der_to_obj_decoder_functions };
diff --git a/providers/implementations/storemgmt/file_store_local.h b/providers/implementations/storemgmt/file_store_local.h
index b25dacc18b..3459315948 100644
--- a/providers/implementations/storemgmt/file_store_local.h
+++ b/providers/implementations/storemgmt/file_store_local.h
@@ -7,5 +7,5 @@
* https://www.openssl.org/source/license.html
*/
-extern const OSSL_ALGORITHM ossl_der_to_obj_algorithm;
+extern const OSSL_ALGORITHM ossl_any_to_obj_algorithm[];