diff options
-rw-r--r-- | crypto/build.info | 2 | ||||
-rw-r--r-- | crypto/err/err.c | 2 | ||||
-rw-r--r-- | crypto/err/openssl.ec | 1 | ||||
-rw-r--r-- | crypto/property/property_parse.c | 2 | ||||
-rw-r--r-- | crypto/serializer/build.info | 1 | ||||
-rw-r--r-- | crypto/serializer/serializer_local.h | 34 | ||||
-rw-r--r-- | crypto/serializer/serializer_meth.c | 514 | ||||
-rw-r--r-- | doc/man3/OSSL_SERIALIZER.pod | 128 | ||||
-rw-r--r-- | doc/man3/OSSL_SERIALIZER_CTX.pod | 94 | ||||
-rw-r--r-- | doc/man7/openssl-core.h.pod | 23 | ||||
-rw-r--r-- | doc/man7/provider-serializer.pod | 227 | ||||
-rw-r--r-- | doc/man7/provider.pod | 8 | ||||
-rw-r--r-- | include/crypto/serializer.h | 13 | ||||
-rw-r--r-- | include/internal/cryptlib.h | 3 | ||||
-rw-r--r-- | include/openssl/core.h | 10 | ||||
-rw-r--r-- | include/openssl/core_numbers.h | 25 | ||||
-rw-r--r-- | include/openssl/err.h | 2 | ||||
-rw-r--r-- | include/openssl/pem.h | 1 | ||||
-rw-r--r-- | include/openssl/serializer.h | 59 | ||||
-rw-r--r-- | include/openssl/types.h | 5 | ||||
-rw-r--r-- | util/libcrypto.num | 14 | ||||
-rw-r--r-- | util/other.syms | 2 |
22 files changed, 1165 insertions, 5 deletions
diff --git a/crypto/build.info b/crypto/build.info index 5f90a2eda2..5beaf528be 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ - err comp ocsp cms ts srp cmac ct async ess crmf cmp + err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer LIBS=../libcrypto diff --git a/crypto/err/err.c b/crypto/err/err.c index bc33a06b7e..0fb46bef4d 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -75,6 +75,7 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"}, {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"}, {0, NULL}, }; @@ -111,6 +112,7 @@ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_DISABLED, "called a function that was disabled at compile-time"}, {ERR_R_INIT_FAIL, "init fail"}, {ERR_R_OPERATION_FAIL, "operation fail"}, + {ERR_R_INVALID_PROVIDER_FUNCTIONS, "invalid provider functions"}, {0, NULL}, }; diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index 211edd42f3..485c0c89ce 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -40,6 +40,7 @@ L OSSL_STORE include/openssl/store.h crypto/store/store_err.c L ESS include/openssl/ess.h crypto/ess/ess_err.c 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 # additional header files to be scanned for function names L NONE include/openssl/x509_vfy.h NONE diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index a16bcd6dba..f6377e7714 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -568,6 +568,8 @@ int ossl_property_parse_init(OPENSSL_CTX *ctx) "version", /* Version number of this provider */ "fips", /* FIPS supporting provider */ "engine", /* An old style engine masquerading as a provider */ + "format", /* output format for serializers */ + "type", /* output type for serializers */ }; size_t i; diff --git a/crypto/serializer/build.info b/crypto/serializer/build.info new file mode 100644 index 0000000000..7d69df931c --- /dev/null +++ b/crypto/serializer/build.info @@ -0,0 +1 @@ +SOURCE[../../libcrypto]=serializer_meth.c diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h new file mode 100644 index 0000000000..979ba83e78 --- /dev/null +++ b/crypto/serializer/serializer_local.h @@ -0,0 +1,34 @@ +/* + * Copyright 2019 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_numbers.h> +#include <openssl/types.h> +#include "internal/cryptlib.h" +#include "internal/refcount.h" + +struct ossl_serializer_st { + OSSL_PROVIDER *prov; + int id; + const char *propdef; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_serializer_newctx_fn *newctx; + OSSL_OP_serializer_freectx_fn *freectx; + OSSL_OP_serializer_set_ctx_params_fn *set_ctx_params; + OSSL_OP_serializer_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_serializer_serialize_data_fn *serialize_data; + OSSL_OP_serializer_serialize_object_fn *serialize_object; +}; + +struct ossl_serializer_ctx_st { + OSSL_SERIALIZER *ser; + void *serctx; +}; diff --git a/crypto/serializer/serializer_meth.c b/crypto/serializer/serializer_meth.c new file mode 100644 index 0000000000..103188f93a --- /dev/null +++ b/crypto/serializer/serializer_meth.c @@ -0,0 +1,514 @@ +/* + * Copyright 2019 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_numbers.h> +#include <openssl/serializer.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" + +/* + * Serializer can have multiple names, separated with colons in a name string + */ +#define NAME_SEPARATOR ':' + +/* Simple method structure constructor and destructor */ +static OSSL_SERIALIZER *ossl_serializer_new(void) +{ + OSSL_SERIALIZER *ser = NULL; + + if ((ser = OPENSSL_zalloc(sizeof(*ser))) == NULL + || (ser->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; + + return ser; +} + +int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser) +{ + int ref = 0; + + CRYPTO_UP_REF(&ser->refcnt, &ref, ser->lock); + return 1; +} + +void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser) +{ + int ref = 0; + + if (ser == NULL) + return; + + CRYPTO_DOWN_REF(&ser->refcnt, &ref, ser->lock); + if (ref > 0) + return; + ossl_provider_free(ser->prov); + CRYPTO_THREAD_lock_free(ser->lock); + OPENSSL_free(ser); +} + +/* Permanent serializer method store, constructor and destructor */ +static void serializer_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *serializer_store_new(OPENSSL_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OPENSSL_CTX_METHOD serializer_store_method = { + serializer_store_new, + serializer_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct serializer_data_st { + OPENSSL_CTX *libctx; + OSSL_METHOD_CONSTRUCT_METHOD *mcm; + int id; /* For get_serializer_from_store() */ + const char *names; /* For get_serializer_from_store() */ + const char *propquery; /* For get_serializer_from_store() */ +}; + +/* + * Generic routines to fetch / create SERIALIZER methods with + * ossl_method_construct() + */ + +/* Temporary serializer method store, constructor and destructor */ +static void *alloc_tmp_serializer_store(OPENSSL_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + static void dealloc_tmp_serializer_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent serializer store */ +static OSSL_METHOD_STORE *get_serializer_store(OPENSSL_CTX *libctx) +{ + return openssl_ctx_get_data(libctx, OPENSSL_CTX_SERIALIZER_STORE_INDEX, + &serializer_store_method); +} + +/* Get serializer methods from a store, or put one in */ +static void *get_serializer_from_store(OPENSSL_CTX *libctx, void *store, + void *data) +{ + struct serializer_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_serializer_store(libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) + return NULL; + return method; +} + +static int put_serializer_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_serializer_store(libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + (int (*)(void *))OSSL_SERIALIZER_up_ref, + (void (*)(void *))OSSL_SERIALIZER_free); +} + +/* Create and populate a serializer method */ +static void *serializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_SERIALIZER *ser = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + + if ((ser = ossl_serializer_new()) == NULL) + return NULL; + ser->id = id; + ser->propdef = algodef->property_definition; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_SERIALIZER_NEWCTX: + if (ser->newctx == NULL) + ser->newctx = + OSSL_get_OP_serializer_newctx(fns); + break; + case OSSL_FUNC_SERIALIZER_FREECTX: + if (ser->freectx == NULL) + ser->freectx = + OSSL_get_OP_serializer_freectx(fns); + break; + case OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS: + if (ser->set_ctx_params == NULL) + ser->set_ctx_params = + OSSL_get_OP_serializer_set_ctx_params(fns); + break; + case OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS: + if (ser->settable_ctx_params == NULL) + ser->settable_ctx_params = + OSSL_get_OP_serializer_settable_ctx_params(fns); + break; + case OSSL_FUNC_SERIALIZER_SERIALIZE_DATA: + if (ser->serialize_data == NULL) + ser->serialize_data = + OSSL_get_OP_serializer_serialize_data(fns); + break; + case OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT: + if (ser->serialize_object == NULL) + ser->serialize_object = + OSSL_get_OP_serializer_serialize_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 (!((ser->newctx == NULL && ser->freectx == NULL) + || (ser->newctx != NULL && ser->freectx != NULL)) + || (ser->serialize_data == NULL && ser->serialize_object == NULL)) { + OSSL_SERIALIZER_free(ser); + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + OSSL_SERIALIZER_free(ser); + return NULL; + } + + ser->prov = prov; + return ser; +} + + +/* + * The core fetching functionality passes the names of the implementation. + * This function is responsible to getting an identity number for them, + * then call serializer_from_dispatch() with that identity number. + */ +static void *construct_serializer(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *unused) +{ + /* + * This function is only called if get_serializer_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 = serializer_from_dispatch(id, algodef, prov); + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_serializer(void *method, void *data) +{ + OSSL_SERIALIZER_free(method); +} + +static int up_ref_serializer(void *method) +{ + return OSSL_SERIALIZER_up_ref(method); +} + +static void free_serializer(void *method) +{ + OSSL_SERIALIZER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by name */ +static OSSL_SERIALIZER *inner_ossl_serializer_fetch(OPENSSL_CTX *libctx, + int id, const char *name, + const char *properties) +{ + OSSL_METHOD_STORE *store = get_serializer_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_serializer_store, + dealloc_tmp_serializer_store, + get_serializer_from_store, + put_serializer_in_store, + construct_serializer, + destruct_serializer + }; + struct serializer_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_SERIALIZER, + 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_serializer_from_store() and + * put_serializer_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + ossl_method_store_cache_set(store, id, properties, method, + up_ref_serializer, free_serializer); + } + } + + return method; +} + +OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *libctx, const char *name, + const char *properties) +{ + return inner_ossl_serializer_fetch(libctx, 0, name, properties); +} + +OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id, + const char *properties) +{ + return inner_ossl_serializer_fetch(libctx, id, NULL, properties); +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER *ser) +{ + if (!ossl_assert(ser != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ser->prov; +} + +const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser) +{ + if (!ossl_assert(ser != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ser->propdef; +} + +int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser) +{ + if (!ossl_assert(ser != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ser->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); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == ser->id; + } + return 0; +} + +struct serializer_do_all_data_st { + void (*user_fn)(void *method, void *arg); + void *user_arg; +}; + +static void serializer_do_one(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algodef, + int no_store, void *vdata) +{ + struct serializer_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 = + serializer_from_dispatch(id, algodef, provider); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + OSSL_SERIALIZER_free(method); + } +} + +void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx, + void (*fn)(OSSL_SERIALIZER *ser, + void *arg), + void *arg) +{ + struct serializer_do_all_data_st data; + + data.user_fn = (void (*)(void *, void *))fn; + data.user_arg = arg; + ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, + serializer_do_one, &data); +} + +void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser, + void (*fn)(const char *name, void *data), + void *data) +{ + if (ser == NULL) + return; + + if (ser->prov != NULL) { + OPENSSL_CTX *libctx = ossl_provider_library_context(ser->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + ossl_namemap_doall_names(namemap, ser->id, fn, data); + } +} + +const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser) +{ + if (ser != NULL && ser->settable_ctx_params != NULL) + return ser->settable_ctx_params(); + return NULL; +} + +/* + * Serializer context support + */ + +/* + * |ser| value NULL is valid, and signifies that there is no serializer. + * This is useful to provide fallback mechanisms. + * Funtions that want to verify if there is a serializer can do so with + * OSSL_SERIALIZER_CTX_get_serializer() + */ +OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser) +{ + OSSL_SERIALIZER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ctx->ser = ser; + if (ser != NULL && ser->newctx != NULL) { + const OSSL_PROVIDER *prov = OSSL_SERIALIZER_provider(ser); + void *provctx = ossl_provider_ctx(prov); + + if (OSSL_SERIALIZER_up_ref(ser)) { + ctx->serctx = ser->newctx(provctx); + } else { + OSSL_SERIALIZER_free(ser); + OPENSSL_free(ctx); + ctx = NULL; + } + } + + return ctx; +} + +const OSSL_SERIALIZER * +OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ctx->ser; +} + + +int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx, + const OSSL_PARAM params[]) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->ser != NULL && ctx->ser->set_ctx_params != NULL) + return ctx->ser->set_ctx_params(ctx->serctx, params); + return 0; +} + +void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx) +{ + if (ctx != NULL) { + if (ctx->ser != NULL && ctx->ser->freectx != NULL) + ctx->ser->freectx(ctx->serctx); + OSSL_SERIALIZER_free(ctx->ser); + OPENSSL_free(ctx); + } +} diff --git a/doc/man3/OSSL_SERIALIZER.pod b/doc/man3/OSSL_SERIALIZER.pod new file mode 100644 index 0000000000..34767734f7 --- /dev/null +++ b/doc/man3/OSSL_SERIALIZER.pod @@ -0,0 +1,128 @@ +=pod + +=head1 NAME + +OSSL_SERIALIZER, +OSSL_SERIALIZER_fetch, +OSSL_SERIALIZER_up_ref, +OSSL_SERIALIZER_free, +OSSL_SERIALIZER_provider, +OSSL_SERIALIZER_properties, +OSSL_SERIALIZER_is_a, +OSSL_SERIALIZER_number, +OSSL_SERIALIZER_do_all_provided, +OSSL_SERIALIZER_names_do_all +- Serializer method routines + +=head1 SYNOPSIS + + #include <openssl/serializer.h> + + typedef struct ossl_serializer_st OSSL_SERIALIZER; + + OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *ctx, const char *name, + const char *properties); + int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *serializer); + void OSSL_SERIALIZER_free(OSSL_SERIALIZER *serializer); + const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER + *serializer); + const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser); + int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *serializer, + const char *name); + int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *serializer); + void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx, + void (*fn)(OSSL_SERIALIZER *serializer, + void *arg), + void *arg); + void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *serializer, + void (*fn)(const char *name, void *data), + void *data); + +=head1 DESCRIPTION + +=for comment Future development should also talk about deserialization + +B<OSSL_SERIALIZER> is a method for serializers, which know how to +serialize an object of some kind to a serialized form, such as PEM, +DER, or even human readable text. + +OSSL_SERIALIZER_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 serializer +method is expected to be able to serialize, 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_SERIALIZER_up_ref() increments the reference count for the given +I<serializer>. + +OSSL_SERIALIZER_free() decrements the reference count for the given +I<serializer>, and when the count reaches zero, frees it. + +OSSL_SERIALIZER_provider() returns the provider of the given +I<serializer>. + +OSSL_SERIALIZER_provider() returns the property definition associated +with the given I<serializer>. + +OSSL_SERIALIZER_is_a() checks if I<serializer> is an implementation of an +algorithm that's identifiable with I<name>. + +OSSL_SERIALIZER_number() returns the internal dynamic number assigned to +the given I<serializer>. + +OSSL_SERIALIZER_names_do_all() traverses all names for the given +I<serializer>, and calls I<fn> with each name and I<data>. + +OSSL_SERIALIZER_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. + +=head1 NOTES + +OSSL_SERIALIZER_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. + +=head1 RETURN VALUES + +OSSL_SERIALIZER_fetch() returns a pointer to the key management +implementation represented by an OSSL_SERIALIZER object, or NULL on +error. + +OSSL_SERIALIZER_up_ref() returns 1 on success, or 0 on error. + +OSSL_SERIALIZER_free() doesn't return any value. + +OSSL_SERIALIZER_provider() returns a pointer to a provider object, or +NULL on error. + +OSSL_SERIALIZER_properties() returns a pointer to a property +definition string, or NULL on error. + +OSSL_SERIALIZER_is_a() returns 1 of I<serializer> was identifiable, +otherwise 0. + +OSSL_SERIALIZER_number() returns an integer. + +=head1 SEE ALSO + +L<provider(7)>, L<OSSL_SERIALIZER_CTX(3)>, L<OPENSSL_CTX(3)> + +=head1 HISTORY + +The functions described here were added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 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 diff --git a/doc/man3/OSSL_SERIALIZER_CTX.pod b/doc/man3/OSSL_SERIALIZER_CTX.pod new file mode 100644 index 0000000000..d446b842d0 --- /dev/null +++ b/doc/man3/OSSL_SERIALIZER_CTX.pod @@ -0,0 +1,94 @@ +=pod + +=head1 NAME + +OSSL_SERIALIZER_CTX, +OSSL_SERIALIZER_CTX_new, +OSSL_SERIALIZER_CTX_get_serializer, +OSSL_SERIALIZER_settable_ctx_params, +OSSL_SERIALIZER_CTX_set_params, +OSSL_SERIALIZER_CTX_free +- Serializer context routines + +=head1 SYNOPSIS + + #include <openssl/serializer.h> + + typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX; + + OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser); + const OSSL_SERIALIZER * + OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx); + const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser); + int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx, + const OSSL_PARAM params[]); + void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx); + +=head1 DESCRIPTION + +B<OSSL_SERIALIZER_CTX> is a context with which B<OSSL_SERIALIZER> +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_SERIALIZER_CTX_new() creates a B<OSSL_SERIALIZER_CTX> associated +with the serializer I<ser>. NULL is a valid I<ser>, the context will +be created anyway, it's just not very useful. This is intentional, to +distinguish between errors in allocating the context or assigning it +values on one hand, and the lack of serializer support on the other. + +=begin comment + +The above distinction makes it possible for other routines to sense if +they need to report an error or fall back on other methods to +serialize. + +=end comment + +OSSL_SERIALIZER_CTX_get_serializer() gets the serializer method +currently associated with the context I<ctx>. + +OSSL_SERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)> +array of parameter descriptors. + +OSSL_SERIALIZER_CTX_set_params() attempts to set parameters specified +with an L<OSSL_PARAM(3)> array I<params>. Parameters that the +implementation doesn't recognise should be ignored. + +OSSL_SERIALIZER_CTX_free() frees the given context I<ctx>. + +=head1 RETURN VALUES + +OSSL_SERIALIZER_CTX_new() returns a pointer to a +B<OSSL_SERIALIZER_CTX>, or NULL if the context structure couldn't be +allocated. + +OSSL_SERIALIZER_CTX_get_serializer() returns a pointer to the +serializer method associated with I<ctx>. NULL is a valid return +value and signifies that there is no associated serializer method. + +OSSL_SERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)> +array, or NULL if none is available. + +OSSL_SERIALIZER_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_SERIALIZER(3)> + +=head1 HISTORY + +The functions described here were added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 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 diff --git a/doc/man7/openssl-core.h.pod b/doc/man7/openssl-core.h.pod index b5323e9d21..28307a97d4 100644 --- a/doc/man7/openssl-core.h.pod +++ b/doc/man7/openssl-core.h.pod @@ -76,7 +76,7 @@ B<OSSL_PARAM> is further described in L<OSSL_PARAM(3)> =item B<OSSL_C |