summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-08-16 21:25:08 +0200
committerRichard Levitte <levitte@openssl.org>2020-08-21 09:23:58 +0200
commitece9304c96f71277ca95696d9bc49fdec51e9f17 (patch)
tree7038f8760e1538754bc67371cb5a466a83935dad /crypto
parentRename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE (diff)
downloadopenssl-ece9304c96f71277ca95696d9bc49fdec51e9f17.tar.xz
openssl-ece9304c96f71277ca95696d9bc49fdec51e9f17.zip
Rename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE
Fixes #12455 Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12660)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asn1/i2d_pr.c14
-rw-r--r--crypto/build.info2
-rw-r--r--crypto/encode_decode/build.info8
-rw-r--r--crypto/encode_decode/decoder_err.c (renamed from crypto/serializer/deserializer_err.c)14
-rw-r--r--crypto/encode_decode/decoder_lib.c483
-rw-r--r--crypto/encode_decode/decoder_meth.c552
-rw-r--r--crypto/encode_decode/decoder_pkey.c (renamed from crypto/serializer/deserializer_pkey.c)141
-rw-r--r--crypto/encode_decode/encoder_err.c33
-rw-r--r--crypto/encode_decode/encoder_lib.c (renamed from crypto/serializer/serializer_lib.c)12
-rw-r--r--crypto/encode_decode/encoder_local.h140
-rw-r--r--crypto/encode_decode/encoder_meth.c523
-rw-r--r--crypto/encode_decode/encoder_pkey.c276
-rw-r--r--crypto/encode_decode/endecode_pass.c (renamed from crypto/serializer/serdes_pass.c)34
-rw-r--r--crypto/err/err.c4
-rw-r--r--crypto/err/openssl.ec12
-rw-r--r--crypto/err/openssl.txt6
-rw-r--r--crypto/evp/p_lib.c20
-rw-r--r--crypto/evp/pmeth_gn.c1
-rw-r--r--crypto/pem/pem_local.h38
-rw-r--r--crypto/pem/pem_pk8.c23
-rw-r--r--crypto/pem/pem_pkey.c1
-rw-r--r--crypto/property/property_parse.c6
-rw-r--r--crypto/serializer/build.info8
-rw-r--r--crypto/serializer/deserializer_lib.c488
-rw-r--r--crypto/serializer/deserializer_meth.c552
-rw-r--r--crypto/serializer/serializer_err.c33
-rw-r--r--crypto/serializer/serializer_local.h140
-rw-r--r--crypto/serializer/serializer_meth.c522
-rw-r--r--crypto/serializer/serializer_pkey.c275
-rw-r--r--crypto/x509/x_pubkey.c26
30 files changed, 2190 insertions, 2197 deletions
diff --git a/crypto/asn1/i2d_pr.c b/crypto/asn1/i2d_pr.c
index 545300cbab..84513db5bf 100644
--- a/crypto/asn1/i2d_pr.c
+++ b/crypto/asn1/i2d_pr.c
@@ -10,7 +10,7 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include "crypto/asn1.h"
@@ -31,17 +31,17 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
return ret;
}
if (a->keymgmt != NULL) {
- const char *serprop = OSSL_SERIALIZER_PrivateKey_TO_DER_PQ;
- OSSL_SERIALIZER_CTX *ctx =
- OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop);
+ const char *encprop = OSSL_ENCODER_PrivateKey_TO_DER_PQ;
+ OSSL_ENCODER_CTX *ctx =
+ OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, encprop);
BIO *out = BIO_new(BIO_s_mem());
BUF_MEM *buf = NULL;
int ret = -1;
if (ctx != NULL
&& out != NULL
- && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL
- && OSSL_SERIALIZER_to_bio(ctx, out)
+ && OSSL_ENCODER_CTX_get_encoder(ctx) != NULL
+ && OSSL_ENCODER_to_bio(ctx, out)
&& BIO_get_mem_ptr(out, &buf) > 0) {
ret = buf->length;
@@ -57,7 +57,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
}
}
BIO_free(out);
- OSSL_SERIALIZER_CTX_free(ctx);
+ OSSL_ENCODER_CTX_free(ctx);
return ret;
}
ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
diff --git a/crypto/build.info b/crypto/build.info
index 83625029c0..07e3dd526f 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 http ocsp cms ts srp cmac ct async ess crmf cmp serializer \
+ err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \
ffc
LIBS=../libcrypto
diff --git a/crypto/encode_decode/build.info b/crypto/encode_decode/build.info
new file mode 100644
index 0000000000..4686c4a19d
--- /dev/null
+++ b/crypto/encode_decode/build.info
@@ -0,0 +1,8 @@
+SOURCE[../../libcrypto]=endecode_pass.c
+
+SOURCE[../../libcrypto]=encoder_meth.c encoder_lib.c encoder_pkey.c
+SOURCE[../../libcrypto]=decoder_meth.c decoder_lib.c \
+ decoder_pkey.c
+
+SOURCE[../../libcrypto]=encoder_err.c
+SOURCE[../../libcrypto]=decoder_err.c
diff --git a/crypto/serializer/deserializer_err.c b/crypto/encode_decode/decoder_err.c
index 2cc245996f..984f7abeb9 100644
--- a/crypto/serializer/deserializer_err.c
+++ b/crypto/encode_decode/decoder_err.c
@@ -9,23 +9,23 @@
*/
#include <openssl/err.h>
-#include <openssl/deserializererr.h>
+#include <openssl/decodererr.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"},
+static const ERR_STRING_DATA OSSL_DECODER_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_MISSING_GET_PARAMS),
+ "missing get params"},
{0, NULL}
};
#endif
-int ERR_load_OSSL_DESERIALIZER_strings(void)
+int ERR_load_OSSL_DECODER_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);
+ if (ERR_reason_error_string(OSSL_DECODER_str_reasons[0].error) == NULL)
+ ERR_load_strings_const(OSSL_DECODER_str_reasons);
#endif
return 1;
}
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
new file mode 100644
index 0000000000..21b4703084
--- /dev/null
+++ b/crypto/encode_decode/decoder_lib.c
@@ -0,0 +1,483 @@
+/*
+ * 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 "encoder_local.h"
+#include "e_os.h"
+
+struct decoder_process_data_st {
+ OSSL_DECODER_CTX *ctx;
+
+ /* Current BIO */
+ BIO *bio;
+
+ /* Index of the current decoder instance to be processed */
+ size_t current_deser_inst_index;
+};
+
+static int decoder_process(const OSSL_PARAM params[], void *arg);
+
+int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in)
+{
+ struct decoder_process_data_st data;
+ int ok = 0;
+
+ memset(&data, 0, sizeof(data));
+ data.ctx = ctx;
+ data.bio = in;
+
+ ok = decoder_process(NULL, &data);
+
+ /* Clear any internally cached passphrase */
+ if (!ctx->flag_user_passphrase) {
+ OSSL_DECODER_CTX_set_passphrase(ctx, NULL, 0);
+ ctx->flag_user_passphrase = 0;
+ }
+ return ok;
+}
+
+#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_DECODER, ERR_R_BIO_LIB);
+ return NULL;
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ return b;
+}
+
+int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp)
+{
+ BIO *b = bio_from_file(fp);
+ int ret = 0;
+
+ if (b != NULL)
+ ret = OSSL_DECODER_from_bio(ctx, b);
+
+ BIO_free(b);
+ return ret;
+}
+#endif
+
+int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
+ const char *input_type)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, 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_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder)
+{
+ OSSL_DECODER_INSTANCE *decoder_inst = NULL;
+ const OSSL_PROVIDER *prov = NULL;
+ OSSL_PARAM params[2];
+ void *provctx = NULL;
+
+ if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (decoder->get_params == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DECODER,
+ OSSL_DECODER_R_MISSING_GET_PARAMS);
+ return 0;
+ }
+
+ if (ctx->decoder_insts == NULL
+ && (ctx->decoder_insts =
+ sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!OSSL_DECODER_up_ref(decoder)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ decoder_inst->decoder = decoder;
+
+ prov = OSSL_DECODER_provider(decoder_inst->decoder);
+ provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
+
+ /* Cache the input type for this encoder */
+ params[0] =
+ OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_TYPE,
+ (char **)&decoder_inst->input_type, 0);
+ params[1] = OSSL_PARAM_construct_end();
+
+ if (!decoder_inst->decoder->get_params(params)
+ || !OSSL_PARAM_modified(&params[0]))
+ goto err;
+
+ if ((decoder_inst->deserctx = decoder_inst->decoder->newctx(provctx))
+ == NULL)
+ goto err;
+
+ if (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, decoder_inst) <= 0)
+ goto err;
+
+ return 1;
+ err:
+ if (decoder_inst != NULL) {
+ if (decoder_inst->decoder != NULL)
+ decoder_inst->decoder->freectx(decoder_inst->deserctx);
+ OSSL_DECODER_free(decoder_inst->decoder);
+ OPENSSL_free(decoder_inst);
+ }
+ return 0;
+}
+
+int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
+ OPENSSL_CTX *libctx, const char *propq)
+{
+ /*
+ * This function goes through existing decoder methods in
+ * |ctx->decoder_insts|, and tries to fetch new decoders that produce
+ * what the existing ones want as input, and push those newly fetched
+ * decoders on top of the same stack.
+ * Then it does the same again, but looping over the newly fetched
+ * decoders, until there are no more encoders 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" decoders */
+ size_t w_new_start, w_new_end; /* "new" decoders */
+ 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_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ /*
+ * If there is no stack of OSSL_DECODER_INSTANCE, we have nothing
+ * more to add. That's fine.
+ */
+ if (ctx->decoder_insts == NULL)
+ return 1;
+
+ w_prev_start = 0;
+ w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_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_DECODER_INSTANCE *decoder_inst =
+ sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+ const char *name = decoder_inst->input_type;
+ OSSL_DECODER *decoder = NULL;
+
+ /*
+ * If the caller has specified what the initial input should be,
+ * and the decoder 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,
+ decoder_inst->input_type) != 0)
+ continue;
+
+ ERR_set_mark();
+ decoder = OSSL_DECODER_fetch(libctx, name, propq);
+ ERR_pop_to_mark();
+
+ if (decoder != NULL) {
+ size_t j;
+
+ /*
+ * Check that we don't already have this decoder in our
+ * stack We only need to check among the newly added ones.
+ */
+ for (j = w_new_start; j < w_new_end; j++) {
+ OSSL_DECODER_INSTANCE *check_inst =
+ sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, j);
+
+ if (decoder == check_inst->decoder) {
+ /* We found it, so drop the new fetch */
+ OSSL_DECODER_free(decoder);
+ decoder = NULL;
+ break;
+ }
+ }
+ }
+
+ if (decoder == 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_DECODER_CTX_add_decoder(ctx, decoder)) /* ref++ */
+ w_new_end++;
+ OSSL_DECODER_free(decoder); /* ref-- */
+ }
+ /* How many were added in this iteration */
+ count = w_new_end - w_new_start;
+
+ /* Slide the "previous decoder" windows */
+ w_prev_start = w_new_start;
+ w_prev_end = w_new_end;
+
+ depth++;
+ } while (count != 0 && depth <= 10);
+
+ return 1;
+}
+
+int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx)
+{
+ if (ctx == NULL || ctx->decoder_insts == NULL)
+ return 0;
+ return sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+}
+
+int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
+ OSSL_DECODER_CONSTRUCT *construct)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ctx->construct = construct;
+ return 1;
+}
+
+int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
+ void *construct_data)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ctx->construct_data = construct_data;
+ return 1;
+}
+
+int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
+ OSSL_DECODER_CLEANUP *cleanup)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ctx->cleanup = cleanup;
+ return 1;
+}
+
+OSSL_DECODER_CONSTRUCT *
+OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ return ctx->construct;
+}
+
+void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ return ctx->construct_data;
+}
+
+OSSL_DECODER_CLEANUP *
+OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ return ctx->cleanup;
+}
+
+int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
+ void *reference, size_t reference_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg)
+{
+ if (!(ossl_assert(decoder_inst != NULL)
+ && ossl_assert(reference != NULL)
+ && ossl_assert(export_cb != NULL)
+ && ossl_assert(export_cbarg != NULL))) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return decoder_inst->decoder->export_object(decoder_inst->deserctx,
+ reference, reference_sz,
+ export_cb, export_cbarg);
+}
+
+OSSL_DECODER *OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst)
+{
+ if (decoder_inst == NULL)
+ return NULL;
+ return decoder_inst->decoder;
+}
+
+void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst)
+{
+ if (decoder_inst == NULL)
+ return NULL;
+ return decoder_inst->deserctx;
+}
+
+static int decoder_process(const OSSL_PARAM params[], void *arg)
+{
+ struct decoder_process_data_st *data = arg;
+ OSSL_DECODER_CTX *ctx = data->ctx;
+ OSSL_DECODER_INSTANCE *decoder_inst = NULL;
+ OSSL_DECODER *decoder = NULL;
+ BIO *bio = data->bio;
+ long loc;
+ size_t i;
+ int ok = 0;
+ /* For recursions */
+ struct decoder_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_DECODER_CTX_num_decoders(ctx);
+
+ bio = data->bio;
+ } else {
+ const OSSL_PARAM *p;
+
+ decoder_inst =
+ sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts,
+ data->current_deser_inst_index);
+ decoder = OSSL_DECODER_INSTANCE_decoder(decoder_inst);
+
+ if (ctx->construct != NULL
+ && ctx->construct(decoder_inst, params, ctx->construct_data)) {
+ ok = 1;
+ goto end;
+ }
+
+ /* The constructor didn't return success */
+
+ /*
+ * so we try to use the object we got and feed it to any next
+ * decoder that will take it. Object references are not
+ * allowed for this.
+ * If this data isn't present, decoding has failed.
+ */
+
+ p = OSSL_PARAM_locate_const(params, OSSL_DECODER_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 decoders 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_DECODER, ERR_R_BIO_LIB);
+ goto end;
+ }
+
+ for (i = data->current_deser_inst_index; i-- > 0;) {
+ OSSL_DECODER_INSTANCE *new_deser_inst =
+ sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+ OSSL_DECODER *new_deser =
+ OSSL_DECODER_INSTANCE_decoder(new_deser_inst);
+
+ /*
+ * If |decoder| 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 (decoder == NULL && ctx->start_input_type != NULL
+ && strcasecmp(ctx->start_input_type,
+ new_deser_inst->input_type) != 0)
+ continue;
+
+ /*
+ * If we have a previous decoder, we check that the input type
+ * of the next to be used matches the type of this previous one.
+ * decoder_inst->input_type is a cache of the parameter "input-type"
+ * value for that decoder.
+ */
+ if (decoder != NULL
+ && !OSSL_DECODER_is_a(decoder, new_deser_inst->input_type))
+ continue;
+
+ /*
+ * Checking the return value of BIO_reset() or BIO_seek() is unsafe.
+ * Furthermore, BIO_reset() is unsafe to use if the source BIO happens
+ * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero
+ * no matter where we are in the underlying buffer we're reading from.
+ *
+ * So, we simply do a BIO_seek(), and use BIO_tell() that we're back
+ * at the same position. This is a best effort attempt, but BIO_seek()
+ * and BIO_tell() should come as a pair...
+ */
+ (void)BIO_seek(bio, loc);
+ if (BIO_tell(bio) != loc)
+ goto end;
+
+ /* Recurse */
+ new_data.current_deser_inst_index = i;
+ ok = new_deser->decode(new_deser_inst->deserctx, (OSSL_CORE_BIO *)bio,
+ decoder_process, &new_data,
+ ctx->passphrase_cb, new_data.ctx);
+ if (ok)
+ break;
+ }
+
+ end:
+ BIO_free(new_data.bio);
+ return ok;
+}
diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c
new file mode 100644
index 0000000000..2259c6348a
--- /dev/null
+++ b/crypto/encode_decode/decoder_meth.c
@@ -0,0 +1,552 @@
+/*
+ * 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/decoder.h>
+#include <openssl/ui.h>
+#include "internal/core.h"
+#include "internal/namemap.h"
+#include "internal/property.h"
+#include "internal/provider.h"
+#include "crypto/encoder.h"
+#include "encoder_local.h"
+
+static void OSSL_DECODER_INSTANCE_free(OSSL_DECODER_INSTANCE *instance);
+
+/*
+ * Decoder can have multiple names, separated with colons in a name string
+ */
+#define NAME_SEPARATOR ':'
+
+/* Simple method structure constructor and destructor */
+static OSSL_DECODER *ossl_decoder_new(void)
+{
+ OSSL_DECODER *decoder = NULL;
+
+ if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL
+ || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ OSSL_DECODER_free(decoder);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ decoder->base.refcnt = 1;
+
+ return decoder;
+}
+
+int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
+{
+ int ref = 0;
+
+ CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
+ return 1;
+}
+
+void OSSL_DECODER_free(OSSL_DECODER *decoder)
+{
+ int ref = 0;
+
+ if (decoder == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
+ if (ref > 0)
+ return;
+ ossl_provider_free(decoder->base.prov);
+ CRYPTO_THREAD_lock_free(decoder->base.lock);
+ OPENSSL_free(decoder);
+}
+
+/* Permanent decoder method store, constructor and destructor */
+static void decoder_store_free(void *vstore)
+{
+ ossl_method_store_free(vstore);
+}
+
+static void *decoder_store_new(OPENSSL_CTX *ctx)
+{
+ return ossl_method_store_new(ctx);
+}
+
+
+static const OPENSSL_CTX_METHOD decoder_store_method = {
+ decoder_store_new,
+ decoder_store_free,
+};
+
+/* Data to be passed through ossl_method_construct() */
+struct decoder_data_st {
+ OPENSSL_CTX *libctx;
+ OSSL_METHOD_CONSTRUCT_METHOD *mcm;
+ int id; /* For get_decoder_from_store() */
+ const char *names; /* For get_decoder_from_store() */
+ const char *propquery; /* For get_decoder_from_store() */
+};
+
+/*
+ * Generic routines to fetch / create DECODER methods with
+ * ossl_method_construct()
+ */
+
+/* Temporary decoder method store, constructor and destructor */
+static void *alloc_tmp_decoder_store(OPENSSL_CTX *ctx)
+{
+ return ossl_method_store_new(ctx);
+}
+
+static void dealloc_tmp_decoder_store(void *store)
+{
+ if (store != NULL)
+ ossl_method_store_free(store);
+}
+
+/* Get the permanent decoder store */
+static OSSL_METHOD_STORE *get_decoder_store(OPENSSL_CTX *libctx)
+{
+ return openssl_ctx_get_data(libctx, OPENSSL_CTX_DECODER_STORE_INDEX,
+ &decoder_store_method);
+}
+
+/* Get decoder methods from a store, or put one in */
+static void *get_decoder_from_store(OPENSSL_CTX *libctx, void *store,
+ void *data)
+{
+ struct decoder_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_decoder_store(libctx)) == NULL)
+ return NULL;
+
+ if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
+ return NULL;
+ return method;
+}
+
+static int put_decoder_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_decoder_store(libctx)) == NULL)
+ return 0;
+
+ return ossl_method_store_add(store, prov, id, propdef, method,
+ (int (*)(void *))OSSL_DECODER_up_ref,
+ (void (*)(void *))OSSL_DECODER_free);
+}
+
+/* Create and populate a decoder method */
+static void *decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
+ OSSL_PROVIDER *prov)
+{
+ OSSL_DECODER *decoder = NULL;
+ const OSSL_DISPATCH *fns = algodef->implementation;
+
+ if ((decoder = ossl_decoder_new()) == NULL)
+ return NULL;
+ decoder->base.id = id;
+ decoder->base.propdef = algodef->property_definition;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_DECODER_NEWCTX:
+ if (decoder->newctx == NULL)
+ decoder->newctx = OSSL_FUNC_decoder_newctx(fns);
+ break;
+ case OSSL_FUNC_DECODER_FREECTX:
+ if (decoder->freectx == NULL)
+ decoder->freectx = OSSL_FUNC_decoder_freectx(fns);
+ break;
+ case OSSL_FUNC_DECODER_GET_PARAMS:
+ if (decoder->get_params == NULL)
+ decoder->get_params =
+ OSSL_FUNC_decoder_get_params(fns);
+ break;
+ case OSSL_FUNC_DECODER_GETTABLE_PARAMS:
+ if (decoder->gettable_params == NULL)
+ decoder->gettable_params =
+ OSSL_FUNC_decoder_gettable_params(fns);
+ break;
+ case OSSL_FUNC_DECODER_SET_CTX_PARAMS:
+ if (decoder->set_ctx_params == NULL)
+ decoder->set_ctx_params =
+ OSSL_FUNC_decoder_set_ctx_params(fns);
+ break;
+ case OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS:
+ if (decoder->settable_ctx_params == NULL)
+ decoder->settable_ctx_params =
+ OSSL_FUNC_decoder_settable_ctx_params(fns);
+ break;
+ case OSSL_FUNC_DECODER_DECODE:
+ if (decoder->decode == NULL)
+ decoder->decode = OSSL_FUNC_decoder_decode(fns);
+ break;
+ case OSSL_FUNC_DECODER_EXPORT_OBJECT:
+ if (decoder->export_object == NULL)
+ decoder->export_object = OSSL_FUNC_decoder_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 encoding driver functions.
+ */
+ if (!((decoder->newctx == NULL && decoder->freectx == NULL)
+ || (decoder->newctx != NULL && decoder->freectx != NULL))
+ || (decoder->decode == NULL && decoder->export_object == NULL)) {
+ OSSL_DECODER_free(decoder);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
+ return NULL;
+ }
+
+ if (prov != NULL && !ossl_provider_up_ref(prov)) {
+ OSSL_DECODER_free(decoder);
+ return NULL;
+ }
+
+ decoder->base.prov = prov;
+ return decoder;
+}
+
+
+/*
+ * The core fetching functionality passes the names of the implementation.
+ * This function is responsible to getting an identity number for them,
+ * then call decoder_from_dispatch() with that identity number.
+ */
+static void *construct_decoder(const OSSL_ALGORITHM *algodef,
+ OSSL_PROVIDER *prov, void *unused)
+{
+ /*
+ * This function is only called if get_decoder_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 = decoder_from_dispatch(id, algodef, prov);
+
+ return method;
+}
+
+/* Intermediary function to avoid ugly casts, used below */
+static void destruct_decoder(void *method, void *data)
+{
+ OSSL_DECODER_free(method);
+}
+
+static int up_ref_decoder(void *method)
+{
+ return OSSL_DECODER_up_ref(method);
+}
+
+static void free_decoder(void *method)
+{
+ OSSL_DECODER_free(method);
+}
+
+/* Fetching support. Can fetch by numeric identity or by name */
+static OSSL_DECODER *inner_ossl_decoder_fetch(OPENSSL_CTX *libctx, int id,
+ const char *name,
+ const char *properties)
+{
+ OSSL_METHOD_STORE *store = get_decoder_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_decoder_store,
+ dealloc_tmp_decoder_store,
+ get_decoder_from_store,
+ put_decoder_in_store,
+ construct_decoder,
+ destruct_decoder
+ };
+ struct decoder_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_DECODER,
+ 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_decoder_from_store() and
+ * put_decoder_in_store() above.
+ */
+ if (id == 0)
+ id = ossl_namemap_name2num(namemap, name);
+ ossl_method_store_cache_set(store, id, properties, method,
+ up_ref_decoder, free_decoder);
+ }
+ }
+
+ return method;
+}
+
+OSSL_DECODER *OSSL_DECODER_fetch(OPENSSL_CTX *libctx, const char *name,
+ const char *properties)
+{
+ return inner_ossl_decoder_fetch(libctx, 0, name, properties);
+}
+
+OSSL_DECODER *ossl_decoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+ const char *properties)
+{
+ return inner_ossl_decoder_fetch(libctx, id, NULL, properties);
+}
+
+/*
+ * Library of basic method functions
+ */
+
+const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *decoder)
+{
+ if (!ossl_assert(decoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return decoder->base.prov;
+}
+
+const char *OSSL_DECODER_properties(const OSSL_DECODER *decoder)
+{
+ if (!ossl_assert(decoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return decoder->base.propdef;
+}
+
+int OSSL_DECODER_number(const OSSL_DECODER *decoder)
+{
+ if (!ossl_assert(decoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return decoder->base.id;
+}
+
+int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name)
+{
+ if (decoder->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(decoder->base.prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ return ossl_namemap_name2num(namemap, name) == decoder->base.id;
+ }
+ return 0;
+}
+
+struct decoder_do_all_data_st {
+ void (*user_fn)(void *method, void *arg);
+ void *user_arg;
+};
+
+static void decoder_do_one(OSSL_PROVIDER *provider,
+ const OSSL_ALGORITHM *algodef,
+ int no_store, void *vdata)
+{
+ struct decoder_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 =
+ decoder_from_dispatch(id, algodef, provider);
+
+ if (method != NULL) {
+ data->user_fn(method, data->user_arg);
+ OSSL_DECODER_free(method);
+ }
+}
+
+void OSSL_DECODER_do_all_provided(OPENSSL_CTX *libctx,
+ void (*fn)(OSSL_DECODER *decoder, void *arg),
+ void *arg)
+{
+ struct decoder_do_all_data_st data;
+
+ data.user_fn = (void (*)(void *, void *))fn;
+ data.user_arg = arg;
+ ossl_algorithm_do_all(libctx, OSSL_OP_DECODER, NULL,
+ NULL, decoder_do_one, NULL,
+ &data);
+}
+
+void OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder,
+ void (*fn)(const char *name, void *data),
+ void *data)
+{
+ if (decoder == NULL)
+ return;
+
+ if (decoder->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(decoder->base.prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ ossl_namemap_doall_names(namemap, decoder->base.id, fn, data);
+ }
+}
+
+const OSSL_PARAM *
+OSSL_DECODER_gettable_params(OSSL_DECODER *decoder)
+{
+ if (decoder != NULL && decoder->gettable_params != NULL) {
+ void *provctx = ossl_provider_ctx(OSSL_DECODER_provider(decoder));
+
+ return decoder->gettable_params(provctx);
+ }
+ return NULL;
+}
+
+int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[])
+{
+ if (decoder != NULL && decoder->get_params != NULL)
+ return decoder->get_params(params);
+ return 0;
+}
+
+const OSSL_PARAM *
+OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder)
+{
+ if (decoder != NULL && decoder->settable_ctx_params != NULL) {
+ void *provctx = ossl_provider_ctx(OSSL_DECODER_provider(decoder));
+
+ return decoder->settable_ctx_params(provctx);
+ }
+ return NULL;
+}
+
+/*
+ * Decoder context support
+ */
+
+/*
+ * |encoder| value NULL is valid, and signifies that there is no decoder.
+ * This is useful to provide fallback mechanisms.
+ * Functions that want to verify if there is a decoder can do so with
+ * OSSL_DECODER_CTX_get_decoder()
+ */
+OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void)
+{
+ OSSL_DECODER_CTX *ctx;
+
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ctx->passphrase_cb = ossl_decoder_passphrase_in_cb;
+ return ctx;
+}
+
+int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
+ const OSSL_PARAM params[])
+{
+ size_t i;
+ size_t l;
+
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (ctx->decoder_insts == NULL)
+ return 1;
+
+ l = (size_t)sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+ for (i = 0; i < l; i++) {
+ OSSL_DECODER_INSTANCE *decoder_inst =
+ sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+
+ if (decoder_inst->deserctx == NULL
+ || decoder_inst->decoder->set_ctx_params == NULL)
+ continue;
+ if (!decoder_inst->decoder->set_ctx_params(decoder_inst->deserctx, params))
+ return 0;
+ }
+ return 1;
+}
+
+static void
+OSSL_DECODER_INSTANCE_free(OSSL_DECODER_INSTANCE *decoder_inst)
+{
+ if (decoder_inst != NULL) {
+ if (decoder_inst->decoder->freectx != NULL)
+ decoder_inst->decoder->freectx(decoder_inst->deserctx);
+ decoder_inst->deserctx = NULL;
+ OSSL_DECODER_free(decoder_inst->decoder);
+ decoder_inst->decoder = NULL;
+ OPENSSL_free(decoder_inst);
+ decoder_inst = NULL;
+ }
+}
+
+void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx)
+{
+ if (ctx != NULL) {
+ if (ctx->cleanup != NULL)
+ ctx->cleanup(ctx->construct_data);
+ sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts,
+ OSSL_DECODER_INSTANCE_free);
+ OSSL_DECODER_CTX_set_passphrase_ui(ctx, NULL, NULL);
+ OSSL_DECODER_CTX_set_passphrase(ctx, NULL, 0);
+ OPENSSL_free(ctx);
+ }
+}
diff --git a/crypto/serializer/deserializer_pkey.c b/crypto/encode_decode/decoder_pkey.c
index 6375a29e36..7f468c2476 100644
--- a/crypto/serializer/deserializer_pkey.c
+++ b/crypto/encode_decode/decoder_pkey.c
@@ -10,17 +10,17 @@
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/ui.h>
-#include <openssl/deserializer.h>
+#include <openssl/decoder.h>
#include <openssl/safestack.h>
#include "crypto/evp.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
-int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
- const unsigned char *kstr,
- size_t klen)
+int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
+ const unsigned char *kstr,
+ size_t klen)
{
if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -36,7 +36,7 @@ int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
ctx->cached_passphrase_len = klen;
}
if (ctx->cached_passphrase == NULL) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -44,7 +44,7 @@ int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
return 1;
}
-static void deserializer_ctx_reset_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx)
+static void decoder_ctx_reset_passphrase_ui(OSSL_DECODER_CTX *ctx)
{
UI_destroy_method(ctx->allocated_ui_method);
ctx->allocated_ui_method = NULL;
@@ -52,28 +52,28 @@ static void deserializer_ctx_reset_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx)
ctx->ui_data = NULL;
}
-int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
- const UI_METHOD *ui_method,
- void *ui_data)
+int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
+ const UI_METHOD *ui_method,
+ void *ui_data)
{
if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- deserializer_ctx_reset_passphrase_ui(ctx);
+ decoder_ctx_reset_passphrase_ui(ctx);
ctx->ui_method = ui_method;
ctx->ui_data = ui_data;
return 1;
}
-int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
- pem_password_cb *cb, void *cbarg)
+int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
+ pem_password_cb *cb, void *cbarg)
{
UI_METHOD *ui_method = NULL;
if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -84,10 +84,10 @@ int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
*/
if (cb == NULL
|| (ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) != NULL) {
- deserializer_ctx_reset_passphrase_ui(ctx);
+ decoder_ctx_reset_passphrase_ui(ctx);
ctx->ui_method = ctx->allocated_ui_method = ui_method;
ctx->ui_data = cbarg;
- ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb;
+ ctx->passphrase_cb = ossl_decoder_passphrase_in_cb;
return 1;
}
@@ -95,26 +95,26 @@ int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
}
/*
- * Support for OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY:
+ * Support for OSSL_DECODER_CTX_new_by_EVP_PKEY:
* The construct data, and collecting keymgmt information for it
*/
DEFINE_STACK_OF(EVP_KEYMGMT)
-struct deser_EVP_PKEY_data_st {
+struct decoder_EVP_PKEY_data_st {
char *object_type; /* recorded object data type, may be NULL */
void **object; /* Where the result should end up */
STACK_OF(EVP_KEYMGMT) *keymgmts; /* The EVP_KEYMGMTs we handle */
};
-static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
- const OSSL_PARAM *params,
- void *construct_data)
+static int decoder_construct_EVP_PKEY(OSSL_DECODER_INSTANCE *decoder_inst,
+ const OSSL_PARAM *params,
+ void *construct_data)
{
- struct deser_EVP_PKEY_data_st *data = construct_data;
- OSSL_DESERIALIZER *deser =
- OSSL_DESERIALIZER_INSTANCE_deserializer(deser_inst);
- void *deserctx = OSSL_DESERIALIZER_INSTANCE_deserializer_ctx(deser_inst);
+ struct decoder_EVP_PKEY_data_st *data = construct_data;
+ OSSL_DECODER *decoder =
+ OSSL_DECODER_INSTANCE_decoder(decoder_inst);
+ void *deserctx = OSSL_DECODER_INSTANCE_decoder_ctx(decoder_inst);
size_t i, end_i;
/*
* |object_ref| points to a provider reference to an object, its exact
@@ -128,7 +128,7 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
size_t object_ref_sz = 0;
const OSSL_PARAM *p;
- p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_DATA_TYPE);
+ p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_DATA_TYPE);
if (p != NULL) {
char *object_type = NULL;
@@ -143,7 +143,7 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
* reference for the moment. This enforces that the key data itself
* remains with the provider.
*/
- p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_REFERENCE);
+ p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_REFERENCE);
if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
return 0;
object_ref = p->data;
@@ -160,35 +160,35 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
* 1. If the object data type (recorded in |data->object_type|)
* is defined, by checking it using EVP_KEYMGMT_is_a().
* 2. If the object data type is NOT defined, by comparing the
- * EVP_KEYMGMT and OSSL_DESERIALIZER method numbers. Since
- * EVP_KEYMGMT and OSSL_DESERIALIZE operate with the same
+ * EVP_KEYMGMT and OSSL_DECODER method numbers. Since
+ * EVP_KEYMGMT and OSSL_DECODE operate with the same
* namemap, we know that the method numbers must match.
*
- * This allows individual deserializers to specify variants of keys,
- * such as a DER to RSA deserializer finding a RSA-PSS key, without
- * having to deserialize the exact same DER blob into the exact same
+ * This allows individual decoders to specify variants of keys,
+ * such as a DER to RSA decoder finding a RSA-PSS key, without
+ * having to decode the exact same DER blob into the exact same
* internal structure twice. This is, of course, entirely at the
- * discretion of the deserializer implementations.
+ * discretion of the decoder implementations.
*/
if (data->object_type != NULL
? EVP_KEYMGMT_is_a(keymgmt, data->object_type)
- : EVP_KEYMGMT_number(keymgmt) == OSSL_DESERIALIZER_number(deser)) {
+ : EVP_KEYMGMT_number(keymgmt) == OSSL_DECODER_number(decoder)) {
EVP_PKEY *pkey = NULL;
void *keydata = NULL;
const OSSL_PROVIDER *keymgmt_prov =
EVP_KEYMGMT_provider(keymgmt);
- const OSSL_PROVIDER *deser_prov =
- OSSL_DESERIALIZER_provider(deser);
+ const OSSL_PROVIDER *decoder_prov =
+ OSSL_DECODER_provider(decoder);
/*
- * If the EVP_KEYMGMT and the OSSL_DESERIALIZER are from the
+ * If the EVP_KEYMGMT and the OSSL_DECODER are from the
* same provider, we assume that the KEYMGMT has a key loading
* function that can handle the provider reference we hold.
*
- * Otherwise, we export from the deserializer and import the
+ * Otherwise, we export from the decoder and import the
* result in the keymgmt.
*/
- if (keymgmt_prov == deser_prov) {
+ if (keymgmt_prov == decoder_prov) {
keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz);
} else {
struct evp_keymgmt_util_try_import_data_st import_data;
@@ -201,9 +201,9 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
* No need to check for errors here, the value of
* |import_data.keydata| is as much an indicator.
*/
- (void)deser->export_object(deserctx, object_ref, object_ref_sz,
- &evp_keymgmt_util_try_import,
- &import_data);
+ (void)decoder->export_object(deserctx, object_ref, object_ref_sz,
+ &evp_keymgmt_util_try_import,
+ &import_data);
keydata = import_data.keydata;
import_data.keydata = NULL;
}
@@ -225,9 +225,9 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
return (*data->object != NULL);
}
-static void deser_clean_EVP_PKEY_construct_arg(void *construct_data)
+static void decoder_clean_EVP_PKEY_construct_arg(void *construct_data)
{
- struct deser_EVP_PKEY_data_st *data = construct_data;
+ struct decoder_EVP_PKEY_data_st *data = construct_data;
if (data != NULL) {
sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free);
@@ -239,9 +239,9 @@ static void deser_clean_EVP_PKEY_construct_arg(void *construct_data)
DEFINE_STACK_OF_CSTRING()
struct collected_data_st {
- struct deser_EVP_PKEY_data_st *process_data;
+ struct decoder_EVP_PKEY_data_st *process_data;
STACK_OF(OPENSSL_CSTRING) *names;
- OSSL_DESERIALIZER_CTX *ctx;
+ OSSL_DECODER_CTX *ctx;
unsigned int error_occured:1;
};
@@ -280,7 +280,7 @@ static void collect_name(const char *name, void *arg)
data->error_occured = 0; /* All is good now */
}
-static void collect_deserializer(OSSL_DESERIALIZER *deser, void *arg)
+static void collect_decoder(OSSL_DECODER *decoder, void *arg)
{
struct collected_data_st *data = arg;
size_t i, end_i;
@@ -294,37 +294,36 @@ static void collect_deserializer(OSSL_DESERIALIZER *deser, void *arg)
for (i = 0; i < end_i; i++) {
const char *name = sk_OPENSSL_CSTRING_value(data->names, i);
- if (!OSSL_DESERIALIZER_is_a(deser, name))
+ if (!OSSL_DECODER_is_a(decoder, name))
continue;
- (void)OSSL_DESERIALIZER_CTX_add_deserializer(data->ctx, deser);
+ (void)OSSL_DECODER_CTX_add_decoder(data->ctx, decoder);
}
data->error_occured = 0; /* All is good now */
}
-OSSL_DESERIALIZER_CTX *
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
- const char *input_type,
- OPENSSL_CTX *libctx,
- const char *propquery)
+OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
+ const char *input_type,
+ OPENSSL_CTX *libctx,
+ const char *propquery)
{
- OSSL_DESERIALIZER_CTX *ctx = NULL;
+ OSSL_DECODER_CTX *ctx = NULL;
struct collected_data_st *data = NULL;
size_t i, end_i;
- if ((ctx = OSSL_DESERIALIZER_CTX_new()) == NULL
+ if ((ctx = OSSL_DECODER_CTX_new()) == NULL
|| (data = OPENSSL_zalloc(sizeof(*data))) == NULL
|| (data->process_data =
OPENSSL_zalloc(sizeof(*data->process_data))) == NULL
|| (data->process_data->keymgmts
= sk_EVP_KEYMGMT_new_null()) == NULL
|| (data->names = sk_OPENSSL_CSTRING_new_null()) == NULL) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
goto err;
}
data->process_data->object = (void **)pkey;
data->ctx = ctx;
- OSSL_DESERIALIZER_CTX_set_input_type(ctx, input_type);
+ OSSL_DECODER_CTX_set_input_type(ctx, input_type);
/* First, find all keymgmts to form goals */
EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, data);
@@ -345,30 +344,30 @@ OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
}
/*
- * Finally, find all deserializers that have any keymgmt of the collected
+ * Finally, find all decoders that have any keymgmt of the collected
* keymgmt names
*/
- OSSL_DESERIALIZER_do_all_provided(libctx, collect_deserializer, data);
+ OSSL_DECODER_do_all_provided(libctx, collect_decoder, data);
if (data->error_occured)
goto err;
- /* If we found no deserializers to match the keymgmts, we err */
- if (OSSL_DESERIALIZER_CTX_num_deserializers(ctx) == 0)
+ /* If we found no decoders to match the keymgmts, we err */
+ if (OSSL_DECODER_CTX_num_decoders(ctx) == 0)
goto err;
- /* Finally, collect extra deserializers based on what we already have */
- (void)OSSL_DESERIALIZER_CTX_add_extra(ctx, libctx, propquery);
+ /* Finally, collect extra decoders based on what we already have */
+ (void)OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery);
- if (!OSSL_DESERIALIZER_CTX_set_construct(ctx, deser_construct_EVP_PKEY)
- || !OSSL_DESERIALIZER_CTX_set_construct_data(ctx, data->process_data)
- || !OSSL_DESERIALIZER_CTX_set_cleanup
- (ctx, deser_clean_EVP_PKEY_construct_arg))
+ if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_EVP_PKEY)
+ || !OSSL_DECODER_CTX_set_construct_data(ctx, data->process_data)
+ || !OSSL_DECODER_CTX_set_cleanup(ctx,
+ decoder_clean_EVP_PKEY_construct_arg))
goto err;
data->process_data = NULL;
err:
- deser_clean_EVP_PKEY_construct_arg(data->process_data);
+ decoder_clean_EVP_PKEY_construct_arg(data->process_data);
sk_OPENSSL_CSTRING_free(data->names);
OPENSSL_free(data);
return ctx;
diff --git a/crypto/encode_decode/encoder_err.c b/crypto/encode_decode/encoder_err.c
new file mode 100644
index 0000000000..5416f8390e
--- /dev/null
+++ b/crypto/encode_decode/encoder_err.c
@@ -0,0 +1,33 @@
+/*
+ * 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/encodererr.h>
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA OSSL_ENCODER_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY),
+ "incorrect property query"},
+ {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_ENCODER_NOT_FOUND),
+ "encoder not found"},
+ {0, NULL}
+};
+
+#endif
+
+int ERR_load_OSSL_ENCODER_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ if (ERR_reason_error_string(OSSL_ENCODER_str_reasons[0].error) == NULL)
+ ERR_load_strings_const(OSSL_ENCODER_str_reasons);
+#endif
+ return 1;
+}
diff --git a/crypto/serializer/serializer_lib.c b/crypto/encode_decode/encoder_lib.c
index 932ef1e3ae..b083fa2d4c 100644
--- a/crypto/serializer/serializer_lib.c
+++ b/crypto/encode_decode/encoder_lib.c
@@ -8,10 +8,10 @@
*/
#include <openssl/bio.h>
-#include <openssl/serializer.h>
-#include "serializer_local.h"
+#include <openssl/encoder.h>
+#include "encoder_local.h"
-int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
+int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out)
{
return ctx->do_output(ctx, out);
}
@@ -22,20 +22,20 @@ static BIO *bio_from_file(FILE *fp)
BIO *b;
if ((b = BIO_new(BIO_s_file())) == NULL) {
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_BUF_LIB);
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_BUF_LIB);
return NULL;
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
return b;
}
-int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp)
+int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp)
{
BIO *b = bio_from_file(fp);
int ret = 0;
if (b != NULL)
- ret = OSSL_SERIALIZER_to_bio(ctx, b);
+ ret = OSSL_ENCODER_to_bio(ctx, b);
BIO_free(b);
return ret;
diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h
new file mode 100644
index 0000000000..34931d4e43
--- /dev/null
+++ b/crypto/encode_decode/encoder_local.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2019-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_dispatch.h>
+#include <openssl/types.h>
+#include <openssl/safestack.h>
+#include <openssl/encoder.h>
+#include <openssl/decoder.h>
+#include "internal/cryptlib.h"
+#include "internal/refcount.h"
+
+struct ossl_serdes_base_st {
+ OSSL_PROVIDER *prov;
+ int id;
+ const char *propdef;
+
+ CRYPTO_REF_COUNT refcnt;
+ CRYPTO_RWLOCK *lock;
+};
+
+struct ossl_encoder_st {
+ struct ossl_serdes_base_st base;
+ OSSL_FUNC_encoder_newctx_fn *newctx;
+ OSSL_FUNC_encoder_freectx_fn *freectx;
+ OSSL_FUNC_encoder_set_ctx_params_fn *set_ctx_params;
+ OSSL_FUNC_encoder_settable_ctx_params_fn *settable_ctx_params;
+ OSSL_FUNC_encoder_encode_data_fn *encode_data;
+ OSSL_FUNC_encoder_encode_object_fn *encode_object;
+};
+
+struct ossl_decoder_st {
+ struct ossl_serdes_base_st base;
+ OSSL_FUNC_decoder_newctx_fn *newctx;
+ OSSL_FUNC_decoder_freectx_fn *freectx;
+ OSSL_FUNC_decoder_get_params_fn *get_params;
+ OSSL_FUNC_decoder_gettable_params_fn *gettable_params;
+ OSSL_FUNC_decoder_set_ctx_params_fn *set_ctx_params;
+ OSSL_FUNC_decoder_settable_ctx_params_fn *settable_ctx_params;
+ OSSL_FUNC_decoder_decode_fn *decode;
+ OSSL_FUNC_decoder_export_object_fn *export_object;
+};
+
+struct ossl_encoder_ctx_st {
+ OSSL_ENCODER *encoder;
+ void *serctx;
+
+ int selection;
+
+ /*-
+ * Output / encoding data, used by OSSL_ENCODER_to_{bio,fp}
+ *
+ * |object| is the libcrypto object to handle.
+ * |do_output| performs the actual encoding.
+ *
+ * |do_output| must have intimate knowledge of |object|.
+ */
+ const void *object;
+ int (*do_output)(OSSL_ENCODER_CTX *ctx, BIO *out);
+
+ /* For any function that needs a passphrase reader */
+ const UI_METHOD *ui_method;
+ void *ui_data;
+ /*
+ * if caller used OSSL_ENCODER_CTX_set_passphrase_cb(), we need
+ * intermediary storage.
+ */
+ UI_METHOD *allocated_ui_method;
+};
+
+struct ossl_decoder_instance_st {
+ OSSL_DECODER *decoder; /* Never NULL */
+ void *deserctx; /* Never NULL */
+ const char *input_type; /* Never NULL */
+};
+
+DEFINE_STACK_OF(OSSL_DECODER_INSTANCE)
+
+struct ossl_decoder_ctx_st {
+ /*
+ * The caller may know the input type of the data they pass. If not,
+ * this will remain NULL and the decoding functionality will start
+ * with trying to decode with any desencoder in |decoder_insts|,
+ * regardless of their respective input type.
+ */
+ const char *start_input_type;
+
+ /*
+ * Decoders that are components of any current decoding path.
+ */
+ STACK_OF(OSSL_DECODER_INSTANCE) *decoder_insts;
+
+ /*
+ * The constructors of a decoding, and its caller argument.
+ */
+ OSSL_DECODER_CONSTRUCT *construct;
+ OSSL_DECODER_CLEANUP *cleanup;
+ void *construct_data;
+
+ /* For any function that needs a passphrase reader */
+ OSSL_PASSPHRASE_CALLBACK *passphrase_cb;
+ const UI_METHOD *ui_method;
+ void *ui_data;
+ /*
+ * if caller used OSSL_ENCODER_CTX_set_pem_password_cb(), we need
+ * intermediary storage.
+ */
+ UI_METHOD *allocated_ui_method;
+ /*
+ * Because the same input may pass through more than one decoder,
+ * we cache any passphrase passed to us. The desrializing processor
+ * must clear this at the end of a run.
+ */
+ unsigned char *cached_passphrase;
+ size_t cached_passphrase_len;
+
+ /*
+ * Flag section. Keep these together
+ */
+
+ /*
+ * The passphrase was passed to us by the user. In that case, it
+ * should only be freed when freeing this context.
+ */
+ unsigned int flag_user_passphrase:1;
+};
+
+/* Passphrase callbacks, found in serdes_pass.c */
+
+/*
+ * Encoders typically want to get an outgoing passphrase, while
+ * decoders typically want to get en incoming passphrase.
+ */
+OSSL_PASSPHRASE_CALLBACK ossl_encoder_passphrase_out_cb;
+OSSL_PASSPHRASE_CALLBACK ossl_decoder_passphrase_in_cb;
diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c
new file mode 100644
index 0000000000..ef3c24433e
--- /dev/null
+++ b/crypto/encode_decode/encoder_meth.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2019-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/encoder.h>
+#include <openssl/ui.h>
+#include "internal/core.h"
+#include "internal/namemap.h"
+#include "internal/property.h"
+#include "internal/provider.h"
+#include "crypto/encoder.h"
+#include "encoder_local.h"
+
+/*
+ * Encoder can have multiple names, separated with colons in a name string
+ */
+#define NAME_SEPARATOR ':'
+
+/* Simple method structure constructor and destructor */
+static OSSL_ENCODER *ossl_encoder_new(void)
+{
+ OSSL_ENCODER *encoder = NULL;
+
+ if ((encoder = OPENSSL_zalloc(sizeof(*encoder))) == NULL
+ || (encoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ OSSL_ENCODER_free(encoder);
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ encoder->base.refcnt = 1;
+
+ return encoder;
+}
+
+int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder)
+{
+ int ref = 0;
+
+ CRYPTO_UP_REF(&encoder->base.refcnt, &ref, encoder->base.lock);
+ return 1;
+}
+
+void OSSL_ENCODER_free(OSSL_ENCODER *encoder)
+{
+ int ref = 0;
+
+ if (encoder == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref, encoder->base.lock);
+ if (ref > 0)
+ return;
+ ossl_provider_free(encoder->base.prov);
+ CRYPTO_THREAD_lock_free(encoder->base.lock);
+ OPENSSL_free(encoder);
+}
+
+/* Permanent encoder method store, constructor and destructor */
+static void encoder_store_free(void *vstore)
+{
+ ossl_method_store_free(vstore);
+}
+
+static void *encoder_store_new(OPENSSL_CTX *ctx)
+{
+ return ossl_method_store_new(ctx);
+}
+
+
+static const OPENSSL_CTX_METHOD encoder_store_method = {
+ encoder_store_new,
+ encoder_store_free,
+};
+
+/* Data to be passed through ossl_method_construct() */
+struct encoder_data_st {
+ OPENSSL_CTX *libctx;
+ OSSL_METHOD_CONSTRUCT_METHOD *mcm;
+ int id; /* For get_encoder_from_store() */
+ const char *names; /* For get_encoder_from_store() */
+ const char *propquery; /* For get_encoder_from_store() */
+};
+
+/*
+ * Generic routines to fetch / create ENCODER methods with
+ * ossl_method_construct()
+ */
+
+/* Temporary encoder method store, constructor and destructor */
+static void *alloc_tmp_encoder_store(OPENSSL_CTX *ctx)
+{
+ return ossl_method_store_new(ctx);
+}
+
+static void dealloc_tmp_encoder_store(void *store)
+{
+ if (store != NULL)
+ ossl_method_store_free(store);
+}
+
+/* Get the permanent encoder store */
+static OSSL_METHOD_STORE *get_encoder_store(OPENSSL_CTX *libctx)
+{
+ return openssl_ctx_get_data(libctx, OPENSSL_CTX_ENCODER_STORE_INDEX,
+ &encoder_store_method);
+}
+
+/* Get encoder methods from a store, or put one in */
+static void *get_encoder_from_store(OPENSSL_CTX *libctx, void *store,
+ void *data)
+{
+ struct encoder_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_encoder_store(libctx)) == NULL)
+ return NULL;
+
+ if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
+ return NULL;
+ return method;
+}
+
+static int put_encoder_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_encoder_store(libctx)) == NULL)
+ return 0;
+
+ return ossl_method_store_add(store, prov, id, propdef, method,
+ (int (*)(void *))OSSL_ENCODER_up_ref,
+ (void (*)(void *))OSSL_ENCODER_free);
+}
+
+/* Create and populate a encoder method */
+static void *encoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
+ OSSL_PROVIDER *prov)
+{
+ OSSL_ENCODER *encoder = NULL;
+ const OSSL_DISPATCH *fns = algodef->implementation;
+
+ if ((encoder = ossl_encoder_new()) == NULL)
+ return NULL;
+ encoder->base.id = id;
+ encoder->base.propdef = algodef->property_definition;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_ENCODER_NEWCTX:
+ if (encoder->newctx == NULL)
+ encoder->newctx =
+ OSSL_FUNC_encoder_newctx(fns);
+ break;
+ case OSSL_FUNC_ENCODER_FREECTX:
+ if (encoder->freectx == NULL)
+ encoder->freectx =
+ OSSL_FUNC_encoder_freectx(fns);
+ break;
+ case OSSL_FUNC_ENCODER_SET_CTX_PARAMS:
+ if (encoder->set_ctx_params == NULL)
+ encoder->set_ctx_params =
+ OSSL_FUNC_encoder_set_ctx_params(fns);
+ break;
+ case OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS:
+ if (encoder->settable_ctx_params == NULL)
+ encoder->settable_ctx_params =
+ OSSL_FUNC_encoder_settable_ctx_params(fns);
+ break;
+ case OSSL_FUNC_ENCODER_ENCODE_DATA:
+ if (encoder->encode_data == NULL)
+ encoder->encode_data =
+ OSSL_FUNC_encoder_encode_data(fns);
+ break;
+ case OSSL_FUNC_ENCODER_ENCODE_OBJECT:
+ if (encoder->encode_object == NULL)
+ encoder->encode_object =
+ OSSL_FUNC_encoder_encode_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 encoding driver functions.
+ */
+ if (!((encoder->newctx == NULL && encoder->freectx == NULL)
+ || (encoder->newctx != NULL && encoder->freectx != NULL))
+ || (encoder->encode_data == NULL && encoder->encode_object == NULL)) {
+ OSSL_ENCODER_free(encoder);
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
+ return NULL;
+ }
+
+ if (prov != NULL && !ossl_provider_up_ref(prov)) {
+ OSSL_ENCODER_free(encoder);
+ return NULL;
+ }
+
+ encoder->base.prov = prov;
+ return encoder;
+}
+
+
+/*
+ * The core fetching functionality passes the names of the implementation.
+ * This function is responsible to getting an identity number for them,
+ * then call encoder_from_dispatch() with that identity number.
+ */
+static void *construct_encoder(const OSSL_ALGORITHM *algodef,
+ OSSL_PROVIDER *prov, void *unused)
+{
+ /*
+ * This function is only called if get_encoder_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 = encoder_from_dispatch(id, algodef, prov);
+
+ return method;
+}
+
+/* Intermediary function to avoid ugly casts, used below */
+static void destruct_encoder(void *method, void *data)
+{
+ OSSL_ENCODER_free(method);
+}
+
+static int up_ref_encoder(void *method)
+{
+ return OSSL_ENCODER_up_ref(method);
+}
+
+static void free_encoder(void *method)
+{
+ OSSL_ENCODER_free(method);
+}
+
+/* Fetching support. Can fetch by numeric identity or by name */
+static OSSL_ENCODER *inner_ossl_encoder_fetch(OPENSSL_CTX *libctx,
+ int id, const char *name,
+ const char *properties)
+{
+ OSSL_METHOD_STORE *store = get_encoder_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_encoder_store,
+ dealloc_tmp_encoder_store,
+ get_encoder_from_store,
+ put_encoder_in_store,
+ construct_encoder,
+ destruct_encoder
+ };
+ struct encoder_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_ENCODER,
+ 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_encoder_from_store() and
+ * put_encoder_in_store() above.
+ */
+ if (id == 0)
+ id = ossl_namemap_name2num(namemap, name);
+ ossl_method_store_cache_set(store, id, properties, method,
+ up_ref_encoder, free_encoder);
+ }
+ }
+
+ return method;
+}
+
+OSSL_ENCODER *OSSL_ENCODER_fetch(OPENSSL_CTX *libctx, const char *name,
+ const char *properties)
+{
+ return inner_ossl_encoder_fetch(libctx, 0, name, properties);
+}
+
+OSSL_ENCODER *ossl_encoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+ const char *properties)
+{
+ return inner_ossl_encoder_fetch(libctx, id, NULL, properties);
+}
+
+/*
+ * Library of basic method functions
+ */
+
+const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder)
+{
+ if (!ossl_assert(encoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return encoder->base.prov;
+}
+
+const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder)
+{
+ if (!ossl_assert(encoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return encoder->base.propdef;
+}
+
+int OSSL_ENCODER_number(const OSSL_ENCODER *encoder)
+{
+ if (!ossl_assert(encoder != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return encoder->base.id;
+}
+
+int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name)
+{
+ if (encoder->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(encoder->base.prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ return ossl_namemap_name2num(namemap, name) == encoder->base.id;
+ }
+ return 0;
+}
+
+struct encoder_do_all_data_st {
+ void (*user_fn)(void *method, void *arg);
+ void *user_arg;
+};
+
+static void encoder_do_one(OSSL_PROVIDER *provider,
+ const OSSL_ALGORITHM *algodef,
+ int no_store, void *vdata)
+{
+ struct encoder_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 =
+ encoder_from_dispatch(id, algodef, provider);
+
+ if (method != NULL) {
+ data->user_fn(method, data->user_arg);
+ OSSL_ENCODER_free(method);
+ }
+}
+
+void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
+ void (*fn)(OSSL_ENCODER *encoder, void *arg),
+ void *arg)
+{
+ struct encoder_do_all_data_st data;
+
+ data.user_fn = (void (*)(void *, void *))fn;
+ data.user_arg = arg;
+
+ /*
+ * No pre- or post-condition for this call, as this only creates methods
+ * temporarly and then promptly destroys them.
+ */
+ ossl_algorithm_do_all(libctx, OSSL_OP_ENCODER, NULL, NULL,
+ encoder_do_one, NULL, &data);
+}
+
+void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
+ void (*fn)(const char *name, void *data),
+ void *data)
+{
+ if (encoder == NULL)
+ return;
+
+ if (encoder->base.prov != NULL) {
+ OPENSSL_CTX *libctx = ossl_provider_library_context(encoder->base.prov);
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+ ossl_namemap_doall_names(namemap, encoder->base.id, fn, data);
+ }
+}
+
+const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder)
+{
+ if (encoder != NULL && encoder->settable_ctx_params != NULL) {
+ void *provctx = ossl_provider_ctx(OSSL_ENCODER_provider(encoder));
+
+ return encoder->settable_ctx_params(provctx);
+ }
+ return NULL;
+}
+
+/*
+ * Encoder context support
+ */
+
+/*
+ * |encoder| value NULL is valid, and signifies that there is no encoder.
+ * This is useful to provide fallback mechanisms.
+ * Functions that want to verify if there is a encoder can do so with
+ * OSSL_ENCODER_CTX_get_encoder()
+ */
+OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(OSSL_ENCODER *encoder)
+{
+ OSSL_ENCODER_CTX *ctx;
+
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ctx->encoder = encoder;
+ if (encoder != NULL && encoder->newctx != NULL) {
+ const OSSL_PROVIDER *prov = OSSL_ENCODER_provider(encoder);
+ void *provctx = ossl_provider_ctx(prov);
+
+ if (OSSL_ENCODER_up_ref(encoder)) {
+ ctx->serctx = encoder->newctx(provctx);
+ } else {
+ OSSL_ENCODER_free(encoder);
+ OPENSSL_free(ctx);
+ ctx = NULL;
+ }
+ }
+
+ return ctx;
+}
+
+const OSSL_ENCODER *
+OSSL_ENCODER_CTX_get_encoder(OSSL_ENCODER_CTX *ctx)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return ctx->encoder;
+}
+
+
+int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
+ const OSSL_PARAM params[])
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (ctx->encoder != NULL && ctx->encoder->set_ctx_params != NULL)
+ return ctx->encoder->set_ctx_params(ctx->serctx, params);
+ return 0;
+}
+
+void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx)
+{
+ if (ctx != NULL) {
+ if (ctx->encoder != NULL && ctx->encoder->freectx != NULL)
+ ctx->encoder->freectx(ctx->serctx);
+ OSSL_ENCODER_free(ctx->encoder);
+ UI_destroy_method(ctx->allocated_ui_method);
+ OPENSSL_free(ctx);
+ }
+}
diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c
new file mode 100644
index 0000000000..dc776c023e
--- /dev/null
+++ b/crypto/encode_decode/encoder_pkey.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2019-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/ui.h>
+#include <openssl/params.h>
+#include <openssl/encoder.h>
+#include <openssl/core_names.h>
+#include <openssl/safestack.h>
+#include "internal/provider.h"
+#include "internal/property.h"
+#include "crypto/evp.h"
+#include "encoder_local.h"
+
+DEFINE_STACK_OF_CSTRING()
+
+int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx,
+ const char *cipher_name,
+ const char *propquery)
+{
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
+
+ params[0] =
+ OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_CIPHER,
+ (void *)cipher_name, 0);
+ params[1] =
+ OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES,
+ (void *)propquery, 0);
+
+ return OSSL_ENCODER_CTX_set_params(ctx, params);
+}
+
+int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
+ const unsigned char *kstr,
+ size_t klen)
+{
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ params[0] = OSSL_PARAM_construct_octet_string(OSSL_ENCODER_PARAM_PASS,
+ (void *)kstr, klen);
+
+ return OSSL_ENCODER_CTX_set_params(ctx, params);
+}
+
+static void encoder_ctx_reset_passphrase_ui(OSSL_ENCODER_CTX *ctx)
+{
+ UI_destroy_method(ctx->allocated_ui_method);
+ ctx->allocated_ui_method = NULL;
+ ctx->ui_method = NULL;
+ ctx->ui_data = NULL;
+}
+
+int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
+ const UI_METHOD *ui_method,
+ void *ui_data)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ encoder_ctx_reset_passphrase_ui(ctx);
+ ctx->ui_method = ui_method;
+ ctx->ui_data = ui_data;
+ return 1;
+}
+
+int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx,
+ pem_password_cb *cb, void *cbarg)
+{
+ if (!ossl_assert(ctx != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ encoder_ctx_reset_passphrase_ui(ctx);
+ if (cb == NULL)
+ return 1;
+ ctx->ui_method =
+ ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 1);
+ ctx->ui_data = cbarg;
+
+ return ctx->ui_method != NULL;
+}
+
+/*
+ * Support for OSSL_ENCODER_CTX_new_by_TYPE:
+ * finding a suitable encoder
+ */
+
+struct selected_encoder_st {
+ STACK_OF(OPENSSL_CSTRING) *names;
+ int error;
+};
+
+static void cache_encoders(const char *name, void *data)
+{
+ struct selected_encoder_st *d = data;
+
+ if (sk_OPENSSL_CSTRING_push(d->names, name) <= 0)
+ d->error = 1;
+}
+
+/*
+ * Support for OSSL_ENCODER_to_bio:
+ * writing callback for the OSSL_PARAM (the implementation doesn't have
+ * intimate knowledge of the provider side object)
+ */
+
+struct encoder_write_data_st {
+ OSSL_ENCODER_CTX *ctx;
+ BIO *out;
+};
+
+static int encoder_write_cb(const OSSL_PARAM params[], void *arg)
+{
+ struct encoder_write_data_st *write_data = arg;
+ OSSL_ENCODER_CTX *ctx = write_data->ctx;
+ BIO *out = write_data->out;
+
+ return ctx->encoder->encode_data(ctx->serctx, params, (OSSL_CORE_BIO *)out,
+ ossl_encoder_passphrase_out_cb, ctx);
+}
+
+/*
+ * Support for OSSL_ENCODER_to_bio:
+ * Perform the actual output.
+ */
+
+static int encoder_EVP_PKEY_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out)
+{
+ const EVP_PKEY *pkey = ctx->object;
+ void *keydata = pkey->keydata;
+ EVP_KEYMGMT *keymgmt = pkey->keymgmt;
+
+ /*
+ * OSSL_ENCODER_CTX_new() creates a context, even when the
+ * encoder it's given is NULL. Callers can detect the lack
+ * of encoder with OSSL_ENCODER_CTX_get_encoder() and
+ * should take precautions, possibly call a fallback instead of
+ * OSSL_ENCODER_to_bio() / OSSL_ENCODER_to_fp(). If it's
+ * come this far, we return an error.
+ */
+ if (ctx->encoder == NULL)
+ return 0;
+
+ if (ctx->encoder->encode_object == NULL
+ || (OSSL_ENCODER_provider(ctx->encoder)
+ != EVP_KEYMGMT_provider(keymgmt))) {
+ struct encoder_write_data_st write_data;
+
+ write_data.ctx = ctx;
+ write_data.out = out;
+
+ return evp_keymgmt_export(keymgmt, keydata, ctx->selection,
+ &encoder_write_cb, &write_data);
+ }
+
+ return ctx->encoder->encode_object(ctx->serctx, keydata,
+ (OSSL_CORE_BIO *)out,
+ ossl_encoder_passphrase_out_cb, ctx);
+}
+
+/*
+ * OSSL_ENCODER_CTX_new_by_EVP_PKEY() returns a ctx with no encoder if
+ * it couldn't find a suitable encoder. This allows a caller to detect if
+ * a suitable encoder was found, with OSSL_ENCODER_CTX_get_encoder(),
+ * and to use fallback methods if the result is NULL.
+ */
+OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
+ const char *propquery)
+{
+ OSSL_ENCODER_CTX *ctx = NULL;
+ OSSL_ENCODER *encoder = NULL;
+ EVP_KEYMGMT *keymgmt = pkey->keymgmt;
+ int selection = OSSL_KEYMGMT_SELECT_ALL;
+
+ if (!ossl_assert(pkey != NULL && propquery != NULL)) {
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ if (keymgmt != NULL) {
+ const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt);
+ OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov);
+ struct selected_encoder_st sel_data;
+ OSSL_ENCODER *first = NULL;
+ const char *name;
+ int i;
+
+ /*
+ * Select the encoder in two steps. First, get the names of all of
+ * the encoders. Then determine which is the best one to use.
+ * This has to be broken because it isn't possible to fetch the
+ * serialisers inside EVP_KEYMGMT_names_do_all() due to locking
+ * order inversions with the store lock.
+ */
+ sel_data.error = 0;
+ sel_data.names = sk_OPENSSL_CSTRING_new_null();
+ if (sel_data.names == NULL)
+ return NULL;
+ EVP_KEYMGMT_names_do_all(keymgmt, cache_encoders, &sel_data);
+ /*
+ * Ignore memory allocation errors that are indicated in sel_data.error
+ * in case a suitable provider does get found regardless.
+ */
+
+ /*
+ * Encoders offer two functions, one that handles object data in
+ * the form of a OSSL_PARAM array, and one that directly handles a
+ * provider side object. The latter requires that the encoder
+ * is offered by the same provider that holds that object, but is
+ * more desirable because it usually provides faster encoding.
+ *
+ * When looking up possible encoders, we save the first that can
+ * handle an OSSL_PARAM array in |first| and use that if nothing
+ * better turns up.
+ */
+ for (i = 0; i < sk_OPENSSL_CSTRING_num(sel_data.names); i++) {
+ name = sk_OPENSSL_CSTRING_value(sel_data.names, i);
+ encoder = OSSL_ENCODER_fetch(libctx, name, propquery);
+ if (encoder != NULL) {
+ if (OSSL_ENCODER_provider(encoder) == desired_prov
+ && encoder->encode_object != NULL) {
+ OSSL_ENCODER_free(first);
+ break;
+ }
+ if (first == NULL && encoder->encode_data != NULL)
+ first = encoder;
+ else
+ OSSL_ENCODER_free(encoder);
+ encoder = NULL;
+ }
+ }
+ sk_OPENSSL_CSTRING_free(sel_data.names);
+ if (encoder == NULL)
+ encoder = first;
+
+ if (encoder != NULL) {
+ OSSL_PROPERTY_LIST *check = NULL, *current_props = NULL;
+
+ check = ossl_parse_query(libctx, "type=parameters");
+ current_props =
+ ossl_parse_property(libctx, OSSL_ENCODER_properties(encoder));
+ if (ossl_property_match_count(check, current_props) > 0)
+ selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
+ ossl_property_free(current_props);
+ ossl_property_free(check);
+ } else {
+ if (sel_data.error)
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
+ else
+ ERR_raise(ERR_LIB_OSSL_ENCODER,
+ OSSL_ENCODER_R_ENCODER_NOT_FOUND);
+ }
+ }
+
+ ctx = OSSL_ENCODER_CTX_new(encoder); /* refcnt(encoder)++ */
+ OSSL_ENCODER_free(encoder); /* refcnt(encoder)-- */
+
+ if (ctx != NULL) {
+ /* Setup for OSSL_ENCODE_to_bio() */
+ ctx->selection = selection;
+ ctx->object = pkey;
+ ctx->do_output = encoder_EVP_PKEY_to_bio;
+ }
+
+ return ctx;
+}
+
diff --git a/crypto/serializer/serdes_pass.c b/crypto/encode_decode/endecode_pass.c
index 75200955b5..113f5eeb84 100644
--- a/crypto/serializer/serdes_pass.c
+++ b/crypto/encode_decode/endecode_pass.c
@@ -11,7 +11,7 @@
#include <openssl/ui.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
/* Passphrase callbacks for any who need it */
@@ -56,7 +56,7 @@ static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len,
/* Get an application constructed prompt */
prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
- if (prompt == NULL) {
+ if (prompt == NULL) {
ERR_raise(errlib, ERR_R_MALLOC_FAILURE);
goto end;
}
@@ -107,33 +107,33 @@ static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len,
}
/*
- * Serializers typically want to get an outgoing passphrase, while
- * deserializers typically want to get en incoming passphrase.
+ * Encoders typically want to get an outgoing passphrase, while
+ * decoders typically want to get en incoming passphrase.
*/
-int ossl_serializer_passphrase_out_cb(char *pass, size_t pass_size,
- size_t *pass_len,
- const OSSL_PARAM params[], void *arg)
+int ossl_encoder_passphrase_out_cb(char *pass, size_t pass_size,
+ size_t *pass_len,
+ const OSSL_PARAM params[], void *arg)
{
- OSSL_SERIALIZER_CTX *ctx = arg;
+ OSSL_ENCODER_CTX *ctx = arg;
if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return do_passphrase(pass, pass_size, pass_len, params, arg, 1,
ctx->ui_method, ctx->ui_data,
- ERR_LIB_OSSL_SERIALIZER);
+ ERR_LIB_OSSL_ENCODER);
}
-int ossl_deserializer_passphrase_in_cb(char *pass, size_t pass_size,
- size_t *pass_len,
- const OSSL_PARAM params[], void *arg)
+int ossl_decoder_passphrase_in_cb(char *pass, size_t pass_size,
+ size_t *pass_len,
+ const OSSL_PARAM params[], void *arg)
{
- OSSL_DESERIALIZER_CTX *ctx = arg;
+ OSSL_DECODER_CTX *ctx = arg;
if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -147,13 +147,13 @@ int ossl_deserializer_passphrase_in_cb(char *pass, size_t pass_size,
return 1;
} else {
if ((ctx->cached_passphrase = OPENSSL_zalloc(pass_size)) == NULL) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
return 0;
}
}
if (do_passphrase(pass, pass_size, pass_len, params, arg, 0,
ctx->ui_method, ctx->ui_data,
- ERR_LIB_OSSL_DESERIALIZER)) {
+ ERR_LIB_OSSL_DECODER)) {
memcpy(ctx->cached_passphrase, pass, *pass_len);
ctx->cached_passphrase_len = *pass_len;
return 1;
diff --git a/crypto/err/err.c b/crypto/err/err.c
index e2d70d7a58..9098112d1c 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -75,8 +75,8 @@ 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"},
- {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, 0), "DESERIALIZER routines"},
+ {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, 0), "ENCODER routines"},
+ {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, 0), "DECODER routines"},
{ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"},
{0, NULL},
};
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index f1bed12795..037611d759 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -40,16 +40,16 @@ 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
-L OSSL_DESERIALIZER include/openssl/deserializer.h crypto/serializer/deserializer_err.c
+L OSSL_ENCODER include/openssl/encoder.h crypto/encoder/encoder_err.c
+L OSSL_DECODER include/openssl/decoder.h crypto/encoder/decoder_err.c
L HTTP include/openssl/http.h crypto/http/http_err.c
# additional header files to be scanned for function names
L NONE include/openssl/x509_vfy.h NONE
-L NONE crypto/ec/ec_local.h NONE
-L NONE crypto/cms/cms_local.h NONE
-L NONE crypto/ct/ct_local.h NONE
-L NONE ssl/ssl_local.h NONE
+L NONE crypto/ec/ec_local.h NONE
+L NONE crypto/cms/cms_local.h NONE
+L NONE crypto/ct/ct_local.h NONE
+L NONE ssl/ssl_local.h NONE
# SSL/TLS alerts
R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 10531ead7a..3a5a5b5692 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2702,9 +2702,9 @@ OCSP_R_STATUS_TOO_OLD:127:status too old
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_DECODER_R_MISSING_GET_PARAMS:100:missing get params
+OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query
+OSSL_ENCODER_R_ENCODER_NOT_FOUND:101:encoder not found
OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type
OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read
OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index bee6337a88..7a79816788 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -29,7 +29,7 @@
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/param_build.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
#include <openssl/core_names.h>
#include "crypto/asn1.h"
@@ -1143,23 +1143,23 @@ static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
}
static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
- const char *propquery /* For provided serialization */,
+ const char *propquery /* For provided encoding */,
int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx),
ASN1_PCTX *legacy_pctx /* For legacy print */)
{
int pop_f_prefix;
long saved_indent;
- OSSL_SERIALIZER_CTX *ctx = NULL;
+ OSSL_ENCODER_CTX *ctx = NULL;
int ret = -2; /* default to unsupported */
if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
return 0;
- ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery);
- if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
- ret = OSSL_SERIALIZER_to_bio(ctx, out);
- OSSL_SERIALIZER_CTX_free(ctx);
+ ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, propquery);
+ if (OSSL_ENCODER_CTX_get_encoder(ctx) != NULL)
+ ret = OSSL_ENCODER_to_bio(ctx, out);
+ OSSL_ENCODER_CTX_free(ctx);
if (ret != -2)
goto end;
@@ -1178,7 +1178,7 @@ static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
- return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
+ return print_pkey(pkey, out, indent, OSSL_ENCODER_PUBKEY_TO_TEXT_PQ,
(pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
pctx);
}
@@ -1186,7 +1186,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
- return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
+ return print_pkey(pkey, out, indent, OSSL_ENCODER_PrivateKey_TO_TEXT_PQ,
(pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
pctx);
}
@@ -1194,7 +1194,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
- return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ,
+ return print_pkey(pkey, out, indent, OSSL_ENCODER_Parameters_TO_TEXT_PQ,
(pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
pctx);
}
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 1ab309329d..2f9346d998 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -27,7 +27,6 @@
/* TODO(3.0) remove when provider SM2 key generation is implemented */
#ifdef TMP_SM2_HACK
# include <openssl/ec.h>
-# include <openssl/serializer.h>
# include "internal/sizes.h"
#endif
diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h
index 2fb1e6f4d5..81d1718e32 100644
--- a/crypto/pem/pem_local.h
+++ b/crypto/pem/pem_local.h
@@ -13,17 +13,17 @@
*/
#include <openssl/pem.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
-/* Alternative IMPLEMENT macros for provided serializers */
+/* Alternative IMPLEMENT macros for provided encoders */
# define IMPLEMENT_PEM_provided_write_body_vars(type, asn1) \
int ret = 0; \
- const char *pq = OSSL_SERIALIZER_##asn1##_TO_PEM_PQ; \
- OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_##type(x, pq); \
+ const char *pq = OSSL_ENCODER_##asn1##_TO_PEM_PQ; \
+ OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_by_##type(x, pq); \
\
- if (ctx != NULL && OSSL_SERIALIZER_CTX_get_serializer(ctx) == NULL) { \
- OSSL_SERIALIZER_CTX_free(ctx); \
+ if (ctx != NULL && OSSL_ENCODER_CTX_get_encoder(ctx) == NULL) { \
+ OSSL_ENCODER_CTX_free(ctx); \
goto legacy; \
}
# define IMPLEMENT_PEM_provided_write_body_pass() \
@@ -38,31 +38,31 @@
} \
if (enc != NULL) { \
ret = 0; \
- if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \
- NULL)) { \
+ if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \
+ NULL)) { \
ret = 1; \
if (kstr != NULL \
- && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, kstr, klen)) \
+ && !OSSL_ENCODER_CTX_set_passphrase(ctx, kstr, klen)) \
ret = 0; \
else if (cb != NULL \
- && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, \
- cb, u)) \
+ && !OSSL_ENCODER_CTX_set_passphrase_cb(ctx, \
+ cb, u)) \
ret = 0; \
} \
} \
if (!ret) { \
- OSSL_SERIALIZER_CTX_free(ctx); \
+ OSSL_ENCODER_CTX_free(ctx); \
return 0; \
}
# define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \
- ret = OSSL_SERIALIZER_to_##outtype(ctx, out); \
- OSSL_SERIALIZER_CTX_free(ctx); \
+ ret = OSSL_ENCODER_to_##outtype(ctx, out); \
+ OSSL_ENCODER_CTX_free(ctx); \
return ret
# define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \
writename) \
legacy: \
return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \
- x, NULL, NULL, 0, NULL, NULL)
+ x, NULL, NULL, 0, NULL, NULL)
# define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \
writename) \
legacy: \
@@ -114,15 +114,15 @@
IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \
IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1)
-# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \
- IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \
+# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \
IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1)
-# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \
+# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \
IMPLEMENT_PEM_read(name, type, str, asn1) \
IMPLEMENT_PEM_provided_write(name, type, str, asn1)
-# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \
+# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \
IMPLEMENT_PEM_read(name, type, str, asn1) \
IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1)
diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c
index 12a25b7a82..84d431820b 100644
--- a/crypto/pem/pem_pk8.c
+++ b/crypto/pem/pem_pk8.c
@@ -15,7 +15,7 @@
#include <openssl/x509.h>
#include <openssl/pkcs12.h>
#include <openssl/pem.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder,
int nid, const EVP_CIPHER *enc,
@@ -69,9 +69,9 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
{
int ret = 0;
const char *pq = isder
- ? OSSL_SERIALIZER_PrivateKey_TO_DER_PQ
- : OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ;
- OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(x, pq);
+ ? OSSL_ENCODER_PrivateKey_TO_DER_PQ
+ : OSSL_ENCODER_PrivateKey_TO_PEM_PQ;
+ OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(x, pq);
if (ctx == NULL)
return 0;
@@ -90,12 +90,11 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
}
}
- if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL) {
+ if (OSSL_ENCODER_CTX_get_encoder(ctx) != NULL) {
ret = 1;
if (enc != NULL) {
ret = 0;
- if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc),
- NULL)) {
+ if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), NULL)) {
const unsigned char *ukstr = (const unsigned char *)kstr;
/*
@@ -106,14 +105,14 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
*/
ret = 1;
if (kstr != NULL
- && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, ukstr, klen))
+ && !OSSL_ENCODER_CTX_set_passphrase(ctx, ukstr, klen))
ret = 0;
else if (cb != NULL
- && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, cb, u))
+ && !OSSL_ENCODER_CTX_set_passphrase_cb(ctx, cb, u))
ret = 0;
}
}
- ret = ret && OSSL_SERIALIZER_to_bio(ctx, bp);
+ ret = ret && OSSL_ENCODER_to_bio(ctx, bp);
} else {
X509_SIG *p8;
PKCS8_PRIV_KEY_INFO *p8inf;
@@ -153,7 +152,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
legacy_end:
PKCS8_PRIV_KEY_INFO_free(p8inf);
}
- OSSL_SERIALIZER_CTX_free(ctx);
+ OSSL_ENCODER_CTX_free(ctx);
return ret;
}
@@ -261,4 +260,4 @@ IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
- PKCS8_PRIV_KEY_INFO)
+ PKCS8_PRIV_KEY_INFO)
diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 4ee5bb7009..e355afe5f9 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -19,7 +19,6 @@
#include <openssl/dh.h>
#include <openssl/store.h>
#include <openssl/ui.h>
-#include <openssl/serializer.h>
#include "crypto/store.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index 91b830c2e5..6d6ca9b266 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -596,9 +596,9 @@ int ossl_property_parse_init(OPENSSL_CTX *ctx)
"provider", /* Name of provider (default, legacy, fips) */
"version", /* Version number of this provider */
"fips", /* FIPS validated or FIPS supporting algorithm */
- "format", /* output format for serializers */
- "type", /* output type for serializers */
- "input", /* input type for deserializers */
+ "format", /* output format for encoders */
+ "type", /* output type for encoders */
+ "input", /* input type for decoders */
};
size_t i;
diff --git a/crypto/serializer/build.info b/crypto/serializer/build.info
deleted file mode 100644
index 11f8889b6b..0000000000
--- a/crypto/serializer/build.info
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCE[../../libcrypto]=serdes_pass.c
-
-SOURCE[../../libcrypto]=serializer_meth.c serializer_lib.c serializer_pkey.c
-SOURCE[../../libcrypto]=deserializer_meth.c deserializer_lib.c \
- deserializer_pkey.c
-
-SOURCE[../../libcrypto]=serializer_err.c
-SOURCE[../../libcrypto]=deserializer_err.c
diff --git a/crypto/serializer/deserializer_lib.c b/crypto/serializer/deserializer_lib.c
deleted file mode 100644
index aa3b552786..0000000000
--- a/crypto/serializer/deserializer_lib.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * 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;
- int ok = 0;
-
- memset(&data, 0, sizeof(data));
- data.ctx = ctx;
- data.bio = in;
-
- ok = deser_process(NULL, &data);
-
- /* Clear any internally cached passphrase */
- if (!ctx->flag_user_passphrase) {
- OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0);
- ctx->flag_user_passphrase = 0;
- }
- return ok;
-}
-
-#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(&params[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_construct(OSSL_DESERIALIZER_CTX *ctx,
- OSSL_DESERIALIZER_CONSTRUCT *construct)
-{
- if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
- ctx->construct = construct;
- return 1;
-}
-
-int OSSL_DESERIALIZER_CTX_set_construct_data(OSSL_DESERIALIZER_CTX *ctx,
- void *construct_data)
-{
- if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
- ctx->construct_data = construct_data;
- return 1;
-}
-
-int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx,
- OSSL_DESERIALIZER_CLEANUP *cleanup)
-{
- if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
- ctx->cleanup = cleanup;
- return 1;
-}
-
-OSSL_DESERIALIZER_CONSTRUCT *
-OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx)
-{
- if (ctx == NULL)
- return NULL;
- return ctx->construct;
-}
-
-void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx)
-{
- if (ctx == NULL)
- return NULL;
- return ctx->construct_data;
-}
-
-OSSL_DESERIALIZER_CLEANUP *
-OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx)
-{
- if (ctx == NULL)
- return NULL;
- return ctx->cleanup;
-}
-
-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->construct != NULL
- && ctx->construct(deser_inst, params, ctx->construct_data)) {
- ok = 1;
- goto end;
- }
-
- /* The constructor 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,
- new_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;
-
- /*
- * Checking the return value of BIO_reset() or BIO_seek() is unsafe.
- * Furthermore, BIO_reset() is unsafe to use if the source BIO happens
- * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero
- * no matter where we are in the underlying buffer we're reading from.
- *
- * So, we simply do a BIO_seek(), and use BIO_tell() that we're back
- * at the same position. This is a best effort attempt, but BIO_seek()
- * and BIO_tell() should come as a pair...
- */
- (void)BIO_seek(bio, loc);
- if (BIO_tell(bio) != loc)
- 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,
- ctx->passphrase_cb,
- new_data.ctx);
- if (ok)
- break;
- }
-
- end:
- BIO_free(new_data.bio);
- return ok;
-}
diff --git a/crypto/serializer/deserializer_meth.c b/crypto/serializer/deserializer_meth.c
deleted file mode 100644
index 69099f5e95..0000000000
--- a/crypto/serializer/deserializer_meth.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * 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(
- ossl_provider_ctx(OSSL_DESERIALIZER_provider(deser)));
- 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(
- ossl_provider_ctx(OSSL_DESERIALIZER_provider(deser)));
- 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;
- }
-
- ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb;
- 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->cleanup != NULL)
- ctx->cleanup(ctx->construct_data);
- sk_OSSL_DESERIALIZER_INSTANCE_pop_free(ctx->deser_insts,
- OSSL_DESERIALIZER_INSTANCE_free);
- OSSL_DESERIALIZER_CTX_set_passphrase_ui(ctx, NULL, NULL);
- OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0);
- OPENSSL_free(ctx);
- }
-}
diff --git a/crypto/serializer/serializer_err.c b/crypto/serializer/serializer_err.c
deleted file mode 100644
index 2ea8b8bede..0000000000
--- a/crypto/serializer/serializer_err.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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/serializererr.h>
-
-#ifndef OPENSSL_NO_ERR
-
-static const ERR_STRING_DATA OSSL_SERIALIZER_str_reasons[] = {
- {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY),
- "incorrect property query"},
- {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND),
- "serializer not found"},
- {0, NULL}
-};
-
-#endif
-
-int ERR_load_OSSL_SERIALIZER_strings(void)
-{
-#ifndef OPENSSL_NO_ERR
- if (ERR_reason_error_string(OSSL_SERIALIZER_str_reasons[0].error) == NULL)
- ERR_load_strings_const(OSSL_SERIALIZER_str_reasons);
-#endif
- return 1;
-}
diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h
deleted file mode 100644
index d139e402d7..0000000000
--- a/crypto/serializer/serializer_local.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2019-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_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_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_settable_ctx_params_fn *settable_ctx_params;
- OSSL_FUNC_serializer_serialize_data_fn *serialize_data;
- 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;
-
- /*-
- * 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);
-
- /* 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;
-};
-
-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 constructors of a deserialization, and its caller argument.
- */
- OSSL_DESERIALIZER_CONSTRUCT *construct;
- OSSL_DESERIALIZER_CLEANUP *cleanup;
- void *construct_data;
-
- /* For any function that needs a passphrase reader */
- OSSL_PASSPHRASE_CALLBACK *passphrase_cb;
- const UI_METHOD *ui_method;
- void *ui_data;
- /*
- * if caller used OSSL_SERIALIZER_CTX_set_pem_password_cb(), we need
- * intermediary storage.
- */
- UI_METHOD *allocated_ui_method;
- /*
- * Because the same input may pass through more than one deserializer,
- * we cache any passphrase passed to us. The desrializing processor
- * must clear this at the end of a run.
- */
- unsigned char *cached_passphrase;
- size_t cached_passphrase_len;
-
- /*
- * Flag section. Keep these together
- */
-
- /*
- * The passphrase was passed to us by the user. In that case, it
- * should only be freed when freeing this context.
- */
- unsigned int flag_user_passphrase:1;
-};
-
-/* Passphrase callbacks, found in serdes_pass.c */
-
-/*
- * Serializers typically want to get an outgoing passphrase, while
- * deserializers typically want to get en incoming passphrase.
- */
-OSSL_PASSPHRASE_CALLBACK ossl_serializer_passphrase_out_cb;
-OSSL_PASSPHRASE_CALLBACK ossl_deserializer_passphrase_in_cb;
diff --git a/crypto/serializer/serializer_meth.c b/crypto/serializer/serializer_meth.c
deleted file mode 100644
index 1489fff890..0000000000
--- a/crypto/serializer/serializer_meth.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright 2019-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/serializer.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"
-
-/*
- * 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->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
- OSSL_SERIALIZER_free(ser);
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- ser->base.refcnt = 1;
-
- return ser;
-}
-
-int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser)
-{
- int ref = 0;
-
- CRYPTO_UP_REF(&ser->base.refcnt, &ref, ser->base.lock);
- return 1;
-}
-
-void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser)
-{
- int ref = 0;
-
- if (ser == NULL)
- return;
-
- CRYPTO_DOWN_REF(&ser->base.refcnt, &ref, ser->base.lock);
- if (ref > 0)
- return;
- ossl_provider_free(ser->base.prov);
- CRYPTO_THREAD_lock_free(ser->base.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->base.id = id;
- ser->base.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_FUNC_serializer_newctx(fns);
- break;
- case OSSL_FUNC_SERIALIZER_FREECTX:
- if (ser->freectx == NULL)
- ser->freectx =
- OSSL_FUNC_serializer_freectx(fns);
- break;
- case OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS:
- if (ser->set_ctx_params == NULL)
- ser->set_ctx_params =
- OSSL_FUNC_serializer_set_ctx_params(fns);
- break;
- case OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS:
- if (ser->settable_ctx_params == NULL)
- ser->settable_ctx_params =
- OSSL_FUNC_serializer_settable_ctx_params(fns);
- break;
- case OSSL_FUNC_SERIALIZER_SERIALIZE_DATA:
- if (ser->serialize_data == NULL)
- ser->serialize_data =
- OSSL_FUNC_serializer_serialize_data(fns);
- break;
- case OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT:
- if (ser->serialize_object == NULL)
- ser->serialize_object =
- OSSL_FUNC_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->base.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->base.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->base.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->base.id;
-}
-
-int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser, const char *name)
-{
- 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->base.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;
-
- /*
- * No pre- or post-condition for this call, as this only creates methods
- * temporarly and then promptly destroys them.
- */
- ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, NULL,
- serializer_do_one, NULL, &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->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->base.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(
- ossl_provider_ctx(OSSL_SERIALIZER_provider(ser)));
- return NULL;
-}
-
-/*
- * Serializer context support
- */
-
-/*
- * |ser| value NULL is valid, and signifies that there is no serializer.
- * This is useful to provide fallback mechanisms.
- * Functions 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);
- UI_destroy_method(ctx->allocated_ui_method);
- OPENSSL_free(ctx);
- }
-}
diff --git a/crypto/serializer/serializer_pkey.c b/crypto/serializer/serializer_pkey.c
deleted file mode 100644
index d31b3cce8b..0000000000
--- a/crypto/serializer/serializer_pkey.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2019-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/ui.h>
-#include <openssl/params.h>
-#include <openssl/serializer.h>
-#include <openssl/core_names.h>
-#include <openssl/safestack.h>
-#include "internal/provider.h"
-#include "internal/property.h"
-#include "crypto/evp.h"
-#include "serializer_local.h"
-
-DEFINE_STACK_OF_CSTRING()
-
-int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx,
- const char *cipher_name,
- const char *propquery)
-{
- OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
-
- params[0] =
- OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER,
- (void *)cipher_name, 0);
- params[1] =
- OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_PROPERTIES,
- (void *)propquery, 0);
-
- return OSSL_SERIALIZER_CTX_set_params(ctx, params);
-}
-
-int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx,
- const unsigned char *kstr,
- size_t klen)
-{
- OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
-
- params[0] = OSSL_PARAM_construct_octet_string(OSSL_SERIALIZER_PARAM_PASS,
- (void *)kstr, klen);
-
- return OSSL_SERIALIZER_CTX_set_params(ctx, params);
-}
-
-static void serializer_ctx_reset_passphrase_ui(OSSL_SERIALIZER_CTX *ctx)
-{
- UI_destroy_method(ctx->allocated_ui_method);
- ctx->allocated_ui_method = NULL;
- ctx->ui_method = NULL;
- ctx->ui_data = NULL;
-}
-
-int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx,
- const UI_METHOD *ui_method,
- void *ui_data)
-{
- if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- serializer_ctx_reset_passphrase_ui(ctx);
- ctx->ui_method = ui_method;
- ctx->ui_data = ui_data;
- return 1;
-}
-
-int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx,
- pem_password_cb *cb, void *cbarg)
-{
- if (!ossl_assert(ctx != NULL)) {
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- serializer_ctx_reset_passphrase_ui(ctx);
- if (cb == NULL)
- return 1;
- ctx->ui_method =
- ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 1);
- ctx->ui_data = cbarg;
-
- return ctx->ui_method != NULL;
-}
-
-/*
- * Support for OSSL_SERIALIZER_CTX_new_by_TYPE:
- * finding a suitable serializer
- */
-
-struct selected_serializer_st {
- STACK_OF(OPENSSL_CSTRING) *names;
- int error;
-};
-
-static void cache_serializers(const char *name, void *data)
-{
- struct selected_serializer_st *d = data;
-
- if (sk_OPENSSL_CSTRING_push(d->names, name) <= 0)
- d->error = 1;
-}
-
-/*
- * Support for OSSL_SERIALIZER_to_bio:
- * writing callback for the OSSL_PARAM (the implementation doesn't have
- * intimate knowledge of the provider side object)
- */
-
-struct serializer_write_data_st {
- OSSL_SERIALIZER_CTX *ctx;
- BIO *out;
-};
-
-static int serializer_write_cb(const OSSL_PARAM params[], void *arg)
-{
- struct serializer_write_data_st *write_data = arg;
- OSSL_SERIALIZER_CTX *ctx = write_data->ctx;
- BIO *out = write_data->out;
-
- return ctx->ser->serialize_data(ctx->serctx, params, (OSSL_CORE_BIO *)out,
- ossl_serializer_passphrase_out_cb, ctx);
-}
-
-/*
- * Support for OSSL_SERIALIZER_to_bio:
- * Perform the actual output.
- */
-
-static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
-{
- const EVP_PKEY *pkey = ctx->object;
- void *keydata = pkey->keydata;
- EVP_KEYMGMT *keymgmt = pkey->keymgmt;
-
- /*
- * OSSL_SERIALIZER_CTX_new() creates a context, even when the
- * serializer it's given is NULL. Callers can detect the lack
- * of serializer with OSSL_SERIALIZER_CTX_get_serializer() and
- * should take precautions, possibly call a fallback instead of
- * OSSL_SERIALIZER_to_bio() / OSSL_SERIALIZER_to_fp(). If it's
- * come this far, we return an error.
- */
- if (ctx->ser == NULL)
- return 0;
-
- if (ctx->ser->serialize_object == NULL
- || OSSL_SERIALIZER_provider(ctx->ser) != EVP_KEYMGMT_provider(keymgmt)) {
- struct serializer_write_data_st write_data;
-
- write_data.ctx = ctx;
- write_data.out = out;
-
- return evp_keymgmt_export(keymgmt, keydata, ctx->selection,
- &serializer_write_cb, &write_data);
- }
-
- return ctx->ser->serialize_object(ctx->serctx, keydata,
- (OSSL_CORE_BIO *)out,
- ossl_serializer_passphrase_out_cb, ctx);
-}
-
-/*
- * OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() returns a ctx with no serializer if
- * it couldn't find a suitable serializer. This allows a caller to detect if
- * a suitable serializer was found, with OSSL_SERIALIZER_CTX_get_serializer(),
- * and to use fallback methods if the result is NULL.
- */
-OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
- const char *propquery)
-{
- OSSL_SERIALIZER_CTX *ctx = NULL;
- OSSL_SERIALIZER *ser = NULL;
- EVP_KEYMGMT *keymgmt = pkey->keymgmt;
- int selection = OSSL_KEYMGMT_SELECT_ALL;
-
- if (!ossl_assert(pkey != NULL && propquery != NULL)) {
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
- return NULL;
- }
-
- if (keymgmt != NULL) {
- const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt);
- OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov);
- struct selected_serializer_st sel_data;
- OSSL_SERIALIZER *first = NULL;
- const char *name;
- int i;
-
- /*
- * Select the serializer in two steps. First, get the names of all of
- * the serializers. Then determine which is the best one to use.
- * This has to be broken because it isn't possible to fetch the
- * serialisers inside EVP_KEYMGMT_names_do_all() due to locking
- * order inversions with the store lock.
- */
- sel_data.error = 0;
- sel_data.names = sk_OPENSSL_CSTRING_new_null();
- if (sel_data.names == NULL)
- return NULL;
- EVP_KEYMGMT_names_do_all(keymgmt, cache_serializers, &sel_data);
- /*
- * Ignore memory allocation errors that are indicated in sel_data.error
- * in case a suitable provider does get found regardless.
- */
-
- /*
- * Serializers offer two functions, one that handles object data in
- * the form of a OSSL_PARAM array, and one that directly handles a
- * provider side object. The latter requires that the serializer
- * is offered by the same provider that holds that object, but is
- * more desirable because it usually provides faster serialization.
- *
- * When looking up possible serializers, we save the first that can
- * handle an OSSL_PARAM array in |first| and use that if nothing
- * better turns up.
- */
- for (i = 0; i < sk_OPENSSL_CSTRING_num(sel_data.names); i++) {
- name = sk_OPENSSL_CSTRING_value(sel_data.names, i);
- ser = OSSL_SERIALIZER_fetch(libctx, name, propquery);
- if (ser != NULL) {
- if (OSSL_SERIALIZER_provider(ser) == desired_prov
- && ser->serialize_object != NULL) {
- OSSL_SERIALIZER_free(first);
- break;
- }
- if (first == NULL && ser->serialize_data != NULL)
- first = ser;
- else
- OSSL_SERIALIZER_free(ser);
- ser = NULL;
- }
- }
- sk_OPENSSL_CSTRING_free(sel_data.names);
- if (ser == NULL)
- ser = first;
-
- if (ser != NULL) {
- OSSL_PROPERTY_LIST *check = NULL, *current_props = NULL;
-
- check = ossl_parse_query(libctx, "type=parameters");
- current_props =
- ossl_parse_property(libctx, OSSL_SERIALIZER_properties(ser));
- if (ossl_property_match_count(check, current_props) > 0)
- selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
- ossl_property_free(current_props);
- ossl_property_free(check);
- } else {
- if (sel_data.error)
- ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE);
- else
- ERR_raise(ERR_LIB_OSSL_SERIALIZER,
- OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND);
- }
- }
-
- ctx = OSSL_SERIALIZER_CTX_new(ser); /* refcnt(ser)++ */
- OSSL_SERIALIZER_free(ser); /* refcnt(ser)-- */
-
- if (ctx != NULL) {
- /* Setup for OSSL_SERIALIZE_to_bio() */
- ctx->selection = selection;
- ctx->object = pkey;
- ctx->do_output = serializer_EVP_PKEY_to_bio;
- }
-
- return ctx;
-}
-
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c
index 59f4a14895..cb47f917ad 100644
--- a/crypto/x509/x_pubkey.c
+++ b/crypto/x509/x_pubkey.c
@@ -22,7 +22,7 @@
#include "crypto/x509.h"
#include <openssl/rsa.h>
#include <openssl/dsa.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
struct X509_pubkey_st {
X509_ALGOR *algor;
@@ -97,18 +97,18 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
}
} else if (pkey->keymgmt != NULL) {
BIO *bmem = BIO_new(BIO_s_mem());
- const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
- OSSL_SERIALIZER_CTX *sctx =
- OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, serprop);
+ const char *encprop = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
+ OSSL_ENCODER_CTX *ectx =
+ OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, encprop);
- if (OSSL_SERIALIZER_to_bio(sctx, bmem)) {
+ if (OSSL_ENCODER_to_bio(ectx, bmem)) {
const unsigned char *der = NULL;
long derlen = BIO_get_mem_data(bmem, (char **)&der);
pk = d2i_X509_PUBKEY(NULL, &der, derlen);
}
- OSSL_SERIALIZER_CTX_free(sctx);
+ OSSL_ENCODER_CTX_free(ectx);
BIO_free(bmem);
}
@@ -124,7 +124,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
/*
* pk->pkey is NULL when using the legacy routine, but is non-NULL when
- * going through the serializer, and for all intents and purposes, it's
+ * going through the encoder, and for all intents and purposes, it's
* a perfect copy of |pkey|, just not the same instance. In that case,
* we could simply return early, right here.
* However, in the interest of being cautious leaning on paranoia, some
@@ -303,16 +303,16 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
}
X509_PUBKEY_free(xpk);
} else if (a->keymgmt != NULL) {
- const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
- OSSL_SERIALIZER_CTX *ctx =
- OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop);
+ const char *encprop = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
+ OSSL_ENCODER_CTX *ctx =
+ OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, encprop);
BIO *out = BIO_new(BIO_s_mem());
BUF_MEM *buf = NULL;
if (ctx != NULL
&& out != NULL
- && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL
- && OSSL_SERIALIZER_to_bio(ctx, out)
+ && OSSL_ENCODER_CTX_get_encoder(ctx) != NULL
+ && OSSL_ENCODER_to_bio(ctx, out)
&& BIO_get_mem_ptr(out, &buf) > 0) {
ret = buf->length;
@@ -328,7 +328,7 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
}
}
BIO_free(out);
- OSSL_SERIALIZER_CTX_free(ctx);
+ OSSL_ENCODER_CTX_free(ctx);
}
return ret;