{ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
{ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"},
{ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"},
+ {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, 0), "DESERIALIZER routines"},
{ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"},
{0, NULL},
};
L PROP include/internal/property.h crypto/property/property_err.c
L PROV providers/common/include/prov/providercommon.h providers/common/provider_err.c
L OSSL_SERIALIZER include/openssl/serializer.h crypto/serializer/serializer_err.c
+L OSSL_DESERIALIZER include/openssl/deserializer.h crypto/serializer/deserializer_err.c
L HTTP include/openssl/http.h crypto/http/http_err.c
# additional header files to be scanned for function names
OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest
OCSP_R_UNKNOWN_NID:120:unknown nid
OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type
+OSSL_DESERIALIZER_R_MISSING_GET_PARAMS:100:missing get params
OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query
OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND:101:serializer not found
OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type
"fips", /* FIPS validated or FIPS supporting algorithm */
"format", /* output format for serializers */
"type", /* output type for serializers */
+ "input", /* input type for deserializers */
};
size_t i;
-SOURCE[../../libcrypto]=serializer_meth.c serializer_lib.c serializer_pkey.c \
- serializer_err.c
+SOURCE[../../libcrypto]=serializer_meth.c serializer_lib.c serializer_pkey.c
+SOURCE[../../libcrypto]=deserializer_meth.c deserializer_lib.c
+
+SOURCE[../../libcrypto]=serializer_err.c
+SOURCE[../../libcrypto]=deserializer_err.c
--- /dev/null
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2020 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
+ */
+
+#include <openssl/err.h>
+#include <openssl/deserializererr.h>
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA OSSL_DESERIALIZER_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, OSSL_DESERIALIZER_R_MISSING_GET_PARAMS),
+ "missing get params"},
+ {0, NULL}
+};
+
+#endif
+
+int ERR_load_OSSL_DESERIALIZER_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ if (ERR_reason_error_string(OSSL_DESERIALIZER_str_reasons[0].error) == NULL)
+ ERR_load_strings_const(OSSL_DESERIALIZER_str_reasons);
+#endif
+ return 1;
+}
--- /dev/null
+/*
+ * Copyright 2020 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
+ */
+
+#include <openssl/core_names.h>
+#include <openssl/bio.h>
+#include <openssl/params.h>
+#include <openssl/provider.h>
+#include "serializer_local.h"
+#include "e_os.h"
+
+struct deser_process_data_st {
+ OSSL_DESERIALIZER_CTX *ctx;
+
+ /* Current BIO */
+ BIO *bio;
+
+ /* Index of the current deserializer instance to be processed */
+ size_t current_deser_inst_index;
+};
+
+static int deser_process(const OSSL_PARAM params[], void *arg);
+
+int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in)
+{
+ struct deser_process_data_st data;
+
+ memset(&data, 0, sizeof(data));
+ data.ctx = ctx;
+ data.bio = in;
+
+ return deser_process(NULL, &data);
+}
+
+#ifndef OPENSSL_NO_STDIO
+static BIO *bio_from_file(FILE *fp)
+{
+ BIO *b;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_BIO_LIB);
+ return NULL;
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ return b;
+}
+
+int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *fp)
+{
+ BIO *b = bio_from_file(fp);
+ int ret = 0;
+
+ if (b != NULL)
+ ret = OSSL_DESERIALIZER_from_bio(ctx, b);
+
+ BIO_free(b);
+ return ret;
+}
+#endif
+
+int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
+ const char *input_type)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ /*
+ * NULL is a valid starting input type, and means that the caller leaves
+ * it to code to discover what the starting input type is.
+ */
+ ctx->start_input_type = input_type;
+ return 1;
+}
+
+int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
+ OSSL_DESERIALIZER *deser)
+{
+ OSSL_DESERIALIZER_INSTANCE *deser_inst = NULL;
+ const OSSL_PROVIDER *prov = NULL;
+ OSSL_PARAM params[2];
+ void *provctx = NULL;
+
+ if (!ossl_assert(ctx != NULL) || !ossl_assert(deser != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (deser->get_params == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER,
+ OSSL_DESERIALIZER_R_MISSING_GET_PARAMS);
+ return 0;
+ }
+
+ if (ctx->deser_insts == NULL
+ && (ctx->deser_insts =
+ sk_OSSL_DESERIALIZER_INSTANCE_new_null()) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if ((deser_inst = OPENSSL_zalloc(sizeof(*deser_inst))) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!OSSL_DESERIALIZER_up_ref(deser)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ deser_inst->deser = deser;
+
+ prov = OSSL_DESERIALIZER_provider(deser_inst->deser);
+ provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
+
+ /* Cache the input type for this serializer */
+ params[0] =
+ OSSL_PARAM_construct_utf8_ptr(OSSL_DESERIALIZER_PARAM_INPUT_TYPE,
+ (char **)&deser_inst->input_type, 0);
+ params[1] = OSSL_PARAM_construct_end();
+
+ if (!deser_inst->deser->get_params(params)
+ || !OSSL_PARAM_modified(¶ms[0]))
+ goto err;
+
+ if ((deser_inst->deserctx = deser_inst->deser->newctx(provctx))
+ == NULL)
+ goto err;
+
+ if (sk_OSSL_DESERIALIZER_INSTANCE_push(ctx->deser_insts, deser_inst) <= 0)
+ goto err;
+
+ return 1;
+ err:
+ if (deser_inst != NULL) {
+ if (deser_inst->deser != NULL)
+ deser_inst->deser->freectx(deser_inst->deserctx);
+ OSSL_DESERIALIZER_free(deser_inst->deser);
+ OPENSSL_free(deser_inst);
+ }
+ return 0;
+}
+
+int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx,
+ OPENSSL_CTX *libctx, const char *propq)
+{
+ /*
+ * This function goes through existing deserializer methods in
+ * |ctx->deser_insts|, and tries to fetch new deserializers that produce
+ * what the existing ones want as input, and push those newly fetched
+ * deserializers on top of the same stack.
+ * Then it does the same again, but looping over the newly fetched
+ * deserializers, until there are no more serializers to be fetched, or
+ * when we have done this 10 times.
+ *
+ * we do this with sliding windows on the stack by keeping track of indexes
+ * and of the end.
+ *
+ * +----------------+
+ * | DER to RSA | <--- w_prev_start
+ * +----------------+
+ * | DER to DSA |
+ * +----------------+
+ * | DER to DH |
+ * +----------------+
+ * | PEM to DER | <--- w_prev_end, w_new_start
+ * +----------------+
+ * <--- w_new_end
+ */
+ size_t w_prev_start, w_prev_end; /* "previous" deserializers */
+ size_t w_new_start, w_new_end; /* "new" deserializers */
+ size_t count = 0; /* Calculates how many were added in each iteration */
+ size_t depth = 0; /* Counts the number of iterations */
+
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ /*
+ * If there is no stack of OSSL_DESERIALIZER_INSTANCE, we have nothing
+ * more to add. That's fine.
+ */
+ if (ctx->deser_insts == NULL)
+ return 1;
+
+ w_prev_start = 0;
+ w_prev_end = sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts);
+ do {
+ size_t i;
+
+ w_new_start = w_new_end = w_prev_end;
+
+ for (i = w_prev_start; i < w_prev_end; i++) {
+ OSSL_DESERIALIZER_INSTANCE *deser_inst =
+ sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i);
+ const char *name = deser_inst->input_type;
+ OSSL_DESERIALIZER *deser = NULL;
+
+ /*
+ * If the caller has specified what the initial input should be,
+ * and the deserializer implementation we're looking at has that
+ * input type, there's no point adding on more implementations
+ * on top of this one, so we don't.
+ */
+ if (ctx->start_input_type != NULL
+ && strcasecmp(ctx->start_input_type,
+ deser_inst->input_type) != 0)
+ continue;
+
+ ERR_set_mark();
+ deser = OSSL_DESERIALIZER_fetch(libctx, name, propq);
+ ERR_pop_to_mark();
+
+ if (deser != NULL) {
+ size_t j;
+
+ /*
+ * Check that we don't already have this deserializer in our
+ * stack We only need to check among the newly added ones.
+ */
+ for (j = w_new_start; j < w_new_end; j++) {
+ OSSL_DESERIALIZER_INSTANCE *check_inst =
+ sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, j);
+
+ if (deser == check_inst->deser) {
+ /* We found it, so drop the new fetch */
+ OSSL_DESERIALIZER_free(deser);
+ deser = NULL;
+ break;
+ }
+ }
+ }
+
+ if (deser == NULL)
+ continue;
+
+ /*
+ * Apart from keeping w_new_end up to date, We don't care about
+ * errors here. If it doesn't collect, then it doesn't...
+ */
+ if (OSSL_DESERIALIZER_CTX_add_deserializer(ctx, deser)) /* ref++ */
+ w_new_end++;
+ OSSL_DESERIALIZER_free(deser); /* ref-- */
+ }
+ /* How many were added in this iteration */
+ count = w_new_end - w_new_start;
+
+ /* Slide the "previous deserializer" windows */
+ w_prev_start = w_new_start;
+ w_prev_end = w_new_end;
+
+ depth++;
+ } while (count != 0 && depth <= 10);
+
+ return 1;
+}
+
+int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx)
+{
+ if (ctx == NULL || ctx->deser_insts == NULL)
+ return 0;
+ return sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts);
+}
+
+int OSSL_DESERIALIZER_CTX_set_finalizer(OSSL_DESERIALIZER_CTX *ctx,
+ OSSL_DESERIALIZER_FINALIZER *finalizer,
+ OSSL_DESERIALIZER_CLEANER *cleaner,
+ void *finalize_arg)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ctx->finalizer = finalizer;
+ ctx->cleaner = cleaner;
+ ctx->finalize_arg = finalize_arg;
+ return 1;
+}
+
+int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
+ void *reference, size_t reference_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg)
+{
+ if (!(ossl_assert(deser_inst != NULL)
+ && ossl_assert(reference != NULL)
+ && ossl_assert(export_cb != NULL)
+ && ossl_assert(export_cbarg != NULL))) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return deser_inst->deser->export_object(deser_inst->deserctx,
+ reference, reference_sz,
+ export_cb, export_cbarg);
+}
+
+OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst)
+{
+ if (deser_inst == NULL)
+ return NULL;
+ return deser_inst->deser;
+}
+
+void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst)
+{
+ if (deser_inst == NULL)
+ return NULL;
+ return deser_inst->deserctx;
+}
+
+static int deser_process(const OSSL_PARAM params[], void *arg)
+{
+ struct deser_process_data_st *data = arg;
+ OSSL_DESERIALIZER_CTX *ctx = data->ctx;
+ OSSL_DESERIALIZER_INSTANCE *deser_inst = NULL;
+ OSSL_DESERIALIZER *deser = NULL;
+ BIO *bio = data->bio;
+ long loc;
+ size_t i;
+ int ok = 0;
+ /* For recursions */
+ struct deser_process_data_st new_data;
+
+ memset(&new_data, 0, sizeof(new_data));
+ new_data.ctx = data->ctx;
+
+ if (params == NULL) {
+ /* First iteration, where we prepare for what is to come */
+
+ data->current_deser_inst_index =
+ OSSL_DESERIALIZER_CTX_num_deserializers(ctx);
+
+ bio = data->bio;
+ } else {
+ const OSSL_PARAM *p;
+
+ deser_inst =
+ sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts,
+ data->current_deser_inst_index);
+ deser = OSSL_DESERIALIZER_INSTANCE_deserializer(deser_inst);
+
+ if (ctx->finalizer(deser_inst, params, ctx->finalize_arg)) {
+ ok = 1;
+ goto end;
+ }
+
+ /* The finalizer didn't return success */
+
+ /*
+ * so we try to use the object we got and feed it to any next
+ * deserializer that will take it. Object references are not
+ * allowed for this.
+ * If this data isn't present, deserialization has failed.
+ */
+
+ p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_DATA);
+ if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
+ goto end;
+ new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size);
+ if (new_data.bio == NULL)
+ goto end;
+ bio = new_data.bio;
+ }
+
+ /*
+ * If we have no more deserializers to look through at this point,
+ * we failed
+ */
+ if (data->current_deser_inst_index == 0)
+ goto end;
+
+ if ((loc = BIO_tell(bio)) < 0) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_BIO_LIB);
+ goto end;
+ }
+
+ for (i = data->current_deser_inst_index; i-- > 0;) {
+ OSSL_DESERIALIZER_INSTANCE *new_deser_inst =
+ sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i);
+ OSSL_DESERIALIZER *new_deser =
+ OSSL_DESERIALIZER_INSTANCE_deserializer(new_deser_inst);
+
+ /*
+ * If |deser| is NULL, it means we've just started, and the caller
+ * may have specified what it expects the initial input to be. If
+ * that's the case, we do this extra check.
+ */
+ if (deser == NULL && ctx->start_input_type != NULL
+ && strcasecmp(ctx->start_input_type, deser_inst->input_type) != 0)
+ continue;
+
+ /*
+ * If we have a previous deserializer, we check that the input type
+ * of the next to be used matches the type of this previous one.
+ * deser_inst->input_type is a cache of the parameter "input-type"
+ * value for that deserializer.
+ */
+ if (deser != NULL
+ && !OSSL_DESERIALIZER_is_a(deser, new_deser_inst->input_type))
+ continue;
+
+ if (loc == 0) {
+ if (BIO_reset(bio) <= 0)
+ goto end;
+ } else {
+ if (BIO_seek(bio, loc) <= 0)
+ goto end;
+ }
+
+ /* Recurse */
+ new_data.current_deser_inst_index = i;
+ ok = new_deser->deserialize(new_deser_inst->deserctx,
+ (OSSL_CORE_BIO *)bio,
+ deser_process, &new_data,
+ NULL /* ossl_deserializer_passphrase_in_cb */,
+ new_data.ctx);
+ if (ok)
+ break;
+ }
+
+ end:
+ BIO_free(new_data.bio);
+ return ok;
+}
--- /dev/null
+/*
+ * Copyright 2020 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
+ */
+
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/deserializer.h>
+#include <openssl/ui.h>
+#include "internal/core.h"
+#include "internal/namemap.h"
+#include "internal/property.h"
+#include "internal/provider.h"
+#include "crypto/serializer.h"
+#include "serializer_local.h"
+
+static void OSSL_DESERIALIZER_INSTANCE_free(OSSL_DESERIALIZER_INSTANCE *instance);
+
+/*
+ * Deserializer can have multiple names, separated with colons in a name string
+ */
+#define NAME_SEPARATOR ':'
+
+/* Simple method structure constructor and destructor */
+static OSSL_DESERIALIZER *ossl_deserializer_new(void)
+{
+ OSSL_DESERIALIZER *deser = NULL;
+
+ if ((deser = OPENSSL_zalloc(sizeof(*deser))) == NULL
+ || (deser->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ OSSL_DESERIALIZER_free(deser);
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ deser->base.refcnt = 1;
+
+ return deser;
+}
+
+int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *deser)
+{
+ int ref = 0;
+
+ CRYPTO_UP_REF(&deser->base.refcnt, &ref, deser->base.lock);
+ return 1;
+}
+
+void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *deser)
+{
+ int ref = 0;
+
+ if (deser == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&deser->base.refcnt, &ref, deser->base.lock);
+ if (ref > 0)
+ return;
+ ossl_provider_free(deser->base.prov);
+ CRYPTO_THREAD_lock_free(deser->base.lock);
+ OPENSSL_free(deser);
+}
+
+/* Permanent deserializer method store, constructor and destructor */
+static void deserializer_store_free(void *vstore)
+{
+ ossl_method_store_free(vstore);
+}
+
+static void *deserializer_store_new(OPENSSL_CTX *ctx)
+{
+ return ossl_method_store_new(ctx);
+}
+
+
+static const OPENSSL_CTX_METHOD deserializer_store_method = {
+ deserializer_store_new,
+ deserializer_store_free,
+};
+
+/* Data to be passed through ossl_method_construct() */
+struct deserializer_data_st {
+ OPENSSL_CTX *libctx;
+ OSSL_METHOD_CONSTRUCT_METHOD *mcm;
+ int id; /* For get_deserializer_from_store() */
+ const char *names; /* For get_deserializer_from_store() */
+ const char *propquery; /* For get_deserializer_from_store() */
+};
+
+/*
+ * Generic routines to fetch / create DESERIALIZER methods with
+ * ossl_method_construct()
+ */
+
+/* Temporary deserializer method store, constructor and destructor */
+static void *alloc_tmp_deserializer_store(OPENSSL_CTX *ctx)
+{
+ return ossl_method_store_new(ctx);
+}
+
+ static void dealloc_tmp_deserializer_store(void *store)
+{
+ if (store != NULL)
+ ossl_method_store_free(store);
+}
+
+/* Get the permanent deserializer store */
+static OSSL_METHOD_STORE *get_deserializer_store(OPENSSL_CTX *libctx)
+{
+ return openssl_ctx_get_data(libctx, OPENSSL_CTX_DESERIALIZER_STORE_INDEX,
+ &deserializer_store_method);
+}
+
+/* Get deserializer methods from a store, or put one in */
+static void *get_deserializer_from_store(OPENSSL_CTX *libctx, void *store,
+ void *data)
+{
+ struct deserializer_data_st *methdata = data;
+ void *method = NULL;
+ int id;
+
+ if ((id = methdata->id) == 0) {
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ id = ossl_namemap_name2num(namemap, methdata->names);
+ }
+
+ if (store == NULL
+ && (store = get_deserializer_store(libctx)) == NULL)
+ return NULL;
+
+ if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
+ return NULL;
+ return method;
+}
+
+static int put_deserializer_in_store(OPENSSL_CTX *libctx, void *store,
+ void *method, const OSSL_PROVIDER *prov,
+ int operation_id, const char *names,
+ const char *propdef, void *unused)
+{
+ OSSL_NAMEMAP *namemap;
+ int id;
+
+ if ((namemap = ossl_namemap_stored(libctx)) == NULL
+ || (id = ossl_namemap_name2num(namemap, names)) == 0)
+ return 0;
+
+ if (store == NULL && (store = get_deserializer_store(libctx)) == NULL)
+ return 0;
+
+ return ossl_method_store_add(store, prov, id, propdef, method,
+ (int (*)(void *))OSSL_DESERIALIZER_up_ref,
+ (void (*)(void *))OSSL_DESERIALIZER_free);
+}
+
+/* Create and populate a deserializer method */
+static void *deserializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
+ OSSL_PROVIDER *prov)
+{
+ OSSL_DESERIALIZER *deser = NULL;
+ const OSSL_DISPATCH *fns = algodef->implementation;
+
+ if ((deser = ossl_deserializer_new()) == NULL)
+ return NULL;
+ deser->base.id = id;
+ deser->base.propdef = algodef->property_definition;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_DESERIALIZER_NEWCTX:
+ if (deser->newctx == NULL)
+ deser->newctx = OSSL_FUNC_deserializer_newctx(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_FREECTX:
+ if (deser->freectx == NULL)
+ deser->freectx = OSSL_FUNC_deserializer_freectx(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_GET_PARAMS:
+ if (deser->get_params == NULL)
+ deser->get_params =
+ OSSL_FUNC_deserializer_get_params(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS:
+ if (deser->gettable_params == NULL)
+ deser->gettable_params =
+ OSSL_FUNC_deserializer_gettable_params(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS:
+ if (deser->set_ctx_params == NULL)
+ deser->set_ctx_params =
+ OSSL_FUNC_deserializer_set_ctx_params(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS:
+ if (deser->settable_ctx_params == NULL)
+ deser->settable_ctx_params =
+ OSSL_FUNC_deserializer_settable_ctx_params(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_DESERIALIZE:
+ if (deser->deserialize == NULL)
+ deser->deserialize = OSSL_FUNC_deserializer_deserialize(fns);
+ break;
+ case OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT:
+ if (deser->export_object == NULL)
+ deser->export_object = OSSL_FUNC_deserializer_export_object(fns);
+ break;
+ }
+ }
+ /*
+ * Try to check that the method is sensible.
+ * If you have a constructor, you must have a destructor and vice versa.
+ * You must have at least one of the serializing driver functions.
+ */
+ if (!((deser->newctx == NULL && deser->freectx == NULL)
+ || (deser->newctx != NULL && deser->freectx != NULL))
+ || (deser->deserialize == NULL && deser->export_object == NULL)) {
+ OSSL_DESERIALIZER_free(deser);
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
+ return NULL;
+ }
+
+ if (prov != NULL && !ossl_provider_up_ref(prov)) {
+ OSSL_DESERIALIZER_free(deser);
+ return NULL;
+ }
+
+ deser->base.prov = prov;
+ return deser;
+}
+
+
+/*
+ * The core fetching functionality passes the names of the implementation.
+ * This function is responsible to getting an identity number for them,
+ * then call deserializer_from_dispatch() with that identity number.
+ */
+static void *construct_deserializer(const OSSL_ALGORITHM *algodef,
+ OSSL_PROVIDER *prov, void *unused)
+{
+ /*
+ * This function is only called if get_deserializer_from_store() returned
+ * NULL, so it's safe to say that of all the spots to create a new
+ * namemap entry, this is it. Should the name already exist there, we
+ * know that ossl_namemap_add() will return its corresponding number.
+ */
+ OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+ const char *names = algodef->algorithm_names;
+ int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
+ void *method = NULL;
+
+ if (id != 0)
+ method = deserializer_from_dispatch(id, algodef, prov);
+
+ return method;
+}
+
+/* Intermediary function to avoid ugly casts, used below */
+static void destruct_deserializer(void *method, void *data)
+{
+ OSSL_DESERIALIZER_free(method);
+}
+
+static int up_ref_deserializer(void *method)
+{
+ return OSSL_DESERIALIZER_up_ref(method);
+}
+
+static void free_deserializer(void *method)
+{
+ OSSL_DESERIALIZER_free(method);
+}
+
+/* Fetching support. Can fetch by numeric identity or by name */
+static OSSL_DESERIALIZER *inner_ossl_deserializer_fetch(OPENSSL_CTX *libctx,
+ int id,
+ const char *name,
+ const char *properties)
+{
+ OSSL_METHOD_STORE *store = get_deserializer_store(libctx);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+ void *method = NULL;
+
+ if (store == NULL || namemap == NULL)
+ return NULL;
+
+ /*
+ * If we have been passed neither a name_id or a name, we have an
+ * internal programming error.
+ */
+ if (!ossl_assert(id != 0 || name != NULL))
+ return NULL;
+
+ if (id == 0)
+ id = ossl_namemap_name2num(namemap, name);
+
+ if (id == 0
+ || !ossl_method_store_cache_get(store, id, properties, &method)) {
+ OSSL_METHOD_CONSTRUCT_METHOD mcm = {
+ alloc_tmp_deserializer_store,
+ dealloc_tmp_deserializer_store,
+ get_deserializer_from_store,
+ put_deserializer_in_store,
+ construct_deserializer,
+ destruct_deserializer
+ };
+ struct deserializer_data_st mcmdata;
+
+ mcmdata.libctx = libctx;
+ mcmdata.mcm = &mcm;
+ mcmdata.id = id;
+ mcmdata.names = name;
+ mcmdata.propquery = properties;
+ if ((method = ossl_method_construct(libctx, OSSL_OP_DESERIALIZER,
+ 0 /* !force_cache */,
+ &mcm, &mcmdata)) != NULL) {
+ /*
+ * If construction did create a method for us, we know that
+ * there is a correct name_id and meth_id, since those have
+ * already been calculated in get_deserializer_from_store() and
+ * put_deserializer_in_store() above.
+ */
+ if (id == 0)
+ id = ossl_namemap_name2num(namemap, name);
+ ossl_method_store_cache_set(store, id, properties, method,
+ up_ref_deserializer, free_deserializer);
+ }
+ }
+
+ return method;
+}
+
+OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx,
+ const char *name,
+ const char *properties)
+{
+ return inner_ossl_deserializer_fetch(libctx, 0, name, properties);
+}
+
+OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx,
+ int id,
+ const char *properties)
+{
+ return inner_ossl_deserializer_fetch(libctx, id, NULL, properties);
+}
+
+/*
+ * Library of basic method functions
+ */
+
+const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *deser)
+{
+ if (!ossl_assert(deser != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return deser->base.prov;
+}
+
+const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *deser)
+{
+ if (!ossl_assert(deser != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return deser->base.propdef;
+}
+
+int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *deser)
+{
+ if (!ossl_assert(deser != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return deser->base.id;
+}
+
+int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *deser, const char *name)
+{
+ if (deser->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(deser->base.prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ return ossl_namemap_name2num(namemap, name) == deser->base.id;
+ }
+ return 0;
+}
+
+struct deserializer_do_all_data_st {
+ void (*user_fn)(void *method, void *arg);
+ void *user_arg;
+};
+
+static void deserializer_do_one(OSSL_PROVIDER *provider,
+ const OSSL_ALGORITHM *algodef,
+ int no_store, void *vdata)
+{
+ struct deserializer_do_all_data_st *data = vdata;
+ OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+ const char *names = algodef->algorithm_names;
+ int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
+ void *method = NULL;
+
+ if (id != 0)
+ method =
+ deserializer_from_dispatch(id, algodef, provider);
+
+ if (method != NULL) {
+ data->user_fn(method, data->user_arg);
+ OSSL_DESERIALIZER_free(method);
+ }
+}
+
+void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
+ void (*fn)(OSSL_DESERIALIZER *deser,
+ void *arg),
+ void *arg)
+{
+ struct deserializer_do_all_data_st data;
+
+ data.user_fn = (void (*)(void *, void *))fn;
+ data.user_arg = arg;
+ ossl_algorithm_do_all(libctx, OSSL_OP_DESERIALIZER, NULL,
+ NULL, deserializer_do_one, NULL,
+ &data);
+}
+
+void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *deser,
+ void (*fn)(const char *name, void *data),
+ void *data)
+{
+ if (deser == NULL)
+ return;
+
+ if (deser->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(deser->base.prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ ossl_namemap_doall_names(namemap, deser->base.id, fn, data);
+ }
+}
+
+const OSSL_PARAM *
+OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser)
+{
+ if (deser != NULL && deser->gettable_params != NULL)
+ return deser->gettable_params();
+ return NULL;
+}
+
+int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER *deser, OSSL_PARAM params[])
+{
+ if (deser != NULL && deser->get_params != NULL)
+ return deser->get_params(params);
+ return 0;
+}
+
+const OSSL_PARAM *
+OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *deser)
+{
+ if (deser != NULL && deser->settable_ctx_params != NULL)
+ return deser->settable_ctx_params();
+ return NULL;
+}
+
+/*
+ * Deserializer context support
+ */
+
+/*
+ * |ser| value NULL is valid, and signifies that there is no deserializer.
+ * This is useful to provide fallback mechanisms.
+ * Functions that want to verify if there is a deserializer can do so with
+ * OSSL_DESERIALIZER_CTX_get_deserializer()
+ */
+OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void)
+{
+ OSSL_DESERIALIZER_CTX *ctx;
+
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
+ const OSSL_PARAM params[])
+{
+ size_t i;
+ size_t l;
+
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (ctx->deser_insts == NULL)
+ return 1;
+
+ l = (size_t)sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts);
+ for (i = 0; i < l; i++) {
+ OSSL_DESERIALIZER_INSTANCE *deser_inst =
+ sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i);
+
+ if (deser_inst->deserctx == NULL
+ || deser_inst->deser->set_ctx_params == NULL)
+ continue;
+ if (!deser_inst->deser->set_ctx_params(deser_inst->deserctx, params))
+ return 0;
+ }
+ return 1;
+}
+
+static void
+OSSL_DESERIALIZER_INSTANCE_free(OSSL_DESERIALIZER_INSTANCE *deser_inst)
+{
+ if (deser_inst != NULL) {
+ if (deser_inst->deser->freectx != NULL)
+ deser_inst->deser->freectx(deser_inst->deserctx);
+ deser_inst->deserctx = NULL;
+ OSSL_DESERIALIZER_free(deser_inst->deser);
+ deser_inst->deser = NULL;
+ OPENSSL_free(deser_inst);
+ deser_inst = NULL;
+ }
+}
+
+void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx)
+{
+ if (ctx != NULL) {
+ if (ctx->cleaner != NULL)
+ 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);
+ OPENSSL_free(ctx);
+ }
+}
#include <openssl/core_dispatch.h>
#include <openssl/types.h>
+#include <openssl/safestack.h>
+#include <openssl/serializer.h>
+#include <openssl/deserializer.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
-struct ossl_serializer_st {
+struct ossl_serdes_base_st {
OSSL_PROVIDER *prov;
int id;
const char *propdef;
CRYPTO_REF_COUNT refcnt;
CRYPTO_RWLOCK *lock;
+};
+struct ossl_serializer_st {
+ struct ossl_serdes_base_st base;
OSSL_FUNC_serializer_newctx_fn *newctx;
OSSL_FUNC_serializer_freectx_fn *freectx;
OSSL_FUNC_serializer_set_ctx_params_fn *set_ctx_params;
OSSL_FUNC_serializer_serialize_object_fn *serialize_object;
};
+struct ossl_deserializer_st {
+ struct ossl_serdes_base_st base;
+ OSSL_FUNC_deserializer_newctx_fn *newctx;
+ OSSL_FUNC_deserializer_freectx_fn *freectx;
+ OSSL_FUNC_deserializer_get_params_fn *get_params;
+ OSSL_FUNC_deserializer_gettable_params_fn *gettable_params;
+ OSSL_FUNC_deserializer_set_ctx_params_fn *set_ctx_params;
+ OSSL_FUNC_deserializer_settable_ctx_params_fn *settable_ctx_params;
+ OSSL_FUNC_deserializer_deserialize_fn *deserialize;
+ OSSL_FUNC_deserializer_export_object_fn *export_object;
+};
+
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.
+ /*-
+ * Output / serializing data, used by OSSL_SERIALIZER_to_{bio,fp}
+ *
+ * |object| is the libcrypto object to handle.
+ * |do_output| performs the actual serialization.
+ *
+ * |do_output| must have intimate knowledge of |object|.
*/
const void *object;
int (*do_output)(OSSL_SERIALIZER_CTX *ctx, BIO *out);
*/
UI_METHOD *allocated_ui_method;
};
+
+struct ossl_deserializer_instance_st {
+ OSSL_DESERIALIZER *deser; /* Never NULL */
+ void *deserctx; /* Never NULL */
+ const char *input_type; /* Never NULL */
+};
+
+DEFINE_STACK_OF(OSSL_DESERIALIZER_INSTANCE)
+
+struct ossl_deserializer_ctx_st {
+ /*
+ * The caller may know the input type of the data they pass. If not,
+ * this will remain NULL and the deserializing functionality will start
+ * with trying to deserialize with any desserializer in |deser_insts|,
+ * regardless of their respective input type.
+ */
+ const char *start_input_type;
+
+ /*
+ * Deserializers that are components of any current deserialization path.
+ */
+ STACK_OF(OSSL_DESERIALIZER_INSTANCE) *deser_insts;
+
+ /*
+ * The finalizer of a deserialization, and its caller argument.
+ */
+ OSSL_DESERIALIZER_FINALIZER *finalizer;
+ OSSL_DESERIALIZER_CLEANER *cleaner;
+ void *finalize_arg;
+
+ /* For any function that needs a passphrase reader */
+ const UI_METHOD *ui_method;
+ void *ui_data;
+ /*
+ * if caller used OSSL_SERIALIZER_CTX_set_passphrase_cb(), we need
+ * intermediary storage.
+ */
+ UI_METHOD *allocated_ui_method;
+};
OSSL_SERIALIZER *ser = NULL;
if ((ser = OPENSSL_zalloc(sizeof(*ser))) == NULL
- || (ser->lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ || (ser->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
OSSL_SERIALIZER_free(ser);
ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE);
return NULL;
}
- ser->refcnt = 1;
+ ser->base.refcnt = 1;
return ser;
}
{
int ref = 0;
- CRYPTO_UP_REF(&ser->refcnt, &ref, ser->lock);
+ CRYPTO_UP_REF(&ser->base.refcnt, &ref, ser->base.lock);
return 1;
}
if (ser == NULL)
return;
- CRYPTO_DOWN_REF(&ser->refcnt, &ref, ser->lock);
+ CRYPTO_DOWN_REF(&ser->base.refcnt, &ref, ser->base.lock);
if (ref > 0)
return;
- ossl_provider_free(ser->prov);
- CRYPTO_THREAD_lock_free(ser->lock);
+ ossl_provider_free(ser->base.prov);
+ CRYPTO_THREAD_lock_free(ser->base.lock);
OPENSSL_free(ser);
}
if ((ser = ossl_serializer_new()) == NULL)
return NULL;
- ser->id = id;
- ser->propdef = algodef->property_definition;
+ ser->base.id = id;
+ ser->base.propdef = algodef->property_definition;
for (; fns->function_id != 0; fns++) {
switch (fns->function_id) {
return NULL;
}
- ser->prov = prov;
+ ser->base.prov = prov;
return ser;
}
return 0;
}
- return ser->prov;
+ return ser->base.prov;
}
const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser)
return 0;
}
- return ser->propdef;
+ return ser->base.propdef;
}
int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser)
return 0;
}
- return ser->id;
+ return ser->base.id;
}
int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser, const char *name)
{
- if (ser->prov != NULL) {
- OPENSSL_CTX *libctx = ossl_provider_library_context(ser->prov);
+ if (ser->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(ser->base.prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
- return ossl_namemap_name2num(namemap, name) == ser->id;
+ return ossl_namemap_name2num(namemap, name) == ser->base.id;
}
return 0;
}
if (ser == NULL)
return;
- if (ser->prov != NULL) {
- OPENSSL_CTX *libctx = ossl_provider_library_context(ser->prov);
+ if (ser->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(ser->base.prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
- ossl_namemap_doall_names(namemap, ser->id, fn, data);
+ ossl_namemap_doall_names(namemap, ser->base.id, fn, data);
}
}
--- /dev/null
+=pod
+
+=head1 NAME
+
+OSSL_DESERIALIZER,
+OSSL_DESERIALIZER_fetch,
+OSSL_DESERIALIZER_up_ref,
+OSSL_DESERIALIZER_free,
+OSSL_DESERIALIZER_provider,
+OSSL_DESERIALIZER_properties,
+OSSL_DESERIALIZER_is_a,
+OSSL_DESERIALIZER_number,
+OSSL_DESERIALIZER_do_all_provided,
+OSSL_DESERIALIZER_names_do_all,
+OSSL_DESERIALIZER_gettable_params,
+OSSL_DESERIALIZER_get_params
+- Deserializer method routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/deserializer.h>
+
+ typedef struct ossl_deserializer_st OSSL_DESERIALIZER;
+
+ OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *ctx, const char *name,
+ const char *properties);
+ int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *deserializer);
+ void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *deserializer);
+ const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER
+ *deserializer);
+ const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *deser);
+ int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *deserializer,
+ const char *name);
+ int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *deserializer);
+ void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
+ void (*fn)(OSSL_DESERIALIZER *deserializer,
+ void *arg),
+ void *arg);
+ void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *deserializer,
+ void (*fn)(const char *name, void *data),
+ void *data);
+ const OSSL_PARAM *OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser);
+ int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER_CTX *ctx,
+ const OSSL_PARAM params[]);
+
+=head1 DESCRIPTION
+
+B<OSSL_DESERIALIZER> is a method for deserializers, which know how to
+deserialize serialized data into an object of some type that the rest
+of OpenSSL knows how to handle.
+
+OSSL_DESERIALIZER_fetch() looks for an algorithm within the provider that
+has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
+name given by I<name> and the properties given by I<properties>.
+The I<name> determines what type of object the fetched deserializer
+method is expected to be able to deserialize, and the properties are
+used to determine the expected output type.
+For known properties and the values they may have, please have a look
+in L<provider-serializer(7)/Names and properties>.
+
+OSSL_DESERIALIZER_up_ref() increments the reference count for the given
+I<deserializer>.
+
+OSSL_DESERIALIZER_free() decrements the reference count for the given
+I<deserializer>, and when the count reaches zero, frees it.
+
+OSSL_DESERIALIZER_provider() returns the provider of the given
+I<deserializer>.
+
+OSSL_DESERIALIZER_properties() returns the property definition associated
+with the given I<deserializer>.
+
+OSSL_DESERIALIZER_is_a() checks if I<deserializer> is an implementation
+of an algorithm that's identifiable with I<name>.
+
+OSSL_DESERIALIZER_number() returns the internal dynamic number assigned
+to the given I<deserializer>.
+
+OSSL_DESERIALIZER_names_do_all() traverses all names for the given
+I<deserializer>, and calls I<fn> with each name and I<data>.
+
+OSSL_DESERIALIZER_do_all_provided() traverses all serializer
+implementations by all activated providers in the library context
+I<libctx>, and for each of the implementations, calls I<fn> with the
+implementation method and I<data> as arguments.
+
+OSSL_DESERIALIZER_gettable_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_DESERIALIZER_get_params() attempts to get parameters specified
+with an L<OSSL_PARAM(3)> array I<params>. Parameters that the
+implementation doesn't recognise should be ignored.
+
+=head1 RETURN VALUES
+
+OSSL_DESERIALIZER_fetch() returns a pointer to an OSSL_DESERIALIZER object,
+or NULL on error.
+
+OSSL_DESERIALIZER_up_ref() returns 1 on success, or 0 on error.
+
+OSSL_DESERIALIZER_free() doesn't return any value.
+
+OSSL_DESERIALIZER_provider() returns a pointer to a provider object, or
+NULL on error.
+
+OSSL_DESERIALIZER_properties() returns a pointer to a property
+definition string, or NULL on error.
+
+OSSL_DESERIALIZER_is_a() returns 1 if I<deserializer> was identifiable,
+otherwise 0.
+
+OSSL_DESERIALIZER_number() returns an integer.
+
+=head1 NOTES
+
+OSSL_DESERIALIZER_fetch() may be called implicitly by other fetching
+functions, using the same library context and properties.
+Any other API that uses keys will typically do this.
+
+=begin comment TODO(3.0) Add examples!
+
+=head1 EXAMPLES
+
+Text, because pod2xxx doesn't like empty sections
+
+=end comment
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DESERIALIZER_CTX(3)>, L<OSSL_DESERIALIZER_from_bio(3)>,
+L<OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 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
--- /dev/null
+=pod
+
+=head1 NAME
+
+OSSL_DESERIALIZER_CTX,
+OSSL_DESERIALIZER_CTX_new,
+OSSL_DESERIALIZER_settable_ctx_params,
+OSSL_DESERIALIZER_CTX_set_params,
+OSSL_DESERIALIZER_CTX_free
+- Serializer context routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/deserializer.h>
+
+ typedef struct ossl_deserializer_ctx_st OSSL_DESERIALIZER_CTX;
+
+ OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(OPENSSL_CTX *libctx);
+ const OSSL_PARAM *OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *deser);
+ int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
+ const OSSL_PARAM params[]);
+ void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx);
+
+=head1 DESCRIPTION
+
+B<OSSL_DESERIALIZER_CTX> is a context with which B<OSSL_DESERIALIZER>
+operations are performed. The context typically holds values, both
+internal and supplied by the application, which are useful for the
+implementations supplied by providers.
+
+OSSL_DESERIALIZER_CTX_new() creates a new empty B<OSSL_DESERIALIZER_CTX>.
+
+OSSL_DESERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_DESERIALIZER_CTX_set_params() attempts to set parameters specified
+with an L<OSSL_PARAM(3)> array I<params>. These parameters are passed
+to all deserializers that have been added to the I<ctx> so far.
+Parameters that an implementation doesn't recognise should be ignored
+by it.
+
+OSSL_DESERIALIZER_CTX_free() frees the given context I<ctx>.
+
+=head1 RETURN VALUES
+
+OSSL_DESERIALIZER_CTX_new() returns a pointer to a
+B<OSSL_DESERIALIZER_CTX>, or NULL if the context structure couldn't be
+allocated.
+
+OSSL_DESERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array, or NULL if none is available.
+
+OSSL_DESERIALIZER_CTX_set_params() returns 1 if all recognised
+parameters were valid, or 0 if one of them was invalid or caused some
+other failure in the implementation.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DESERIALIZER(3)>, L<OSSL_DESERIALIZER_from_bio(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 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
--- /dev/null
+=pod
+
+=head1 NAME
+
+OSSL_DESERIALIZER_from_bio,
+OSSL_DESERIALIZER_from_fp,
+OSSL_DESERIALIZER_CTX_set_input_type,
+OSSL_DESERIALIZER_CTX_add_deserializer,
+OSSL_DESERIALIZER_CTX_add_extra,
+OSSL_DESERIALIZER_CTX_num_deserializers,
+OSSL_DESERIALIZER_INSTANCE,
+OSSL_DESERIALIZER_FINALIZER,
+OSSL_DESERIALIZER_CLEANER,
+OSSL_DESERIALIZER_CTX_set_finalizer,
+OSSL_DESERIALIZER_export,
+OSSL_DESERIALIZER_INSTANCE_deserializer,
+OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
+- Routines to perform a deserialization
+
+=head1 SYNOPSIS
+
+ #include <openssl/deserializer.h>
+
+ int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in);
+ int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *fp);
+
+ int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
+ const char *input_type);
+ int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
+ OSSL_DESERIALIZER *deser);
+ int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx);
+ int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx);
+
+ typedef struct ossl_deserializer_instance_st OSSL_DESERIALIZER_INSTANCE;
+ typedef int (OSSL_DESERIALIZER_FINALIZER)
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst,
+ const OSSL_PARAM *params, void *finalize_arg);
+ typedef void (OSSL_DESERIALIZER_CLEANER)(void *finalize_arg);
+
+ int OSSL_DESERIALIZER_CTX_set_finalizer(OSSL_DESERIALIZER_CTX *ctx,
+ OSSL_DESRIALIZER_FINALIZER *finalizer,
+ OSSL_DESERIALIZER_CLEANER *cleaner,
+ void *finalize_arg);
+
+ int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
+ void *reference, size_t reference_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg);
+
+ OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst);
+ void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst);
+
+Feature availability macros:
+
+=over 4
+
+=item OSSL_DESERIALIZER_from_fp() is only available when B<OPENSSL_NO_STDIO>
+is undefined.
+
+=back
+
+=head1 DESCRIPTION
+
+The B<OSSL_DESERIALIZER_CTX> holds data about multiple deserializers, as
+needed to figure out what the input data is and to attempt to unpack it into
+one of several possible related results. This also includes chaining
+deserializers, so the output from one can become the input for another.
+This allows having generic format deserializers such as PEM to DER, as well
+as more specialized deserializers like DER to RSA.
+
+The chains may be limited by specifying an input type, which is considered a
+starting point.
+This is both considered by OSSL_DESERIALIZER_CTX_add_extra(), which will
+stop adding on more deserializer implementations when it has already added
+those that take the specified input type, and OSSL_DESERIALIZER_from_bio(),
+which will only start the deserializing process with the deserializer
+implementations that take that input type. For example, if the input type
+is set to C<DER>, a PEM to DER deserializer will be ignored.
+
+The input type can also be NULL, which means that the caller doesn't know
+what type of input they have. In this case, OSSL_DESERIALIZER_from_bio()
+will simply try with one deserializer implementation after the other, and
+thereby discover what kind of input the caller gave it.
+
+For every deserialization done, even intermediary, a I<finalizer>
+provided by the caller is used to attempt to "finalize" the current
+deserialization output, which is always a provider side object of some
+sort, by "wrapping" it into some appropriate type or structure that
+the caller knows how to handle. Exactly what this "wrapping" consists
+of is entirely at the discretion of the I<finalizer>.
+
+B<OSSL_DESERIALIZER_INSTANCE> is an opaque structure that contains
+data about the deserializer that was just used, and that may be
+useful for the I<finalizer>. There are some functions to extract data
+from this type, described further down.
+
+=head2 Functions
+
+OSSL_DESERIALIZER_from_bio() runs the deserialization process for the
+context I<ctx>, with the input coming from the B<BIO> I<in>. The
+application is required to set up the B<BIO> properly, for example to
+have it in text or binary mode if that's appropriate.
+
+=for comment Know your deserializer!
+
+OSSL_DESERIALIZER_from_fp() does the same thing as OSSL_DESERIALIZER_from_bio(),
+except that the input is coming from the B<FILE> I<fp>.
+
+OSSL_DESERIALIZER_CTX_add_deserializer() populates the B<OSSL_DESERIALIZER_CTX>
+I<ctx> with a deserializer, to be used to attempt to deserialize some
+serialized input.
+
+OSSL_DESERIALIZER_CTX_add_extra() finds deserializers that generate
+input for already added deserializers, and adds them as well. This is
+used to build deserializer chains.
+
+OSSL_DESERIALIZER_CTX_set_input_type() sets the starting input type. This
+limits the deserializer chains to be considered, as explained in the general
+description above.
+
+OSSL_DESERIALIZER_CTX_num_deserializers() gets the number of
+deserializers currently added to the context I<ctx>.
+
+OSSL_DESERIALIZER_CTX_set_finalizer() sets the I<finalizer> function
+together with the caller argument for the finalizer, I<finalize_arg>,
+as well as I<cleaner>, the function to clean up I<finalize_arg> when
+the deserialization has concluded.
+
+OSSL_DESERIALIZER_export() is a fallback function for I<finalizers>
+that can't use the data they get directly for diverse reasons. It
+takes the same deserialize instance I<deser_inst> that the
+I<finalizer> got and an object I<reference>, unpacks the object that
+refers to, and exports it by creating an L<OSSL_PARAM(3)> array that
+it then passes to I<export_cb>, along with I<export_arg>.
+
+OSSL_DESERIALIZER_INSTANCE_deserializer() can be used to get the
+deserializer method from a deserializer instance I<deser_inst>.
+
+OSSL_DESERIALIZER_INSTANCE_deserializer-ctx() can be used to get the
+deserializer method's provider context from a deserializer instance
+I<deser_inst>.
+
+=head2 Finalizer
+
+The I<finalizer> gets the following arguments:
+
+=over 4
+
+=item I<deser_inst>
+
+The B<OSSL_DESERIALIZER_INSTANCE> for the deserializer from which
+I<finalizer> gets its data.
+
+=item I<params>
+
+The data produced by the deserializer, further described below.
+
+=item I<finalize_arg>
+
+The pointer that was set with OSSL_DESERIALIZE_CTX_set_finalizer() as
+I<finalize_arg>.
+
+=back
+
+The I<finalizer> is expected to return 1 when the data it receives can
+be "finalized", otherwise 0.
+
+The globally known parameters that I<finalize> can get in I<params>
+are:
+
+=over 4
+
+=item "data-type" (B<OSSL_DESERIALIZER_PARAM_DATA_TYPE>) <UTF8 string>
+
+This is a detected content type that some deserializers may provide.
+For example, PEM input sometimes has a type specified in its header,
+and some deserializers may add that information as this parameter.
+This is an optional parameter, but may be useful for extra checks in
+the I<finalizer>.
+
+=item "data" (B<OSSL_DESERIALIZER_PARAM_DATA>) <octet string>
+
+The deserialized data itself, as an octet string. This is produced by
+deserializers when it's possible to pass an object in this form. Most
+often, this is simply meant to be passed to the next deserializer in a
+chain, but could be considered final data as well, at the discretion
+of the I<finalizer>.
+
+=item "reference" (B<OSSL_DESERIALIZER_PARAM_DATA>) <octet string>
+
+The deserialized data itself, as a reference to an object. The
+reference itself is an octet string, and can be passed to other
+operations and functions within the same provider as the one that
+provides I<deser>.
+
+=back
+
+At least one of "data" or "reference" must be present, and it's
+possible that both can be. A I<finalizer> should choose to use the
+"reference" parameter if possible, otherwise the "data" parameter.
+
+If it's not possible to use the "reference" parameter, but that's
+still what a I<finalizer> wants to do, it is possible to use
+OSSL_DESERIALIZER_export() as a fallback.
+
+=head1 RETURN VALUES
+
+OSSL_DESERIALIZER_from_bio() and OSSL_DESERIALIZER_from_fp() return 1 on
+success, or 0 on failure.
+
+OSSL_DESERIALIZER_CTX_add_deserializer(),
+OSSL_DESERIALIZER_CTX_add_extra(), and
+OSSL_DESERIALIZER_CTX_set_finalizer() return 1 on success, or 0 on
+failure.
+
+OSSL_DESERIALIZER_CTX_num_deserializers() returns the current
+number of deserializers. It returns 0 if I<ctx> is NULL.
+
+OSSL_DESERIALIZER_export() returns 1 on success, or 0 on failure.
+
+OSSL_DESERIALIZER_INSTANCE_deserializer() returns an
+B<OSSL_DESERIALIZER> pointer on success, or NULL on failure.
+
+OSSL_DESERIALIZER_INSTANCE_deserializer_ctx() returns a provider
+context pointer on success, or NULL on failure.>
+
+=begin comment TODO(3.0) Add examples!
+
+=head1 EXAMPLES
+
+Text, because pod2xxx doesn't like empty sections
+
+=end comment
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DESERIALIZER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 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
OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
const char *properties);
+OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
+ const char *properties);
# define OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX 8
# define OPENSSL_CTX_FIPS_PROV_INDEX 9
# define OPENSSL_CTX_SERIALIZER_STORE_INDEX 10
-# define OPENSSL_CTX_SELF_TEST_CB_INDEX 11
-# define OPENSSL_CTX_BIO_PROV_INDEX 12
-# define OPENSSL_CTX_GLOBAL_PROPERTIES 13
-# define OPENSSL_CTX_MAX_INDEXES 14
+# define OPENSSL_CTX_DESERIALIZER_STORE_INDEX 11
+# define OPENSSL_CTX_SELF_TEST_CB_INDEX 12
+# define OPENSSL_CTX_BIO_PROV_INDEX 13
+# define OPENSSL_CTX_GLOBAL_PROPERTIES 14
+# define OPENSSL_CTX_MAX_INDEXES 15
typedef struct openssl_ctx_method {
void *(*new_func)(OPENSSL_CTX *ctx);
# define OSSL_OP_ASYM_CIPHER 13
/* New section for non-EVP operations */
# define OSSL_OP_SERIALIZER 20
+# define OSSL_OP_DESERIALIZER 21
/* Highest known operation number */
-# define OSSL_OP__HIGHEST 20
+# define OSSL_OP__HIGHEST 21
/* Digests */
OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, asym_cipher_settable_ctx_params,
(void))
-/* Serializers */
+/* Serializers and deserializers */
# define OSSL_FUNC_SERIALIZER_NEWCTX 1
# define OSSL_FUNC_SERIALIZER_FREECTX 2
# define OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS 3
(void *ctx, void *obj, OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
+# define OSSL_FUNC_DESERIALIZER_NEWCTX 1
+# define OSSL_FUNC_DESERIALIZER_FREECTX 2
+# define OSSL_FUNC_DESERIALIZER_GET_PARAMS 3
+# define OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS 4
+# define OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS 5
+# define OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS 6
+# define OSSL_FUNC_DESERIALIZER_DESERIALIZE 10
+# define OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT 11
+OSSL_CORE_MAKE_FUNC(void *, deserializer_newctx, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void, deserializer_freectx, (void *ctx))
+OSSL_CORE_MAKE_FUNC(int, deserializer_get_params, (OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_gettable_params, (void))
+OSSL_CORE_MAKE_FUNC(int, deserializer_set_ctx_params,
+ (void *ctx, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_settable_ctx_params,
+ (void))
+
+OSSL_CORE_MAKE_FUNC(int, deserializer_deserialize,
+ (void *ctx, OSSL_CORE_BIO *in,
+ OSSL_CALLBACK *metadata_cb, void *metadata_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg))
+OSSL_CORE_MAKE_FUNC(int, deserializer_export_object,
+ (void *ctx, const void *objref, size_t objref_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg))
+
# ifdef __cplusplus
}
# endif
#define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION "tls-negotiated-version"
/*
- * Serializer parameters
+ * Serializer / deserializer parameters
*/
/* The passphrase may be passed as a utf8 string or an octet string */
#define OSSL_SERIALIZER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER
#define OSSL_SERIALIZER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES
#define OSSL_SERIALIZER_PARAM_PASS "passphrase"
+#define OSSL_DESERIALIZER_PARAM_INPUT_TYPE "input-type"
+#define OSSL_DESERIALIZER_PARAM_DATA_TYPE "data-type"
+#define OSSL_DESERIALIZER_PARAM_DATA "data"
+#define OSSL_DESERIALIZER_PARAM_REFERENCE "reference"
+
/* Passphrase callback parameters */
#define OSSL_PASSPHRASE_PARAM_INFO "info"
--- /dev/null
+/*
+ * Copyright 2020 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
+ */
+
+#ifndef OPENSSL_DESERIALIZER_H
+# define OPENSSL_DESERIALIZER_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_STDIO
+# include <stdio.h>
+# endif
+# include <stdarg.h>
+# include <stddef.h>
+# include <openssl/deserializererr.h>
+# include <openssl/types.h>
+# include <openssl/core.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx,
+ const char *name,
+ const char *properties);
+int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *ser);
+void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *ser);
+
+const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *ser);
+const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *ser);
+int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *ser);
+int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *ser,
+ const char *name);
+
+void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
+ void (*fn)(OSSL_DESERIALIZER *ser,
+ void *arg),
+ void *arg);
+void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *ser,
+ void (*fn)(const char *name, void *data),
+ void *data);
+const OSSL_PARAM *OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser);
+int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER *deser, OSSL_PARAM params[]);
+
+const OSSL_PARAM *OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *ser);
+OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void);
+int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
+ const OSSL_PARAM params[]);
+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, int enc,
+ 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);
+
+/*
+ * Utilities to read the object to deserialize, with the result sent to cb.
+ * These will discover all provided methods
+ */
+
+int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
+ const char *input_type);
+int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
+ OSSL_DESERIALIZER *deser);
+int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx,
+ OPENSSL_CTX *libctx, const char *propq);
+int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx);
+
+typedef struct ossl_deserializer_instance_st OSSL_DESERIALIZER_INSTANCE;
+typedef int (OSSL_DESERIALIZER_FINALIZER)
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst,
+ const OSSL_PARAM *params, void *finalize_arg);
+typedef void (OSSL_DESERIALIZER_CLEANER)(void *finalize_arg);
+
+int OSSL_DESERIALIZER_CTX_set_finalizer(OSSL_DESERIALIZER_CTX *ctx,
+ OSSL_DESERIALIZER_FINALIZER *finalizer,
+ OSSL_DESERIALIZER_CLEANER *cleaner,
+ void *finalize_arg);
+
+int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
+ void *reference, size_t reference_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg);
+
+OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst);
+void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
+ (OSSL_DESERIALIZER_INSTANCE *deser_inst);
+
+int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in);
+#ifndef OPENSSL_NO_STDIO
+int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *in);
+#endif
+
+# ifdef __cplusplus
+}
+# endif
+#endif
--- /dev/null
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2020 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
+ */
+
+#ifndef OPENSSL_OSSL_DESERIALIZERERR_H
+# define OPENSSL_OSSL_DESERIALIZERERR_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+# include <openssl/symhacks.h>
+
+
+# ifdef __cplusplus
+extern "C"
+# endif
+int ERR_load_OSSL_DESERIALIZER_strings(void);
+
+/*
+ * OSSL_DESERIALIZER function codes.
+ */
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+# endif
+
+/*
+ * OSSL_DESERIALIZER reason codes.
+ */
+# define OSSL_DESERIALIZER_R_MISSING_GET_PARAMS 100
+
+#endif
# define ERR_LIB_PROV 57
# define ERR_LIB_CMP 58
# define ERR_LIB_OSSL_SERIALIZER 59
-# define ERR_LIB_HTTP 60
+# define ERR_LIB_OSSL_DESERIALIZER 60
+# define ERR_LIB_HTTP 61
# define ERR_LIB_USER 128
typedef struct ossl_serializer_st OSSL_SERIALIZER;
typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX;
+typedef struct ossl_deserializer_st OSSL_DESERIALIZER;
+typedef struct ossl_deserializer_ctx_st OSSL_DESERIALIZER_CTX;
typedef struct ossl_self_test_st OSSL_SELF_TEST;
X509_STORE_load_locations_with_libctx ? 3_0_0 EXIST::FUNCTION:
X509_STORE_set_default_paths_with_libctx ? 3_0_0 EXIST::FUNCTION:
OSSL_STORE_open_with_libctx ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_fetch ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_up_ref ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_free ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_provider ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_properties ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_number ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_is_a ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_do_all_provided ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_names_do_all ? 3_0_0 EXIST::FUNCTION:
+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_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
+OSSL_DESERIALIZER_CTX_add_deserializer ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_CTX_add_extra ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_CTX_num_deserializers ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_CTX_set_finalizer ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_CTX_set_input_type ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_export ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_INSTANCE_deserializer ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_INSTANCE_deserializer_ctx ? 3_0_0 EXIST::FUNCTION:
+ERR_load_OSSL_DESERIALIZER_strings ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_gettable_params ? 3_0_0 EXIST::FUNCTION:
+OSSL_DESERIALIZER_get_params ? 3_0_0 EXIST::FUNCTION:
ERR_load_OBJ_strings(3)
ERR_load_OCSP_strings(3)
ERR_load_OSSL_SERIALIZER_strings(3)
+ERR_load_OSSL_DESERIALIZER_strings(3)
ERR_load_OSSL_STORE_strings(3)
ERR_load_PEM_strings(3)
ERR_load_PKCS12_strings(3)
OPENSSL_Applink external
OPENSSL_CTX datatype
NAMING_AUTHORITY datatype
+OSSL_DESERIALIZER datatype
+OSSL_DESERIALIZER_CTX datatype
+OSSL_DESERIALIZER_FINALIZER datatype
+OSSL_DESERIALIZER_CLEANER datatype
+OSSL_DESERIALIZER_INSTANCE datatype
+OSSL_DESERIALIZER_CTX datatype
OSSL_HTTP_bio_cb_t datatype
OSSL_PARAM datatype
OSSL_PROVIDER datatype