Rename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE
authorRichard Levitte <levitte@openssl.org>
Sun, 16 Aug 2020 19:25:08 +0000 (21:25 +0200)
committerRichard Levitte <levitte@openssl.org>
Fri, 21 Aug 2020 07:23:58 +0000 (09:23 +0200)
Fixes #12455

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12660)

108 files changed:
CHANGES.md
NEWS.md
apps/list.c
crypto/asn1/i2d_pr.c
crypto/build.info
crypto/encode_decode/build.info [new file with mode: 0644]
crypto/encode_decode/decoder_err.c [moved from crypto/serializer/deserializer_err.c with 55% similarity]
crypto/encode_decode/decoder_lib.c [new file with mode: 0644]
crypto/encode_decode/decoder_meth.c [new file with mode: 0644]
crypto/encode_decode/decoder_pkey.c [moved from crypto/serializer/deserializer_pkey.c with 65% similarity]
crypto/encode_decode/encoder_err.c [new file with mode: 0644]
crypto/encode_decode/encoder_lib.c [moved from crypto/serializer/serializer_lib.c with 71% similarity]
crypto/encode_decode/encoder_local.h [new file with mode: 0644]
crypto/encode_decode/encoder_meth.c [new file with mode: 0644]
crypto/encode_decode/encoder_pkey.c [new file with mode: 0644]
crypto/encode_decode/endecode_pass.c [moved from crypto/serializer/serdes_pass.c with 80% similarity]
crypto/err/err.c
crypto/err/openssl.ec
crypto/err/openssl.txt
crypto/evp/p_lib.c
crypto/evp/pmeth_gn.c
crypto/pem/pem_local.h
crypto/pem/pem_pk8.c
crypto/pem/pem_pkey.c
crypto/property/property_parse.c
crypto/serializer/build.info [deleted file]
crypto/serializer/deserializer_lib.c [deleted file]
crypto/serializer/deserializer_meth.c [deleted file]
crypto/serializer/serializer_err.c [deleted file]
crypto/serializer/serializer_local.h [deleted file]
crypto/serializer/serializer_meth.c [deleted file]
crypto/serializer/serializer_pkey.c [deleted file]
crypto/x509/x_pubkey.c
doc/man1/openssl-list.pod.in
doc/man3/OSSL_DECODER.pod [new file with mode: 0644]
doc/man3/OSSL_DECODER_CTX.pod [new file with mode: 0644]
doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod [new file with mode: 0644]
doc/man3/OSSL_DECODER_from_bio.pod [new file with mode: 0644]
doc/man3/OSSL_DESERIALIZER.pod [deleted file]
doc/man3/OSSL_DESERIALIZER_CTX.pod [deleted file]
doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod [deleted file]
doc/man3/OSSL_DESERIALIZER_from_bio.pod [deleted file]
doc/man3/OSSL_ENCODER.pod [new file with mode: 0644]
doc/man3/OSSL_ENCODER_CTX.pod [new file with mode: 0644]
doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod [new file with mode: 0644]
doc/man3/OSSL_ENCODER_to_bio.pod [moved from doc/man3/OSSL_SERIALIZER_to_bio.pod with 58% similarity]
doc/man3/OSSL_SERIALIZER.pod [deleted file]
doc/man3/OSSL_SERIALIZER_CTX.pod [deleted file]
doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod [deleted file]
doc/man7/OSSL_PROVIDER-FIPS.pod
doc/man7/OSSL_PROVIDER-base.pod
doc/man7/OSSL_PROVIDER-default.pod
doc/man7/provider-encoder.pod [moved from doc/man7/provider-serializer.pod with 56% similarity]
doc/man7/provider.pod
include/crypto/encoder.h [moved from include/crypto/serializer.h with 53% similarity]
include/internal/cryptlib.h
include/openssl/core_dispatch.h
include/openssl/core_names.h
include/openssl/decoder.h [new file with mode: 0644]
include/openssl/decodererr.h [moved from include/openssl/deserializererr.h with 68% similarity]
include/openssl/deserializer.h [deleted file]
include/openssl/encoder.h [new file with mode: 0644]
include/openssl/encodererr.h [moved from include/openssl/serializererr.h with 64% similarity]
include/openssl/err.h
include/openssl/serializer.h [deleted file]
include/openssl/types.h
providers/baseprov.c
providers/decoders.inc [new file with mode: 0644]
providers/defltprov.c
providers/deserializers.inc [deleted file]
providers/encoders.inc [new file with mode: 0644]
providers/implementations/build.info
providers/implementations/encode_decode/build.info [new file with mode: 0644]
providers/implementations/encode_decode/decode_common.c [moved from providers/implementations/serializers/deserialize_common.c with 99% similarity]
providers/implementations/encode_decode/decode_der2key.c [moved from providers/implementations/serializers/deserialize_der2key.c with 81% similarity]
providers/implementations/encode_decode/decode_ms2key.c [moved from providers/implementations/serializers/deserialize_ms2key.c with 73% similarity]
providers/implementations/encode_decode/decode_pem2der.c [moved from providers/implementations/serializers/deserialize_pem2der.c with 71% similarity]
providers/implementations/encode_decode/encoder_common.c [moved from providers/implementations/serializers/serializer_common.c with 99% similarity]
providers/implementations/encode_decode/encoder_dh.c [moved from providers/implementations/serializers/serializer_dh.c with 99% similarity]
providers/implementations/encode_decode/encoder_dh_param.c [moved from providers/implementations/serializers/serializer_dh_param.c with 70% similarity]
providers/implementations/encode_decode/encoder_dh_priv.c [moved from providers/implementations/serializers/serializer_dh_priv.c with 73% similarity]
providers/implementations/encode_decode/encoder_dh_pub.c [moved from providers/implementations/serializers/serializer_dh_pub.c with 70% similarity]
providers/implementations/encode_decode/encoder_dsa.c [moved from providers/implementations/serializers/serializer_dsa.c with 99% similarity]
providers/implementations/encode_decode/encoder_dsa_param.c [moved from providers/implementations/serializers/serializer_dsa_param.c with 73% similarity]
providers/implementations/encode_decode/encoder_dsa_priv.c [moved from providers/implementations/serializers/serializer_dsa_priv.c with 74% similarity]
providers/implementations/encode_decode/encoder_dsa_pub.c [moved from providers/implementations/serializers/serializer_dsa_pub.c with 76% similarity]
providers/implementations/encode_decode/encoder_ec.c [moved from providers/implementations/serializers/serializer_ec.c with 99% similarity]
providers/implementations/encode_decode/encoder_ec_param.c [moved from providers/implementations/serializers/serializer_ec_param.c with 68% similarity]
providers/implementations/encode_decode/encoder_ec_priv.c [moved from providers/implementations/serializers/serializer_ec_priv.c with 71% similarity]
providers/implementations/encode_decode/encoder_ec_pub.c [moved from providers/implementations/serializers/serializer_ec_pub.c with 74% similarity]
providers/implementations/encode_decode/encoder_ecx.c [moved from providers/implementations/serializers/serializer_ecx.c with 99% similarity]
providers/implementations/encode_decode/encoder_ecx_priv.c [moved from providers/implementations/serializers/serializer_ecx_priv.c with 68% similarity]
providers/implementations/encode_decode/encoder_ecx_pub.c [moved from providers/implementations/serializers/serializer_ecx_pub.c with 75% similarity]
providers/implementations/encode_decode/encoder_ffc_params.c [moved from providers/implementations/serializers/serializer_ffc_params.c with 98% similarity]
providers/implementations/encode_decode/encoder_local.h [moved from providers/implementations/serializers/serializer_local.h with 99% similarity]
providers/implementations/encode_decode/encoder_rsa.c [moved from providers/implementations/serializers/serializer_rsa.c with 98% similarity]
providers/implementations/encode_decode/encoder_rsa_priv.c [moved from providers/implementations/serializers/serializer_rsa_priv.c with 74% similarity]
providers/implementations/encode_decode/encoder_rsa_pub.c [moved from providers/implementations/serializers/serializer_rsa_pub.c with 75% similarity]
providers/implementations/include/prov/implementations.h
providers/implementations/serializers/build.info [deleted file]
providers/serializers.inc [deleted file]
test/build.info
test/endecode_test.c [moved from test/serdes_test.c with 79% similarity]
test/evp_pkey_provided_test.c
test/recipes/04-test_encoder_decoder.t [moved from test/recipes/04-test_serializer_deserializer.t with 89% similarity]
util/libcrypto.num
util/missingcrypto.txt
util/other.syms

index 31e183f..c2bbf0d 100644 (file)
@@ -612,22 +612,22 @@ OpenSSL 3.0
 
    *Rich Salz*
 
- * Introduced a new method type and API, OSSL_SERIALIZER, to
-   represent generic serializers.  An implementation is expected to
-   be able to serialize an object associated with a given name (such
+ * Introduced a new method type and API, OSSL_ENCODER, to
+   represent generic encoders.  An implementation is expected to
+   be able to encode an object associated with a given name (such
    as an algorithm name for an asymmetric key) into forms given by
    implementation properties.
 
-   Serializers are primarily used from inside libcrypto, through
+   Encoders are primarily used from inside libcrypto, through
    calls to functions like EVP_PKEY_print_private(),
    PEM_write_bio_PrivateKey() and similar.
 
-   Serializers are specified in such a way that they can be made to
+   Encoders are specified in such a way that they can be made to
    directly handle the provider side portion of an object, if this
-   provider side part comes from the same provider as the serializer
+   provider side part comes from the same provider as the encoder
    itself, but can also be made to handle objects in parametrized
    form (as an OSSL_PARAM array of data).  This allows a provider to
-   offer generic serializers as a service for any other provider.
+   offer generic encoders as a service for any other provider.
 
    *Richard Levitte*
 
@@ -769,13 +769,13 @@ OpenSSL 3.0
    *Richard Levitte*
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
@@ -1255,13 +1255,13 @@ OpenSSL 1.1.1
    *Matthias St. Pierre*
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
@@ -2025,13 +2025,13 @@ OpenSSL 1.1.0
 ### Changes between 1.1.0k and 1.1.0l [10 Sep 2019]
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
@@ -3822,13 +3822,13 @@ OpenSSL 1.0.2
 ### Changes between 1.0.2s and 1.0.2t [10 Sep 2019]
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
diff --git a/NEWS.md b/NEWS.md
index e40b293..4b0171f 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -43,7 +43,7 @@ OpenSSL 3.0
   * Added a proper HTTP(S) client to libcrypto supporting GET and POST,
     redirection, plain and ASN.1-encoded contents, proxies, and timeouts.
   * Added util/check-format.pl for checking adherence to the coding guidelines.
-  * Added OSSL_SERIALIZER, a generic serializer API.
+  * Added OSSL_ENCODER, a generic encoder API.
   * Added OSSL_PARAM_BLD, an easier to use API to OSSL_PARAM.
   * Added error raising macros, ERR_raise() and ERR_raise_data().
   * Deprecated ERR_put_error().
index 69a5167..c891bf7 100644 (file)
@@ -16,8 +16,8 @@
 #include <openssl/provider.h>
 #include <openssl/safestack.h>
 #include <openssl/kdf.h>
-#include <openssl/serializer.h>
-#include <openssl/deserializer.h>
+#include <openssl/encoder.h>
+#include <openssl/decoder.h>
 #include <openssl/core_names.h>
 #include "apps.h"
 #include "app_params.h"
@@ -355,124 +355,124 @@ static void list_random_generators(void)
 }
 
 /*
- * Serializers
+ * Encoders
  */
-DEFINE_STACK_OF(OSSL_SERIALIZER)
-static int serializer_cmp(const OSSL_SERIALIZER * const *a,
-                          const OSSL_SERIALIZER * const *b)
+DEFINE_STACK_OF(OSSL_ENCODER)
+static int encoder_cmp(const OSSL_ENCODER * const *a,
+                       const OSSL_ENCODER * const *b)
 {
-    int ret = OSSL_SERIALIZER_number(*a) - OSSL_SERIALIZER_number(*b);
+    int ret = OSSL_ENCODER_number(*a) - OSSL_ENCODER_number(*b);
 
     if (ret == 0)
-        ret = strcmp(OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(*a)),
-                     OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(*b)));
+        ret = strcmp(OSSL_PROVIDER_name(OSSL_ENCODER_provider(*a)),
+                     OSSL_PROVIDER_name(OSSL_ENCODER_provider(*b)));
     return ret;
 }
 
-static void collect_serializers(OSSL_SERIALIZER *serializer, void *stack)
+static void collect_encoders(OSSL_ENCODER *encoder, void *stack)
 {
-    STACK_OF(OSSL_SERIALIZER) *serializer_stack = stack;
+    STACK_OF(OSSL_ENCODER) *encoder_stack = stack;
 
-    sk_OSSL_SERIALIZER_push(serializer_stack, serializer);
-    OSSL_SERIALIZER_up_ref(serializer);
+    sk_OSSL_ENCODER_push(encoder_stack, encoder);
+    OSSL_ENCODER_up_ref(encoder);
 }
 
-static void list_serializers(void)
+static void list_encoders(void)
 {
-    STACK_OF(OSSL_SERIALIZER) *serializers;
+    STACK_OF(OSSL_ENCODER) *encoders;
     int i;
 
-    serializers = sk_OSSL_SERIALIZER_new(serializer_cmp);
-    if (serializers == NULL) {
+    encoders = sk_OSSL_ENCODER_new(encoder_cmp);
+    if (encoders == NULL) {
         BIO_printf(bio_err, "ERROR: Memory allocation\n");
         return;
     }
-    BIO_printf(bio_out, "Provided SERIALIZERs:\n");
-    OSSL_SERIALIZER_do_all_provided(NULL, collect_serializers, serializers);
-    sk_OSSL_SERIALIZER_sort(serializers);
+    BIO_printf(bio_out, "Provided ENCODERs:\n");
+    OSSL_ENCODER_do_all_provided(NULL, collect_encoders, encoders);
+    sk_OSSL_ENCODER_sort(encoders);
 
-    for (i = 0; i < sk_OSSL_SERIALIZER_num(serializers); i++) {
-        OSSL_SERIALIZER *k = sk_OSSL_SERIALIZER_value(serializers, i);
+    for (i = 0; i < sk_OSSL_ENCODER_num(encoders); i++) {
+        OSSL_ENCODER *k = sk_OSSL_ENCODER_value(encoders, i);
         STACK_OF(OPENSSL_CSTRING) *names =
             sk_OPENSSL_CSTRING_new(name_cmp);
 
-        OSSL_SERIALIZER_names_do_all(k, collect_names, names);
+        OSSL_ENCODER_names_do_all(k, collect_names, names);
 
         BIO_printf(bio_out, "  ");
         print_names(bio_out, names);
         BIO_printf(bio_out, " @ %s (%s)\n",
-                   OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(k)),
-                   OSSL_SERIALIZER_properties(k));
+                   OSSL_PROVIDER_name(OSSL_ENCODER_provider(k)),
+                   OSSL_ENCODER_properties(k));
 
         sk_OPENSSL_CSTRING_free(names);
 
         if (verbose) {
             print_param_types("settable operation parameters",
-                              OSSL_SERIALIZER_settable_ctx_params(k), 4);
+                              OSSL_ENCODER_settable_ctx_params(k), 4);
         }
     }
-    sk_OSSL_SERIALIZER_pop_free(serializers, OSSL_SERIALIZER_free);
+    sk_OSSL_ENCODER_pop_free(encoders, OSSL_ENCODER_free);
 }
 
 /*
- * Deserializers
+ * Decoders
  */
-DEFINE_STACK_OF(OSSL_DESERIALIZER)
-static int deserializer_cmp(const OSSL_DESERIALIZER * const *a,
-                            const OSSL_DESERIALIZER * const *b)
+DEFINE_STACK_OF(OSSL_DECODER)
+static int decoder_cmp(const OSSL_DECODER * const *a,
+                       const OSSL_DECODER * const *b)
 {
-    int ret = OSSL_DESERIALIZER_number(*a) - OSSL_DESERIALIZER_number(*b);
+    int ret = OSSL_DECODER_number(*a) - OSSL_DECODER_number(*b);
 
     if (ret == 0)
-        ret = strcmp(OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(*a)),
-                     OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(*b)));
+        ret = strcmp(OSSL_PROVIDER_name(OSSL_DECODER_provider(*a)),
+                     OSSL_PROVIDER_name(OSSL_DECODER_provider(*b)));
     return ret;
 }
 
-static void collect_deserializers(OSSL_DESERIALIZER *deserializer, void *stack)
+static void collect_decoders(OSSL_DECODER *decoder, void *stack)
 {
-    STACK_OF(OSSL_DESERIALIZER) *deserializer_stack = stack;
+    STACK_OF(OSSL_DECODER) *decoder_stack = stack;
 
-    sk_OSSL_DESERIALIZER_push(deserializer_stack, deserializer);
-    OSSL_DESERIALIZER_up_ref(deserializer);
+    sk_OSSL_DECODER_push(decoder_stack, decoder);
+    OSSL_DECODER_up_ref(decoder);
 }
 
-static void list_deserializers(void)
+static void list_decoders(void)
 {
-    STACK_OF(OSSL_DESERIALIZER) *deserializers;
+    STACK_OF(OSSL_DECODER) *decoders;
     int i;
 
-    deserializers = sk_OSSL_DESERIALIZER_new(deserializer_cmp);
-    if (deserializers == NULL) {
+    decoders = sk_OSSL_DECODER_new(decoder_cmp);
+    if (decoders == NULL) {
         BIO_printf(bio_err, "ERROR: Memory allocation\n");
         return;
     }
-    BIO_printf(bio_out, "Provided DESERIALIZERs:\n");
-    OSSL_DESERIALIZER_do_all_provided(NULL, collect_deserializers,
-                                      deserializers);
-    sk_OSSL_DESERIALIZER_sort(deserializers);
+    BIO_printf(bio_out, "Provided DECODERs:\n");
+    OSSL_DECODER_do_all_provided(NULL, collect_decoders,
+                                 decoders);
+    sk_OSSL_DECODER_sort(decoders);
 
-    for (i = 0; i < sk_OSSL_DESERIALIZER_num(deserializers); i++) {
-        OSSL_DESERIALIZER *k = sk_OSSL_DESERIALIZER_value(deserializers, i);
+    for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) {
+        OSSL_DECODER *k = sk_OSSL_DECODER_value(decoders, i);
         STACK_OF(OPENSSL_CSTRING) *names =
             sk_OPENSSL_CSTRING_new(name_cmp);
 
-        OSSL_DESERIALIZER_names_do_all(k, collect_names, names);
+        OSSL_DECODER_names_do_all(k, collect_names, names);
 
         BIO_printf(bio_out, "  ");
         print_names(bio_out, names);
         BIO_printf(bio_out, " @ %s (%s)\n",
-                   OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(k)),
-                   OSSL_DESERIALIZER_properties(k));
+                   OSSL_PROVIDER_name(OSSL_DECODER_provider(k)),
+                   OSSL_DECODER_properties(k));
 
         sk_OPENSSL_CSTRING_free(names);
 
         if (verbose) {
             print_param_types("settable operation parameters",
-                              OSSL_DESERIALIZER_settable_ctx_params(k), 4);
+                              OSSL_DECODER_settable_ctx_params(k), 4);
         }
     }
-    sk_OSSL_DESERIALIZER_pop_free(deserializers, OSSL_DESERIALIZER_free);
+    sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free);
 }
 
 static void list_missing_help(void)
@@ -554,7 +554,7 @@ static void list_options_for_command(const char *command)
             break;
     if (fp->name == NULL) {
         BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
-                command);
+                   command);
         return;
     }
 
@@ -821,8 +821,8 @@ typedef enum HELPLIST_CHOICE {
     OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
-    OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_SERIALIZERS,
-    OPT_DESERIALIZERS,
+    OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_ENCODERS,
+    OPT_DECODERS,
     OPT_MISSING_HELP, OPT_OBJECTS,
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     OPT_ENGINES, 
@@ -847,15 +847,14 @@ const OPTIONS list_options[] = {
     {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
      "List of key derivation and pseudo random function algorithms"},
     {"random-generators", OPT_RANDOM_GENERATORS, '-',
-      "List of random number generators"},
+     "List of random number generators"},
     {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
      "List of message authentication code algorithms"},
     {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"},
     {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
      "List of cipher algorithms"},
-    {"serializers", OPT_SERIALIZERS, '-', "List of serialization methods" },
-    {"deserializers", OPT_DESERIALIZERS, '-',
-      "List of deserialization methods" },
+    {"encoders", OPT_ENCODERS, '-', "List of encoding methods" },
+    {"decoders", OPT_DECODERS, '-', "List of decoding methods" },
     {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
      "List of public key algorithms"},
 #ifndef OPENSSL_NO_DEPRECATED_3_0
@@ -890,8 +889,8 @@ int list_main(int argc, char **argv)
         unsigned int mac_algorithms:1;
         unsigned int cipher_commands:1;
         unsigned int cipher_algorithms:1;
-        unsigned int serializer_algorithms:1;
-        unsigned int deserializer_algorithms:1;
+        unsigned int encoder_algorithms:1;
+        unsigned int decoder_algorithms:1;
         unsigned int pk_algorithms:1;
         unsigned int pk_method:1;
 #ifndef OPENSSL_NO_DEPRECATED_3_0
@@ -943,11 +942,11 @@ opthelp:
         case OPT_CIPHER_ALGORITHMS:
             todo.cipher_algorithms = 1;
             break;
-        case OPT_SERIALIZERS:
-            todo.serializer_algorithms = 1;
+        case OPT_ENCODERS:
+            todo.encoder_algorithms = 1;
             break;
-        case OPT_DESERIALIZERS:
-            todo.deserializer_algorithms = 1;
+        case OPT_DECODERS:
+            todo.decoder_algorithms = 1;
             break;
         case OPT_PK_ALGORITHMS:
             todo.pk_algorithms = 1;
@@ -1003,10 +1002,10 @@ opthelp:
         list_type(FT_cipher, one);
     if (todo.cipher_algorithms)
         list_ciphers();
-    if (todo.serializer_algorithms)
-        list_serializers();
-    if (todo.deserializer_algorithms)
-        list_deserializers();
+    if (todo.encoder_algorithms)
+        list_encoders();
+    if (todo.decoder_algorithms)
+        list_decoders();
     if (todo.pk_algorithms)
         list_pkey();
 #ifndef OPENSSL_NO_DEPRECATED_3_0
index 545300c..84513db 100644 (file)
@@ -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);
index 8362502..07e3dd5 100644 (file)
@@ -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 (file)
index 0000000..4686c4a
--- /dev/null
@@ -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
similarity index 55%
rename from crypto/serializer/deserializer_err.c
rename to crypto/encode_decode/decoder_err.c
index 2cc2459..984f7ab 100644 (file)
@@ -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 (file)
index 0000000..21b4703
--- /dev/null
@@ -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 (file)
index 0000000..2259c63
--- /dev/null
@@ -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);
+    }
+}
similarity index 65%
rename from crypto/serializer/deserializer_pkey.c
rename to crypto/encode_decode/decoder_pkey.c
index 6375a29..7f468c2 100644 (file)
 #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 (file)
index 0000000..5416f83
--- /dev/null
@@ -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;
+}
similarity index 71%
rename from crypto/serializer/serializer_lib.c
rename to crypto/encode_decode/encoder_lib.c
index 932ef1e..b083fa2 100644 (file)
@@ -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 (file)
index 0000000..34931d4
--- /dev/null
@@ -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 (file)
index 0000000..ef3c244
--- /dev/null
@@ -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 (file)
index 0000000..dc776c0
--- /dev/null
@@ -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;
+}
+
similarity index 80%
rename from crypto/serializer/serdes_pass.c
rename to crypto/encode_decode/endecode_pass.c
index 7520095..113f5ee 100644 (file)
@@ -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;
index e2d70d7..9098112 100644 (file)
@@ -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},
 };
index f1bed12..037611d 100644 (file)
@@ -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
index 10531ea..3a5a5b5 100644 (file)
@@ -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
index bee6337..7a79816 100644 (file)
@@ -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);
 }
index 1ab3093..2f9346d 100644 (file)
@@ -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
 
index 2fb1e6f..81d1718 100644 (file)
  */
 
 #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()                       \
     }                                                                   \
     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:                                                             \
     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)
 
index 12a25b7..84d4318 100644 (file)
@@ -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)
index 4ee5bb7..e355afe 100644 (file)
@@ -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"
index 91b830c..6d6ca9b 100644 (file)
@@ -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 (file)
index 11f8889..0000000
+++ /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 (file)
index aa3b552..0000000
+++ /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 (file)
index 69099f5..0000000
+++ /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 (file)
index 2ea8b8b..0000000
+++ /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 (file)
index d139e40..0000000
+++ /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 (file)
index 1489fff..0000000
+++ /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 (file)
index d31b3cc..0000000
+++ /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;
-}
-
index 59f4a14..cb47f91 100644 (file)
@@ -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;
index df970a0..2668084 100644 (file)
@@ -19,8 +19,8 @@ B<openssl list>
 [B<-random-generators>]
 [B<-cipher-commands>]
 [B<-cipher-algorithms>]
-[B<-serializers>]
-[B<-deserializers>]
+[B<-encoders>]
+[B<-decoders>]
 [B<-public-key-algorithms>]
 {- output_off() if $disabled{"deprecated-3.0"}; ""
 -}[B<-public-key-methods>]
@@ -84,18 +84,18 @@ Display a list of random number generators.
 See L</Display of algorithm names> for a description of how names are
 displayed.
 
-=item B<-serializers>
+=item B<-encoders>
 
-Display a list of serializers.
+Display a list of encoders.
 See L</Display of algorithm names> for a description of how names are
 displayed.
 
 In verbose mode, the algorithms provided by a provider will get additional
 information on what parameters each implementation supports.
 
-=item B<-deserializers>
+=item B<-decoders>
 
-Display a list of deserializers.
+Display a list of decoders.
 See L</Display of algorithm names> for a description of how names are
 displayed.
 
diff --git a/doc/man3/OSSL_DECODER.pod b/doc/man3/OSSL_DECODER.pod
new file mode 100644 (file)
index 0000000..96d0a51
--- /dev/null
@@ -0,0 +1,142 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER,
+OSSL_DECODER_fetch,
+OSSL_DECODER_up_ref,
+OSSL_DECODER_free,
+OSSL_DECODER_provider,
+OSSL_DECODER_properties,
+OSSL_DECODER_is_a,
+OSSL_DECODER_number,
+OSSL_DECODER_do_all_provided,
+OSSL_DECODER_names_do_all,
+OSSL_DECODER_gettable_params,
+OSSL_DECODER_get_params
+- Decoder method routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ typedef struct ossl_decoder_st OSSL_DECODER;
+
+ OSSL_DECODER *OSSL_DECODER_fetch(OPENSSL_CTX *ctx, const char *name,
+                                  const char *properties);
+ int OSSL_DECODER_up_ref(OSSL_DECODER *decoder);
+ void OSSL_DECODER_free(OSSL_DECODER *decoder);
+ const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *decoder);
+ const char *OSSL_DECODER_properties(const OSSL_DECODER *decoder);
+ int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name);
+ int OSSL_DECODER_number(const OSSL_DECODER *decoder);
+ void OSSL_DECODER_do_all_provided(OPENSSL_CTX *libctx,
+                                   void (*fn)(OSSL_DECODER *decoder, void *arg),
+                                   void *arg);
+ void OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder,
+                                void (*fn)(const char *name, void *data),
+                                void *data);
+ const OSSL_PARAM *OSSL_DECODER_gettable_params(OSSL_DECODER *decoder);
+ int OSSL_DECODER_get_params(OSSL_DECODER_CTX *ctx, const OSSL_PARAM params[]);
+
+=head1 DESCRIPTION
+
+B<OSSL_DECODER> is a method for decoders, which know how to
+decode encoded data into an object of some type that the rest
+of OpenSSL knows how to handle.
+
+OSSL_DECODER_fetch() looks for an algorithm within the provider that
+has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
+name given by I<name> and the properties given by I<properties>.
+The I<name> determines what type of object the fetched decoder
+method is expected to be able to decode, and the properties are
+used to determine the expected output type.
+For known properties and the values they may have, please have a look
+in L<provider-encoder(7)/Names and properties>.
+
+OSSL_DECODER_up_ref() increments the reference count for the given
+I<decoder>.
+
+OSSL_DECODER_free() decrements the reference count for the given
+I<decoder>, and when the count reaches zero, frees it.
+
+OSSL_DECODER_provider() returns the provider of the given
+I<decoder>.
+
+OSSL_DECODER_properties() returns the property definition associated
+with the given I<decoder>.
+
+OSSL_DECODER_is_a() checks if I<decoder> is an implementation
+of an algorithm that's identifiable with I<name>.
+
+OSSL_DECODER_number() returns the internal dynamic number assigned
+to the given I<decoder>.
+
+OSSL_DECODER_names_do_all() traverses all names for the given
+I<decoder>, and calls I<fn> with each name and I<data>.
+
+OSSL_DECODER_do_all_provided() traverses all encoder
+implementations by all activated providers in the library context
+I<libctx>, and for each of the implementations, calls I<fn> with the
+implementation method and I<data> as arguments.
+
+OSSL_DECODER_gettable_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_DECODER_get_params() attempts to get parameters specified
+with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
+implementation doesn't recognise should be ignored.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_fetch() returns a pointer to an OSSL_DECODER object,
+or NULL on error.
+
+OSSL_DECODER_up_ref() returns 1 on success, or 0 on error.
+
+OSSL_DECODER_free() doesn't return any value.
+
+OSSL_DECODER_provider() returns a pointer to a provider object, or
+NULL on error.
+
+OSSL_DECODER_properties() returns a pointer to a property
+definition string, or NULL on error.
+
+OSSL_DECODER_is_a() returns 1 if I<decoder> was identifiable,
+otherwise 0.
+
+OSSL_DECODER_number() returns an integer.
+
+=head1 NOTES
+
+OSSL_DECODER_fetch() may be called implicitly by other fetching
+functions, using the same library context and properties.
+Any other API that uses keys will typically do this.
+
+=begin comment TODO(3.0) Add examples!
+
+=head1 EXAMPLES
+
+Text, because pod2xxx doesn't like empty sections
+
+=end comment
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER_CTX(3)>, L<OSSL_DECODER_from_bio(3)>,
+L<OSSL_DECODER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DECODER_CTX.pod b/doc/man3/OSSL_DECODER_CTX.pod
new file mode 100644 (file)
index 0000000..7dbd755
--- /dev/null
@@ -0,0 +1,74 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER_CTX,
+OSSL_DECODER_CTX_new,
+OSSL_DECODER_settable_ctx_params,
+OSSL_DECODER_CTX_set_params,
+OSSL_DECODER_CTX_free
+- Encoder context routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ typedef struct ossl_decoder_ctx_st OSSL_DECODER_CTX;
+
+ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(OPENSSL_CTX *libctx);
+ const OSSL_PARAM *OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder);
+ int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
+                                 const OSSL_PARAM params[]);
+ void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx);
+
+=head1 DESCRIPTION
+
+B<OSSL_DECODER_CTX> is a context with which B<OSSL_DECODER>
+operations are performed.  The context typically holds values, both
+internal and supplied by the application, which are useful for the
+implementations supplied by providers.
+
+OSSL_DECODER_CTX_new() creates a new empty B<OSSL_DECODER_CTX>.
+
+OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_DECODER_CTX_set_params() attempts to set parameters specified
+with an L<OSSL_PARAM(3)> array I<params>.  These parameters are passed
+to all decoders that have been added to the I<ctx> so far.
+Parameters that an implementation doesn't recognise should be ignored
+by it.
+
+OSSL_DECODER_CTX_free() frees the given context I<ctx>.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_CTX_new() returns a pointer to a
+B<OSSL_DECODER_CTX>, or NULL if the context structure couldn't be
+allocated.
+
+OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array, or NULL if none is available.
+
+OSSL_DECODER_CTX_set_params() returns 1 if all recognised
+parameters were valid, or 0 if one of them was invalid or caused some
+other failure in the implementation.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER(3)>, L<OSSL_DECODER_from_bio(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod
new file mode 100644 (file)
index 0000000..4486e6b
--- /dev/null
@@ -0,0 +1,109 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER_CTX_new_by_EVP_PKEY,
+OSSL_DECODER_CTX_set_passphrase,
+OSSL_DECODER_CTX_set_pem_password_cb,
+OSSL_DECODER_CTX_set_passphrase_ui
+- Decoder routines to decode EVP_PKEYs
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ OSSL_DECODER_CTX *
+ OSSL_DECODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, const char *input_type,
+                                  OPENSSL_CTX *libctx, const char *propquery);
+
+ int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
+                                     const unsigned char *kstr,
+                                     size_t klen);
+ int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
+                                          pem_password_cb *cb,
+                                          void *cbarg);
+ int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
+                                        const UI_METHOD *ui_method,
+                                        void *ui_data);
+
+=head1 DESCRIPTION
+
+OSSL_DECODER_CTX_new_by_EVP_PKEY() is a utility function that
+creates a B<OSSL_DECODER_CTX>, finds all applicable decoder
+implementations and sets them up, so all the caller has to do next is
+call functions like OSSL_DECODE_from_bio().
+
+Internally OSSL_DECODER_CTX_new_by_EVP_PKEY() searches for all
+available L<EVP_KEYMGMT(3)> implementations, and then builds a list of all
+potential decoder implementations that may be able to process the
+encoded input into data suitable for B<EVP_PKEY>s.  All these
+implementations are implicitly fetched using I<libctx> and I<propquery>.
+
+The search of decoder implementations can be limited with
+I<input_type>, which specifies a starting input type.  This is further
+explained in L<OSSL_DECODER_CTX_set_input_type(3)>.
+
+If no suitable decoder was found, OSSL_DECODER_CTX_new_by_EVP_PKEY()
+still creates a B<OSSL_DECODER_CTX>, but with no associated
+decoder (L<OSSL_DECODER_CTX_num_decoders(3)> returns
+zero).  This helps the caller distinguish between an error when
+creating the B<OSSL_DECODER_CTX>, and the lack the decoder
+support and act accordingly.
+
+OSSL_DECODER_CTX_set_passphrase() gives the implementation a
+pass phrase to use when decrypting the encoded private key.
+Alternatively, a pass phrase callback may be specified with the
+following functions.
+
+OSSL_DECODER_CTX_set_pem_password_cb() and
+OSSL_DECODER_CTX_set_passphrase_ui() set up a callback method that
+the implementation can use to prompt for a pass phrase, giving the caller
+the choice of prefered pass phrase callback form.  These are called
+indirectly, through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
+
+The internal B<OSSL_PASSPHRASE_CALLBACK> function caches the pass phrase, to
+be re-used in all decodings that are performed in the same
+decoding run
+(for example, within one L<OSSL_DECODER_from_bio(3)> call).
+
+=for comment the name OSSL_DECODER_CTX_set_pem_password_cb() leaves
+open the future possibility of having a function where the caller can set a
+B<OSSL_PASSPHRASE_CALLBACK> method as another option.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_CTX_new_by_EVP_PKEY() returns a pointer to a
+B<OSSL_DECODER_CTX>, or NULL if it couldn't be created.
+
+OSSL_DECODER_CTX_set_passphrase(),
+OSSL_DECODER_CTX_set_pem_password_cb() and
+OSSL_DECODER_CTX_set_passphrase_ui()
+all return 1 on success, or 0 on failure.
+
+=head1 NOTES
+
+Parts of the function names are made to match already existing OpenSSL
+names.
+
+B<EVP_PKEY> in OSSL_DECODER_CTX_new_by_EVP_PKEY() matches the type
+name, thus making for the naming pattern
+B<OSSL_DECODER_CTX_new_by_I<TYPE>>() when new types are handled.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER(3)>, L<OSSL_DECODER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DECODER_from_bio.pod b/doc/man3/OSSL_DECODER_from_bio.pod
new file mode 100644 (file)
index 0000000..1beb74d
--- /dev/null
@@ -0,0 +1,276 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER_from_bio,
+OSSL_DECODER_from_fp,
+OSSL_DECODER_CTX_set_input_type,
+OSSL_DECODER_CTX_add_decoder,
+OSSL_DECODER_CTX_add_extra,
+OSSL_DECODER_CTX_num_decoders,
+OSSL_DECODER_INSTANCE,
+OSSL_DECODER_CONSTRUCT,
+OSSL_DECODER_CLEANUP,
+OSSL_DECODER_CTX_set_construct,
+OSSL_DECODER_CTX_set_construct_data,
+OSSL_DECODER_CTX_set_cleanup,
+OSSL_DECODER_CTX_get_construct,
+OSSL_DECODER_CTX_get_construct_data,
+OSSL_DECODER_CTX_get_cleanup,
+OSSL_DECODER_export,
+OSSL_DECODER_INSTANCE_decoder,
+OSSL_DECODER_INSTANCE_decoder_ctx
+- Routines to perform a decoding
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in);
+ int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp);
+
+ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
+                                     const char *input_type);
+ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder);
+ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx);
+ int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx);
+
+ typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE;
+ OSSL_DECODER *
+ OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst);
+ void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst);
+
+ typedef int (OSSL_DECODER_CONSTRUCT)(OSSL_DECODER_INSTANCE *decoder_inst,
+                                      const OSSL_PARAM *params,
+                                      void *construct_data);
+ typedef void (OSSL_DECODER_CLEANUP)(void *construct_data);
+
+ int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
+                                    OSSL_DECODER_CONSTRUCT *construct);
+ int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
+                                         void *construct_data);
+ int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
+                                  OSSL_DECODER_CLEANUP *cleanup);
+ OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx);
+ void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx);
+ OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx);
+
+ int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
+                         void *reference, size_t reference_sz,
+                         OSSL_CALLBACK *export_cb, void *export_cbarg);
+
+Feature availability macros:
+
+=over 4
+
+=item OSSL_DECODER_from_fp() is only available when B<OPENSSL_NO_STDIO>
+is undefined.
+
+=back
+
+=head1 DESCRIPTION
+
+The B<OSSL_DECODER_CTX> holds data about multiple decoders, as
+needed to figure out what the input data is and to attempt to unpack it into
+one of several possible related results.  This also includes chaining
+decoders, so the output from one can become the input for another.
+This allows having generic format decoders such as PEM to DER, as well
+as more specialized decoders like DER to RSA.
+
+The chains may be limited by specifying an input type, which is considered a
+starting point.
+This is both considered by OSSL_DECODER_CTX_add_extra(), which will
+stop adding on more decoder implementations when it has already added
+those that take the specified input type, and OSSL_DECODER_from_bio(),
+which will only start the decoding process with the decoder
+implementations that take that input type.  For example, if the input type
+is set to C<DER>, a PEM to DER decoder will be ignored.
+
+The input type can also be NULL, which means that the caller doesn't know
+what type of input they have.  In this case, OSSL_DECODER_from_bio()
+will simply try with one decoder implementation after the other, and
+thereby discover what kind of input the caller gave it.
+
+For every decoding done, even an intermediary one, a constructor
+provided by the caller is called to attempt to construct an appropriate type
+/ structure that the caller knows how to handle from the current
+decoding result.
+The constructor is set with OSSL_DECODER_CTX_set_construct().
+
+B<OSSL_DECODER_INSTANCE> is an opaque structure that contains
+data about the decoder that was just used, and that may be
+useful for the constructor.  There are some functions to extract data
+from this type, described further down.
+
+=head2 Functions
+
+OSSL_DECODER_from_bio() runs the decoding process for the
+context I<ctx>, with the input coming from the B<BIO> I<in>.  Should
+it make a difference, it's recommended to have the BIO set in binary
+mode rather than text mode.
+
+OSSL_DECODER_from_fp() does the same thing as OSSL_DECODER_from_bio(),
+except that the input is coming from the B<FILE> I<fp>.
+
+OSSL_DECODER_CTX_add_decoder() populates the B<OSSL_DECODER_CTX>
+I<ctx> with a decoder, to be used to attempt to decode some
+encoded input.
+
+OSSL_DECODER_CTX_add_extra() finds decoders that generate
+input for already added decoders, and adds them as well.  This is
+used to build decoder chains.
+
+OSSL_DECODER_CTX_set_input_type() sets the starting input type.  This
+limits the decoder chains to be considered, as explained in the general
+description above.
+
+OSSL_DECODER_CTX_num_decoders() gets the number of
+decoders currently added to the context I<ctx>.
+
+OSSL_DECODER_CTX_set_construct() sets the constructor I<construct>.
+
+OSSL_DECODER_CTX_set_construct_data() sets the constructor data that is
+passed to the constructor every time it's called.
+
+OSSL_DECODER_CTX_set_cleanup() sets the constructor data I<cleanup>
+function.  This is called by L<OSSL_DECODER_CTX_free(3)>.
+
+OSSL_DECODER_CTX_get_construct(),
+OSSL_DECODER_CTX_get_construct_data() and
+OSSL_DECODER_CTX_get_cleanup()
+return the values that have been set by
+OSSL_DECODER_CTX_set_construct(),
+OSSL_DECODER_CTX_set_construct_data() and
+OSSL_DECODER_CTX_set_cleanup() respectively.
+
+OSSL_DECODER_export() is a fallback function for constructors that
+cannot use the data they get directly for diverse reasons.  It takes the same
+decode instance I<decoder_inst> that the constructor got and an object
+I<reference>, unpacks the object which it refers to, and exports it by creating
+an L<OSSL_PARAM(3)> array that it then passes to I<export_cb>, along with
+I<export_arg>.
+
+OSSL_DECODER_INSTANCE_decoder() can be used to get the
+decoder method from a decoder instance I<decoder_inst>.
+
+OSSL_DECODER_INSTANCE_decoder-ctx() can be used to get the
+decoder method's provider context from a decoder instance
+I<decoder_inst>.
+
+=head2 Constructor
+
+A B<OSSL_DECODER_CONSTRUCT> gets the following arguments:
+
+=over 4
+
+=item I<decoder_inst>
+
+The B<OSSL_DECODER_INSTANCE> for the decoder from which
+the constructor gets its data.
+
+=item I<params>
+
+The data produced by the decoder, further described below.
+
+=item I<construct_data>
+
+The pointer that was set with OSSL_DECODE_CTX_set_construct_data().
+
+=back
+
+The constructor is expected to return 1 when the data it receives can
+be constructed, otherwise 0.
+
+The globally known parameters that the constructor can get in I<params>
+are:
+
+=over 4
+
+=item "data-type" (B<OSSL_DECODER_PARAM_DATA_TYPE>) <UTF8 string>
+
+This is a detected content type that some decoders may provide.
+For example, PEM input sometimes has a type specified in its header,
+and some decoders may add that information as this parameter.
+This is an optional parameter, but may be useful for extra checks in
+the constructor.
+
+=item "data" (B<OSSL_DECODER_PARAM_DATA>) <octet string>
+
+The decoded data itself, as an octet string.  This is produced by
+decoders when it's possible to pass an object in this form.  Most
+often, this is simply meant to be passed to the next decoder in a
+chain, but could be considered final data as well, at the discretion
+of the constructor.
+
+=item "reference" (B<OSSL_DECODER_PARAM_DATA>) <octet string>
+
+The decoded data itself, as a reference to an object.  The
+reference itself is an octet string, and can be passed to other
+operations and functions within the same provider as the one that
+provides I<decoder>.
+
+=back
+
+At least one of "data" or "reference" must be present, and it's
+possible that both can be.  A constructor should choose to use the
+"reference" parameter if possible, otherwise it should use the "data"
+parameter.
+
+If it's not possible to use the "reference" parameter, but that's
+still what a constructor wants to do, it is possible to use
+OSSL_DECODER_export() as a fallback.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_from_bio() and OSSL_DECODER_from_fp() return 1 on
+success, or 0 on failure.
+
+OSSL_DECODER_CTX_add_decoder(),
+OSSL_DECODER_CTX_add_extra(),
+OSSL_DECODER_CTX_set_construct(),
+OSSL_DECODER_CTX_set_construct_data() and
+OSSL_DECODER_CTX_set_cleanup() return 1 on success, or 0 on
+failure.
+
+OSSL_DECODER_CTX_get_construct(),
+OSSL_DECODER_CTX_get_construct_data() and
+OSSL_DECODER_CTX_get_cleanup() return the current pointers to the
+cosntructor, the constructor data and the cleanup functions, respectively.
+
+OSSL_DECODER_CTX_num_decoders() returns the current
+number of decoders.  It returns 0 if I<ctx> is NULL.
+
+OSSL_DECODER_export() returns 1 on success, or 0 on failure.
+
+OSSL_DECODER_INSTANCE_decoder() returns an
+B<OSSL_DECODER> pointer on success, or NULL on failure.
+
+OSSL_DECODER_INSTANCE_decoder_ctx() returns a provider
+context pointer on success, or NULL on failure.>
+
+=begin comment TODO(3.0) Add examples!
+
+=head1 EXAMPLES
+
+Text, because pod2xxx doesn't like empty sections
+
+=end comment
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DESERIALIZER.pod b/doc/man3/OSSL_DESERIALIZER.pod
deleted file mode 100644 (file)
index 5562a81..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER,
-OSSL_DESERIALIZER_fetch,
-OSSL_DESERIALIZER_up_ref,
-OSSL_DESERIALIZER_free,
-OSSL_DESERIALIZER_provider,
-OSSL_DESERIALIZER_properties,
-OSSL_DESERIALIZER_is_a,
-OSSL_DESERIALIZER_number,
-OSSL_DESERIALIZER_do_all_provided,
-OSSL_DESERIALIZER_names_do_all,
-OSSL_DESERIALIZER_gettable_params,
-OSSL_DESERIALIZER_get_params
-- Deserializer method routines
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- typedef struct ossl_deserializer_st OSSL_DESERIALIZER;
-
- OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *ctx, const char *name,
-                                            const char *properties);
- int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *deserializer);
- void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *deserializer);
- const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER
-                                                 *deserializer);
- const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *deserializer,
-                            const char *name);
- int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *deserializer);
- void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                        void (*fn)(OSSL_DESERIALIZER *deserializer,
-                                                   void *arg),
-                                        void *arg);
- void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *deserializer,
-                                     void (*fn)(const char *name, void *data),
-                                     void *data);
- const OSSL_PARAM *OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER_CTX *ctx,
-                                  const OSSL_PARAM params[]);
-
-=head1 DESCRIPTION
-
-B<OSSL_DESERIALIZER> is a method for deserializers, which know how to
-deserialize serialized data into an object of some type that the rest
-of OpenSSL knows how to handle.
-
-OSSL_DESERIALIZER_fetch() looks for an algorithm within the provider that
-has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
-name given by I<name> and the properties given by I<properties>.
-The I<name> determines what type of object the fetched deserializer
-method is expected to be able to deserialize, and the properties are
-used to determine the expected output type.
-For known properties and the values they may have, please have a look
-in L<provider-serializer(7)/Names and properties>.
-
-OSSL_DESERIALIZER_up_ref() increments the reference count for the given
-I<deserializer>.
-
-OSSL_DESERIALIZER_free() decrements the reference count for the given
-I<deserializer>, and when the count reaches zero, frees it.
-
-OSSL_DESERIALIZER_provider() returns the provider of the given
-I<deserializer>.
-
-OSSL_DESERIALIZER_properties() returns the property definition associated
-with the given I<deserializer>.
-
-OSSL_DESERIALIZER_is_a() checks if I<deserializer> is an implementation
-of an algorithm that's identifiable with I<name>.
-
-OSSL_DESERIALIZER_number() returns the internal dynamic number assigned
-to the given I<deserializer>.
-
-OSSL_DESERIALIZER_names_do_all() traverses all names for the given
-I<deserializer>, and calls I<fn> with each name and I<data>.
-
-OSSL_DESERIALIZER_do_all_provided() traverses all serializer
-implementations by all activated providers in the library context
-I<libctx>, and for each of the implementations, calls I<fn> with the
-implementation method and I<data> as arguments.
-
-OSSL_DESERIALIZER_gettable_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
-
-OSSL_DESERIALIZER_get_params() attempts to get parameters specified
-with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
-implementation doesn't recognise should be ignored.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_fetch() returns a pointer to an OSSL_DESERIALIZER object,
-or NULL on error.
-
-OSSL_DESERIALIZER_up_ref() returns 1 on success, or 0 on error.
-
-OSSL_DESERIALIZER_free() doesn't return any value.
-
-OSSL_DESERIALIZER_provider() returns a pointer to a provider object, or
-NULL on error.
-
-OSSL_DESERIALIZER_properties() returns a pointer to a property
-definition string, or NULL on error.
-
-OSSL_DESERIALIZER_is_a() returns 1 if I<deserializer> was identifiable,
-otherwise 0.
-
-OSSL_DESERIALIZER_number() returns an integer.
-
-=head1 NOTES
-
-OSSL_DESERIALIZER_fetch() may be called implicitly by other fetching
-functions, using the same library context and properties.
-Any other API that uses keys will typically do this.
-
-=begin comment TODO(3.0) Add examples!
-
-=head1 EXAMPLES
-
-Text, because pod2xxx doesn't like empty sections
-
-=end comment
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER_CTX(3)>, L<OSSL_DESERIALIZER_from_bio(3)>,
-L<OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_DESERIALIZER_CTX.pod b/doc/man3/OSSL_DESERIALIZER_CTX.pod
deleted file mode 100644 (file)
index 413584f..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER_CTX,
-OSSL_DESERIALIZER_CTX_new,
-OSSL_DESERIALIZER_settable_ctx_params,
-OSSL_DESERIALIZER_CTX_set_params,
-OSSL_DESERIALIZER_CTX_free
-- Serializer context routines
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- typedef struct ossl_deserializer_ctx_st OSSL_DESERIALIZER_CTX;
-
- OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(OPENSSL_CTX *libctx);
- const OSSL_PARAM *OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
-                                      const OSSL_PARAM params[]);
- void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx);
-
-=head1 DESCRIPTION
-
-B<OSSL_DESERIALIZER_CTX> is a context with which B<OSSL_DESERIALIZER>
-operations are performed.  The context typically holds values, both
-internal and supplied by the application, which are useful for the
-implementations supplied by providers.
-
-OSSL_DESERIALIZER_CTX_new() creates a new empty B<OSSL_DESERIALIZER_CTX>.
-
-OSSL_DESERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
-
-OSSL_DESERIALIZER_CTX_set_params() attempts to set parameters specified
-with an L<OSSL_PARAM(3)> array I<params>.  These parameters are passed
-to all deserializers that have been added to the I<ctx> so far.
-Parameters that an implementation doesn't recognise should be ignored
-by it.
-
-OSSL_DESERIALIZER_CTX_free() frees the given context I<ctx>.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_CTX_new() returns a pointer to a
-B<OSSL_DESERIALIZER_CTX>, or NULL if the context structure couldn't be
-allocated.
-
-OSSL_DESERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array, or NULL if none is available.
-
-OSSL_DESERIALIZER_CTX_set_params() returns 1 if all recognised
-parameters were valid, or 0 if one of them was invalid or caused some
-other failure in the implementation.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER(3)>, L<OSSL_DESERIALIZER_from_bio(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
deleted file mode 100644 (file)
index c846665..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY,
-OSSL_DESERIALIZER_CTX_set_passphrase,
-OSSL_DESERIALIZER_CTX_set_pem_password_cb,
-OSSL_DESERIALIZER_CTX_set_passphrase_ui
-- Deserializer routines to deserialize EVP_PKEYs
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- OSSL_DESERIALIZER_CTX *
- OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
-                                       const char *input_type,
-                                       OPENSSL_CTX *libctx,
-                                       const char *propquery);
-
- int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
-                                          const unsigned char *kstr,
-                                          size_t klen);
- int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                               pem_password_cb *cb,
-                                               void *cbarg);
- int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
-                                             const UI_METHOD *ui_method,
-                                             void *ui_data);
-
-=head1 DESCRIPTION
-
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() is a utility function that
-creates a B<OSSL_DESERIALIZER_CTX>, finds all applicable deserializer
-implementations and sets them up, so all the caller has to do next is
-call functions like OSSL_DESERIALIZE_from_bio().
-
-Internally OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() searches for all
-available L<EVP_KEYMGMT(3)> implementations, and then builds a list of all
-potential deserializer implementations that may be able to process the
-serialized input into data suitable for B<EVP_PKEY>s.  All these
-implementations are implicitly fetched using I<libctx> and I<propquery>.
-
-The search of deserializer implementations can be limited with
-I<input_type>, which specifies a starting input type.  This is further
-explained in L<OSSL_DESERIALIZER_CTX_set_input_type(3)>.
-
-If no suitable deserializer was found, OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY()
-still creates a B<OSSL_DESERIALIZER_CTX>, but with no associated
-deserializer (L<OSSL_DESERIALIZER_CTX_num_deserializers(3)> returns
-zero).  This helps the caller distinguish between an error when
-creating the B<OSSL_DESERIALIZER_CTX>, and the lack the deserializer
-support and act accordingly.
-
-OSSL_DESERIALIZER_CTX_set_passphrase() gives the implementation a
-pass phrase to use when decrypting the serialized private key.
-Alternatively, a pass phrase callback may be specified with the
-following functions.
-
-OSSL_DESERIALIZER_CTX_set_pem_password_cb() and
-OSSL_DESERIALIZER_CTX_set_passphrase_ui() set up a callback method that
-the implementation can use to prompt for a pass phrase, giving the caller
-the choice of prefered pass phrase callback form.  These are called
-indirectly, through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
-
-The internal B<OSSL_PASSPHRASE_CALLBACK> function caches the pass phrase, to
-be re-used in all deserializations that are performed in the same
-deserialization run
-(for example, within one L<OSSL_DESERIALIZER_from_bio(3)> call).
-
-=for comment the name OSSL_DESERIALIZER_CTX_set_pem_password_cb() leaves
-open the future possibility of having a function where the caller can set a
-B<OSSL_PASSPHRASE_CALLBACK> method as another option.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() returns a pointer to a
-B<OSSL_DESERIALIZER_CTX>, or NULL if it couldn't be created.
-
-OSSL_DESERIALIZER_CTX_set_passphrase(),
-OSSL_DESERIALIZER_CTX_set_pem_password_cb() and
-OSSL_DESERIALIZER_CTX_set_passphrase_ui()
-all return 1 on success, or 0 on failure.
-
-=head1 NOTES
-
-Parts of the function names are made to match already existing OpenSSL
-names.
-
-B<EVP_PKEY> in OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() matches the type
-name, thus making for the naming pattern
-B<OSSL_DESERIALIZER_CTX_new_by_I<TYPE>>() when new types are handled.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER(3)>, L<OSSL_DESERIALIZER_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_DESERIALIZER_from_bio.pod b/doc/man3/OSSL_DESERIALIZER_from_bio.pod
deleted file mode 100644 (file)
index 1aa5489..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER_from_bio,
-OSSL_DESERIALIZER_from_fp,
-OSSL_DESERIALIZER_CTX_set_input_type,
-OSSL_DESERIALIZER_CTX_add_deserializer,
-OSSL_DESERIALIZER_CTX_add_extra,
-OSSL_DESERIALIZER_CTX_num_deserializers,
-OSSL_DESERIALIZER_INSTANCE,
-OSSL_DESERIALIZER_CONSTRUCT,
-OSSL_DESERIALIZER_CLEANUP,
-OSSL_DESERIALIZER_CTX_set_construct,
-OSSL_DESERIALIZER_CTX_set_construct_data,
-OSSL_DESERIALIZER_CTX_set_cleanup,
-OSSL_DESERIALIZER_CTX_get_construct,
-OSSL_DESERIALIZER_CTX_get_construct_data,
-OSSL_DESERIALIZER_CTX_get_cleanup,
-OSSL_DESERIALIZER_export,
-OSSL_DESERIALIZER_INSTANCE_deserializer,
-OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
-- Routines to perform a deserialization
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in);
- int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *fp);
-
- int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
-                                          const char *input_type);
- int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
-                                            OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx);
- int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx);
-
- typedef struct ossl_deserializer_instance_st OSSL_DESERIALIZER_INSTANCE;
- OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
-     (OSSL_DESERIALIZER_INSTANCE *deser_inst);
- void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
-     (OSSL_DESERIALIZER_INSTANCE *deser_inst);
-
- typedef int (OSSL_DESERIALIZER_CONSTRUCT)
-     (OSSL_DESERIALIZER_INSTANCE *deser_inst,
-      const OSSL_PARAM *params, void *construct_data);
- typedef void (OSSL_DESERIALIZER_CLEANUP)(void *construct_data);
-
- int OSSL_DESERIALIZER_CTX_set_construct
-     (OSSL_DESERIALIZER_CTX *ctx, OSSL_DESERIALIZER_CONSTRUCT *construct);
- int OSSL_DESERIALIZER_CTX_set_construct_data
-     (OSSL_DESERIALIZER_CTX *ctx, void *construct_data);
- int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx,
-                                       OSSL_DESERIALIZER_CLEANUP *cleanup);
- OSSL_DESERIALIZER_CONSTRUCT *
- OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx);
- void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx);
- OSSL_DESERIALIZER_CLEANUP *
- OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx);
-
- int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
-                              void *reference, size_t reference_sz,
-                              OSSL_CALLBACK *export_cb, void *export_cbarg);
-
-Feature availability macros:
-
-=over 4
-
-=item OSSL_DESERIALIZER_from_fp() is only available when B<OPENSSL_NO_STDIO>
-is undefined.
-
-=back
-
-=head1 DESCRIPTION
-
-The B<OSSL_DESERIALIZER_CTX> holds data about multiple deserializers, as
-needed to figure out what the input data is and to attempt to unpack it into
-one of several possible related results.  This also includes chaining
-deserializers, so the output from one can become the input for another.
-This allows having generic format deserializers such as PEM to DER, as well
-as more specialized deserializers like DER to RSA.
-
-The chains may be limited by specifying an input type, which is considered a
-starting point.
-This is both considered by OSSL_DESERIALIZER_CTX_add_extra(), which will
-stop adding on more deserializer implementations when it has already added
-those that take the specified input type, and OSSL_DESERIALIZER_from_bio(),
-which will only start the deserializing process with the deserializer
-implementations that take that input type.  For example, if the input type
-is set to C<DER>, a PEM to DER deserializer will be ignored.
-
-The input type can also be NULL, which means that the caller doesn't know
-what type of input they have.  In this case, OSSL_DESERIALIZER_from_bio()
-will simply try with one deserializer implementation after the other, and
-thereby discover what kind of input the caller gave it.
-
-For every deserialization done, even an intermediary one, a constructor
-provided by the caller is called to attempt to construct an appropriate type
-/ structure that the caller knows how to handle from the current
-deserialization result.
-The constructor is set with OSSL_DESERIALIZER_CTX_set_construct().
-
-B<OSSL_DESERIALIZER_INSTANCE> is an opaque structure that contains
-data about the deserializer that was just used, and that may be
-useful for the constructor.  There are some functions to extract data
-from this type, described further down.
-
-=head2 Functions
-
-OSSL_DESERIALIZER_from_bio() runs the deserialization process for the
-context I<ctx>, with the input coming from the B<BIO> I<in>.  Should
-it make a difference, it's recommended to have the BIO set in binary
-mode rather than text mode.
-
-OSSL_DESERIALIZER_from_fp() does the same thing as OSSL_DESERIALIZER_from_bio(),
-except that the input is coming from the B<FILE> I<fp>.
-
-OSSL_DESERIALIZER_CTX_add_deserializer() populates the B<OSSL_DESERIALIZER_CTX>
-I<ctx> with a deserializer, to be used to attempt to deserialize some
-serialized input.
-
-OSSL_DESERIALIZER_CTX_add_extra() finds deserializers that generate
-input for already added deserializers, and adds them as well.  This is
-used to build deserializer chains.
-
-OSSL_DESERIALIZER_CTX_set_input_type() sets the starting input type.  This
-limits the deserializer chains to be considered, as explained in the general
-description above.
-
-OSSL_DESERIALIZER_CTX_num_deserializers() gets the number of
-deserializers currently added to the context I<ctx>.
-
-OSSL_DESERIALIZER_CTX_set_construct() sets the constructor I<construct>.
-
-OSSL_DESERIALIZER_CTX_set_construct_data() sets the constructor data that is
-passed to the constructor every time it's called.
-
-OSSL_DESERIALIZER_CTX_set_cleanup() sets the constructor data I<cleanup>
-function.  This is called by L<OSSL_DESERIALIZER_CTX_free(3)>.
-
-OSSL_DESERIALIZER_CTX_get_construct(),
-OSSL_DESERIALIZER_CTX_get_construct_data() and
-OSSL_DESERIALIZER_CTX_get_cleanup()
-return the values that have been set by
-OSSL_DESERIALIZER_CTX_set_construct(),
-OSSL_DESERIALIZER_CTX_set_construct_data() and
-OSSL_DESERIALIZER_CTX_set_cleanup() respectively.
-
-OSSL_DESERIALIZER_export() is a fallback function for constructors that
-cannot use the data they get directly for diverse reasons.  It takes the same
-deserialize instance I<deser_inst> that the constructor got and an object
-I<reference>, unpacks the object which it refers to, and exports it by creating
-an L<OSSL_PARAM(3)> array that it then passes to I<export_cb>, along with
-I<export_arg>.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer() can be used to get the
-deserializer method from a deserializer instance I<deser_inst>.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer-ctx() can be used to get the
-deserializer method's provider context from a deserializer instance
-I<deser_inst>.
-
-=head2 Constructor
-
-A B<OSSL_DESERIALIZER_CONSTRUCT> gets the following arguments:
-
-=over 4
-
-=item I<deser_inst>
-
-The B<OSSL_DESERIALIZER_INSTANCE> for the deserializer from which
-the constructor gets its data.
-
-=item I<params>
-
-The data produced by the deserializer, further described below.
-
-=item I<construct_data>
-
-The pointer that was set with OSSL_DESERIALIZE_CTX_set_construct_data().
-
-=back
-
-The constructor is expected to return 1 when the data it receives can
-be constructed, otherwise 0.
-
-The globally known parameters that the constructor can get in I<params>
-are:
-
-=over 4
-
-=item "data-type" (B<OSSL_DESERIALIZER_PARAM_DATA_TYPE>) <UTF8 string>
-
-This is a detected content type that some deserializers may provide.
-For example, PEM input sometimes has a type specified in its header,
-and some deserializers may add that information as this parameter.
-This is an optional parameter, but may be useful for extra checks in
-the constructor.
-
-=item "data" (B<OSSL_DESERIALIZER_PARAM_DATA>) <octet string>
-
-The deserialized data itself, as an octet string.  This is produced by
-deserializers when it's possible to pass an object in this form.  Most
-often, this is simply meant to be passed to the next deserializer in a
-chain, but could be considered final data as well, at the discretion
-of the constructor.
-
-=item "reference" (B<OSSL_DESERIALIZER_PARAM_DATA>) <octet string>
-
-The deserialized data itself, as a reference to an object.  The
-reference itself is an octet string, and can be passed to other
-operations and functions within the same provider as the one that
-provides I<deser>.
-
-=back
-
-At least one of "data" or "reference" must be present, and it's
-possible that both can be.  A constructor should choose to use the
-"reference" parameter if possible, otherwise it should use the "data"
-parameter.
-
-If it's not possible to use the "reference" parameter, but that's
-still what a constructor wants to do, it is possible to use
-OSSL_DESERIALIZER_export() as a fallback.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_from_bio() and OSSL_DESERIALIZER_from_fp() return 1 on
-success, or 0 on failure.
-
-OSSL_DESERIALIZER_CTX_add_deserializer(),
-OSSL_DESERIALIZER_CTX_add_extra(),
-OSSL_DESERIALIZER_CTX_set_construct(),
-OSSL_DESERIALIZER_CTX_set_construct_data() and
-OSSL_DESERIALIZER_CTX_set_cleanup() return 1 on success, or 0 on
-failure.
-
-OSSL_DESERIALIZER_CTX_get_construct(),
-OSSL_DESERIALIZER_CTX_get_construct_data() and
-OSSL_DESERIALIZER_CTX_get_cleanup() return the current pointers to the
-cosntructor, the constructor data and the cleanup functions, respectively.
-
-OSSL_DESERIALIZER_CTX_num_deserializers() returns the current
-number of deserializers.  It returns 0 if I<ctx> is NULL.
-
-OSSL_DESERIALIZER_export() returns 1 on success, or 0 on failure.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer() returns an
-B<OSSL_DESERIALIZER> pointer on success, or NULL on failure.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer_ctx() returns a provider
-context pointer on success, or NULL on failure.>
-
-=begin comment TODO(3.0) Add examples!
-
-=head1 EXAMPLES
-
-Text, because pod2xxx doesn't like empty sections
-
-=end comment
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_ENCODER.pod b/doc/man3/OSSL_ENCODER.pod
new file mode 100644 (file)
index 0000000..d899831
--- /dev/null
@@ -0,0 +1,126 @@
+=pod
+
+=head1 NAME
+
+OSSL_ENCODER,
+OSSL_ENCODER_fetch,
+OSSL_ENCODER_up_ref,
+OSSL_ENCODER_free,
+OSSL_ENCODER_provider,
+OSSL_ENCODER_properties,
+OSSL_ENCODER_is_a,
+OSSL_ENCODER_number,
+OSSL_ENCODER_do_all_provided,
+OSSL_ENCODER_names_do_all
+- Encoder method routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/encoder.h>
+
+ typedef struct ossl_encoder_st OSSL_ENCODER;
+
+ OSSL_ENCODER *OSSL_ENCODER_fetch(OPENSSL_CTX *ctx, const char *name,
+                                  const char *properties);
+ int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder);
+ void OSSL_ENCODER_free(OSSL_ENCODER *encoder);
+ const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder);
+ const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder);
+ int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name);
+ int OSSL_ENCODER_number(const OSSL_ENCODER *encoder);
+ void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
+                                   void (*fn)(OSSL_ENCODER *encoder, void *arg),
+                                   void *arg);
+ void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
+                                void (*fn)(const char *name, void *data),
+                                void *data);
+
+=head1 DESCRIPTION
+
+=for comment Future development should also talk about decoding
+
+B<OSSL_ENCODER> is a method for encoders, which know how to
+encode an object of some kind to a encoded form, such as PEM,
+DER, or even human readable text.
+
+OSSL_ENCODER_fetch() looks for an algorithm within the provider that
+has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
+name given by I<name> and the properties given by I<properties>.
+The I<name> determines what type of object the fetched encoder
+method is expected to be able to encode, and the properties are
+used to determine the expected output type.
+For known properties and the values they may have, please have a look
+in L<provider-encoder(7)/Names and properties>.
+
+OSSL_ENCODER_up_ref() increments the reference count for the given
+I<encoder>.
+
+OSSL_ENCODER_free() decrements the reference count for the given
+I<encoder>, and when the count reaches zero, frees it.
+
+OSSL_ENCODER_provider() returns the provider of the given
+I<encoder>.
+
+OSSL_ENCODER_provider() returns the property definition associated
+with the given I<encoder>.
+
+OSSL_ENCODER_is_a() checks if I<encoder> is an implementation of an
+algorithm that's identifiable with I<name>.
+
+OSSL_ENCODER_number() returns the internal dynamic number assigned to
+the given I<encoder>.
+
+OSSL_ENCODER_names_do_all() traverses all names for the given
+I<encoder>, and calls I<fn> with each name and I<data>.
+
+OSSL_ENCODER_do_all_provided() traverses all encoder
+implementations by all activated providers in the library context
+I<libctx>, and for each of the implementations, calls I<fn> with the
+implementation method and I<data> as arguments.
+
+=head1 NOTES
+
+OSSL_ENCODER_fetch() may be called implicitly by other fetching
+functions, using the same library context and properties.
+Any other API that uses keys will typically do this.
+
+=head1 RETURN VALUES
+
+OSSL_ENCODER_fetch() returns a pointer to the key management
+implementation represented by an OSSL_ENCODER object, or NULL on
+error.
+
+OSSL_ENCODER_up_ref() returns 1 on success, or 0 on error.
+
+OSSL_ENCODER_free() doesn't return any value.
+
+OSSL_ENCODER_provider() returns a pointer to a provider object, or
+NULL on error.
+
+OSSL_ENCODER_properties() returns a pointer to a property
+definition string, or NULL on error.
+
+OSSL_ENCODER_is_a() returns 1 of I<encoder> was identifiable,
+otherwise 0.
+
+OSSL_ENCODER_number() returns an integer.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_ENCODER_CTX(3)>, L<OSSL_ENCODER_to_bio(3)>,
+L<OSSL_ENCODER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_ENCODER_CTX.pod b/doc/man3/OSSL_ENCODER_CTX.pod
new file mode 100644 (file)
index 0000000..bf339c6
--- /dev/null
@@ -0,0 +1,93 @@
+=pod
+
+=head1 NAME
+
+OSSL_ENCODER_CTX,
+OSSL_ENCODER_CTX_new,
+OSSL_ENCODER_CTX_get_encoder,
+OSSL_ENCODER_settable_ctx_params,
+OSSL_ENCODER_CTX_set_params,
+OSSL_ENCODER_CTX_free
+- Encoder context routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/encoder.h>
+
+ typedef struct ossl_encoder_ctx_st OSSL_ENCODER_CTX;
+
+ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(OSSL_ENCODER *encoder);
+ const OSSL_ENCODER *OSSL_ENCODER_CTX_get_encoder(OSSL_ENCODER_CTX *ctx);
+ const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder);
+ int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
+                                 const OSSL_PARAM params[]);
+ void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx);
+
+=head1 DESCRIPTION
+
+B<OSSL_ENCODER_CTX> is a context with which B<OSSL_ENCODER>
+operations are performed.  The context typically holds values, both
+internal and supplied by the application, which are useful for the
+implementations supplied by providers.
+
+OSSL_ENCODER_CTX_new() creates a B<OSSL_ENCODER_CTX> associated
+with the encoder I<encoder>.  NULL is a valid I<encoder>, the context will
+be created anyway, it's just not very useful.  This is intentional, to
+distinguish between errors in allocating the context or assigning it
+values on one hand, and the lack of encoder support on the other.
+
+=begin comment
+
+The above distinction makes it possible for other routines to sense if
+they need to report an error or fall back on other methods to
+encode.
+
+=end comment
+
+OSSL_ENCODER_CTX_get_encoder() gets the encoder method
+currently associated with the context I<ctx>.
+
+OSSL_ENCODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_ENCODER_CTX_set_params() attempts to set parameters specified
+with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
+implementation doesn't recognise should be ignored.
+
+OSSL_ENCODER_CTX_free() frees the given context I<ctx>.
+
+=head1 RETURN VALUES
+
+OSSL_ENCODER_CTX_new() returns a pointer to a
+B<OSSL_ENCODER_CTX>, or NULL if the context structure couldn't be
+allocated.
+
+OSSL_ENCODER_CTX_get_encoder() returns a pointer to the
+encoder method associated with I<ctx>.  NULL is a valid return
+value and signifies that there is no associated encoder method.
+
+OSSL_ENCODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array, or NULL if none is available.
+
+OSSL_ENCODER_CTX_set_params() returns 1 if all recognised
+parameters were valid, or 0 if one of them was invalid or caused some
+other failure in the implementation.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_ENCODER(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod
new file mode 100644 (file)
index 0000000..2aa103f
--- /dev/null
@@ -0,0 +1,144 @@
+=pod
+
+=head1 NAME
+
+OSSL_ENCODER_CTX_new_by_EVP_PKEY,
+OSSL_ENCODER_CTX_set_cipher,
+OSSL_ENCODER_CTX_set_passphrase,
+OSSL_ENCODER_CTX_set_passphrase_cb,
+OSSL_ENCODER_CTX_set_passphrase_ui,
+OSSL_ENCODER_PUBKEY_TO_PEM_PQ,
+OSSL_ENCODER_PrivateKey_TO_PEM_PQ,
+OSSL_ENCODER_Parameters_TO_PEM_PQ,
+OSSL_ENCODER_PUBKEY_TO_DER_PQ,
+OSSL_ENCODER_PrivateKey_TO_DER_PQ,
+OSSL_ENCODER_Parameters_TO_DER_PQ,
+OSSL_ENCODER_PUBKEY_TO_TEXT_PQ,
+OSSL_ENCODER_PrivateKey_TO_TEXT_PQ,
+OSSL_ENCODER_Parameters_TO_TEXT_PQ
+- Encoder routines to encode EVP_PKEYs
+
+=head1 SYNOPSIS
+
+ #include <openssl/encoder.h>
+
+ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
+                                                    const char *propquery);
+
+ int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx,
+                                 const char *cipher_name,
+                                 const char *propquery);
+ int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
+                                     const unsigned char *kstr,
+                                     size_t klen);
+ int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx,
+                                        pem_password_cb *cb, void *cbarg);
+ int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
+                                        const UI_METHOD *ui_method,
+                                        void *ui_data);
+
+ #define OSSL_ENCODER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
+ #define OSSL_ENCODER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
+ #define OSSL_ENCODER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
+
+ #define OSSL_ENCODER_PUBKEY_TO_DER_PQ "format=der,type=public"
+ #define OSSL_ENCODER_PrivateKey_TO_DER_PQ "format=der,type=private"
+ #define OSSL_ENCODER_Parameters_TO_DER_PQ "format=der,type=parameters"
+
+ #define OSSL_ENCODER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
+ #define OSSL_ENCODER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
+ #define OSSL_ENCODER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
+
+=head1 DESCRIPTION
+
+OSSL_ENCODER_CTX_new_by_EVP_PKEY() creates a B<OSSL_ENCODER_CTX>
+with a suitable attached output routine for B<EVP_PKEY>s.  It will
+search for a encoder implementation that matches the algorithm of
+the B<EVP_PKEY> and the property query given with I<propquery>.  It
+will prefer to find a encoder from the same provider as the key
+data of the B<EVP_PKEY> itself, but failing that, it will choose the
+first encoder that supplies a generic encoding function.
+
+If no suitable encoder was found, OSSL_ENCODER_CTX_new_by_EVP_PKEY()
+still creates a B<OSSL_ENCODER_CTX>, but with no associated
+encoder (L<OSSL_ENCODER_CTX_get_encoder(3)> returns NULL).
+This helps the caller distinguish between an error when creating
+the B<OSSL_ENCODER_CTX>, and the lack the encoder support and
+act accordingly.
+
+OSSL_ENCODER_CTX_set_cipher() tells the implementation what cipher
+should be used to encrypt encoded keys.  The cipher is given by
+name I<cipher_name>.  The interpretation of that I<cipher_name> is
+implementation dependent.  The implementation may implement the digest
+directly itself or by other implementations, or it may choose to fetch
+it.  If the implementation supports fetching the cipher, then it may
+use I<propquery> as properties to be queried for when fetching.
+I<cipher_name> may also be NULL, which will result in unencrypted
+encoding.
+
+OSSL_ENCODER_CTX_set_passphrase() gives the implementation a
+pass phrase to use when encrypting the encoded private key.
+Alternatively, a pass phrase callback may be specified with the
+following functions.
+
+OSSL_ENCODER_CTX_set_passphrase_cb() and
+OSSL_ENCODER_CTX_set_passphrase_ui() sets up a callback method that
+the implementation can use to prompt for a pass phrase.
+
+=for comment Note that the callback method is called indirectly,
+through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
+
+The macros B<OSSL_ENCODER_PUBKEY_TO_PEM_PQ>,
+B<OSSL_ENCODER_PrivateKey_TO_PEM_PQ>,
+B<OSSL_ENCODER_Parameters_TO_PEM_PQ>,
+B<OSSL_ENCODER_PUBKEY_TO_DER_PQ>,
+B<OSSL_ENCODER_PrivateKey_TO_DER_PQ>,
+B<OSSL_ENCODER_Parameters_TO_DER_PQ>,
+B<OSSL_ENCODER_PUBKEY_TO_TEXT_PQ>,
+B<OSSL_ENCODER_PrivateKey_TO_TEXT_PQ>,
+B<OSSL_ENCODER_Parameters_TO_TEXT_PQ> are convenience macros with
+property queries to encode the B<EVP_PKEY> as a public key, private
+key or parameters to B<PEM>, to B<DER>, or to text.
+
+=head1 RETURN VALUES
+
+OSSL_ENCODER_CTX_new_by_EVP_PKEY() returns a pointer to a
+B<OSSL_ENCODER_CTX>, or NULL if it couldn't be created.
+
+OSSL_ENCODER_CTX_set_cipher(),
+OSSL_ENCODER_CTX_set_passphrase(),
+OSSL_ENCODER_CTX_set_passphrase_cb(), and
+OSSL_ENCODER_CTX_set_passphrase_ui() all return 1 on success, or 0
+on failure.
+
+=head1 NOTES
+
+Parts of the function and macro names are made to match already
+existing OpenSSL names.
+
+B<EVP_PKEY> in OSSL_ENCODER_CTX_new_by_EVP_PKEY() matches the type
+name, thus making for the naming pattern
+B<OSSL_ENCODER_CTX_new_by_I<TYPE>>() when new types are handled.
+
+B<PUBKEY>, B<PrivateKey> and B<Parameters> in the macro names match
+the B<I<TYPE>> part of B<PEM_write_bio_I<TYPE>> functions as well
+as B<i2d_I<TYPE>_bio> functions.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_ENCODER(3)>, L<OSSL_ENCODER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
similarity index 58%
rename from doc/man3/OSSL_SERIALIZER_to_bio.pod
rename to doc/man3/OSSL_ENCODER_to_bio.pod
index 3ed68a1..ee9998b 100644 (file)
@@ -2,46 +2,46 @@
 
 =head1 NAME
 
-OSSL_SERIALIZER_to_bio,
-OSSL_SERIALIZER_to_fp
-- Serializer file output routines
+OSSL_ENCODER_to_bio,
+OSSL_ENCODER_to_fp
+- Encoder file output routines
 
 =head1 SYNOPSIS
 
- #include <openssl/serializer.h>
+ #include <openssl/encoder.h>
 
- int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out);
- int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp);
+ int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out);
+ int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp);
 
 Feature availability macros:
 
 =over 4
 
-=item OSSL_SERIALIZER_to_fp() is only available when B<OPENSSL_NO_STDIO>
+=item OSSL_ENCODER_to_fp() is only available when B<OPENSSL_NO_STDIO>
 is undefined.
 
 =back
 
 =head1 DESCRIPTION
 
-OSSL_SERIALIZER_to_bio() runs the serialization process for the
+OSSL_ENCODER_to_bio() runs the encoding process for the
 context I<ctx>, with the output going to the B<BIO> I<out>.  The
 application is required to set up the B<BIO> properly, for example to
 have it in text or binary mode if that's appropriate.
 
-=for comment Know your serializer!
+=for comment Know your encoder!
 
-OSSL_SERIALIZER_to_fp() does the same thing as OSSL_SERIALIZER_to_bio(),
+OSSL_ENCODER_to_fp() does the same thing as OSSL_ENCODER_to_bio(),
 except that the output is going to the B<FILE> I<fp>.
 
 =head1 RETURN VALUES
 
-OSSL_SERIALIZER_to_bio() and OSSL_SERIALIZER_to_fp() return 1 on
+OSSL_ENCODER_to_bio() and OSSL_ENCODER_to_fp() return 1 on
 success, or 0 on failure.
 
 =head1 SEE ALSO
 
-L<provider(7)>, L<OSSL_SERIALIZER_CTX(3)>
+L<provider(7)>, L<OSSL_ENCODER_CTX(3)>
 
 =head1 HISTORY
 
diff --git a/doc/man3/OSSL_SERIALIZER.pod b/doc/man3/OSSL_SERIALIZER.pod
deleted file mode 100644 (file)
index 05b889b..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_SERIALIZER,
-OSSL_SERIALIZER_fetch,
-OSSL_SERIALIZER_up_ref,
-OSSL_SERIALIZER_free,
-OSSL_SERIALIZER_provider,
-OSSL_SERIALIZER_properties,
-OSSL_SERIALIZER_is_a,
-OSSL_SERIALIZER_number,
-OSSL_SERIALIZER_do_all_provided,
-OSSL_SERIALIZER_names_do_all
-- Serializer method routines
-
-=head1 SYNOPSIS
-
- #include <openssl/serializer.h>
-
- typedef struct ossl_serializer_st OSSL_SERIALIZER;
-
- OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *ctx, const char *name,
-                                        const char *properties);
- int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *serializer);
- void OSSL_SERIALIZER_free(OSSL_SERIALIZER *serializer);
- const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER
-                                               *serializer);
- const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser);
- int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *serializer,
-                          const char *name);
- int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *serializer);
- void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                      void (*fn)(OSSL_SERIALIZER *serializer,
-                                                 void *arg),
-                                      void *arg);
- void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *serializer,
-                                   void (*fn)(const char *name, void *data),
-                                   void *data);
-
-=head1 DESCRIPTION
-
-=for comment Future development should also talk about deserialization
-
-B<OSSL_SERIALIZER> is a method for serializers, which know how to
-serialize an object of some kind to a serialized form, such as PEM,
-DER, or even human readable text.
-
-OSSL_SERIALIZER_fetch() looks for an algorithm within the provider that
-has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
-name given by I<name> and the properties given by I<properties>.
-The I<name> determines what type of object the fetched serializer
-method is expected to be able to serialize, and the properties are
-used to determine the expected output type.
-For known properties and the values they may have, please have a look
-in L<provider-serializer(7)/Names and properties>.
-
-OSSL_SERIALIZER_up_ref() increments the reference count for the given
-I<serializer>.
-
-OSSL_SERIALIZER_free() decrements the reference count for the given
-I<serializer>, and when the count reaches zero, frees it.
-
-OSSL_SERIALIZER_provider() returns the provider of the given
-I<serializer>.
-
-OSSL_SERIALIZER_provider() returns the property definition associated
-with the given I<serializer>.
-
-OSSL_SERIALIZER_is_a() checks if I<serializer> is an implementation of an
-algorithm that's identifiable with I<name>.
-
-OSSL_SERIALIZER_number() returns the internal dynamic number assigned to
-the given I<serializer>.
-
-OSSL_SERIALIZER_names_do_all() traverses all names for the given
-I<serializer>, and calls I<fn> with each name and I<data>.
-
-OSSL_SERIALIZER_do_all_provided() traverses all serializer
-implementations by all activated providers in the library context
-I<libctx>, and for each of the implementations, calls I<fn> with the
-implementation method and I<data> as arguments.
-
-=head1 NOTES
-
-OSSL_SERIALIZER_fetch() may be called implicitly by other fetching
-functions, using the same library context and properties.
-Any other API that uses keys will typically do this.
-
-=head1 RETURN VALUES
-
-OSSL_SERIALIZER_fetch() returns a pointer to the key management
-implementation represented by an OSSL_SERIALIZER object, or NULL on
-error.
-
-OSSL_SERIALIZER_up_ref() returns 1 on success, or 0 on error.
-
-OSSL_SERIALIZER_free() doesn't return any value.
-
-OSSL_SERIALIZER_provider() returns a pointer to a provider object, or
-NULL on error.
-
-OSSL_SERIALIZER_properties() returns a pointer to a property
-definition string, or NULL on error.
-
-OSSL_SERIALIZER_is_a() returns 1 of I<serializer> was identifiable,
-otherwise 0.
-
-OSSL_SERIALIZER_number() returns an integer.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_SERIALIZER_CTX(3)>, L<OSSL_SERIALIZER_to_bio(3)>,
-L<OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_SERIALIZER_CTX.pod b/doc/man3/OSSL_SERIALIZER_CTX.pod
deleted file mode 100644 (file)
index d446b84..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_SERIALIZER_CTX,
-OSSL_SERIALIZER_CTX_new,
-OSSL_SERIALIZER_CTX_get_serializer,
-OSSL_SERIALIZER_settable_ctx_params,
-OSSL_SERIALIZER_CTX_set_params,
-OSSL_SERIALIZER_CTX_free
-- Serializer context routines
-
-=head1 SYNOPSIS
-
- #include <openssl/serializer.h>
-
- typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX;
-
- OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser);
- const OSSL_SERIALIZER *
- OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx);
- const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser);
- int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx,
-                                    const OSSL_PARAM params[]);
- void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx);
-
-=head1 DESCRIPTION
-
-B<OSSL_SERIALIZER_CTX> is a context with which B<OSSL_SERIALIZER>
-operations are performed.  The context typically holds values, both
-internal and supplied by the application, which are useful for the
-implementations supplied by providers.
-
-OSSL_SERIALIZER_CTX_new() creates a B<OSSL_SERIALIZER_CTX> associated
-with the serializer I<ser>.  NULL is a valid I<ser>, the context will
-be created anyway, it's just not very useful.  This is intentional, to
-distinguish between errors in allocating the context or assigning it
-values on one hand, and the lack of serializer support on the other.
-
-=begin comment
-
-The above distinction makes it possible for other routines to sense if
-they need to report an error or fall back on other methods to
-serialize.
-
-=end comment
-
-OSSL_SERIALIZER_CTX_get_serializer() gets the serializer method
-currently associated with the context I<ctx>.
-
-OSSL_SERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
-
-OSSL_SERIALIZER_CTX_set_params() attempts to set parameters specified
-with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
-implementation doesn't recognise should be ignored.
-
-OSSL_SERIALIZER_CTX_free() frees the given context I<ctx>.
-
-=head1 RETURN VALUES
-
-OSSL_SERIALIZER_CTX_new() returns a pointer to a
-B<OSSL_SERIALIZER_CTX>, or NULL if the context structure couldn't be
-allocated.
-
-OSSL_SERIALIZER_CTX_get_serializer() returns a pointer to the
-serializer method associated with I<ctx>.  NULL is a valid return
-value and signifies that there is no associated serializer method.
-
-OSSL_SERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array, or NULL if none is available.
-
-OSSL_SERIALIZER_CTX_set_params() returns 1 if all recognised
-parameters were valid, or 0 if one of them was invalid or caused some
-other failure in the implementation.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_SERIALIZER(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
-
-Licensed under the Apache License 2.0 (the "License").  You may not use
-this file except in compliance with the License.  You can obtain a copy
-in the file LICENSE in the source distribution or at
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod
deleted file mode 100644 (file)
index 5797ab1..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY,
-OSSL_SERIALIZER_CTX_set_cipher,
-OSSL_SERIALIZER_CTX_set_passphrase,
-OSSL_SERIALIZER_CTX_set_passphrase_cb,
-OSSL_SERIALIZER_CTX_set_passphrase_ui,
-OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ,
-OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ,
-OSSL_SERIALIZER_Parameters_TO_PEM_PQ,
-OSSL_SERIALIZER_PUBKEY_TO_DER_PQ,
-OSSL_SERIALIZER_PrivateKey_TO_DER_PQ,
-OSSL_SERIALIZER_Parameters_TO_DER_PQ,
-OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
-OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
-OSSL_SERIALIZER_Parameters_TO_TEXT_PQ
-- Serializer routines to serialize EVP_PKEYs
-
-=head1 SYNOPSIS
-
- #include <openssl/serializer.h>
-
- OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
-                                                          const char *propquery);
-
- int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx,
-                                    const char *cipher_name,
-                                    const char *propquery);
- int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx,
-                                        const unsigned char *kstr,
-                                        size_t klen);
- int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx,
-                                           pem_password_cb *cb, void *cbarg);
- int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx,
-                                           const UI_METHOD *ui_method,
-                                           void *ui_data);
-
- #define OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
- #define OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
-
- #define OSSL_SERIALIZER_PUBKEY_TO_DER_PQ "format=der,type=public"
- #define OSSL_SERIALIZER_PrivateKey_TO_DER_PQ "format=der,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_DER_PQ "format=der,type=parameters"
-
- #define OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
- #define OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
-
-=head1 DESCRIPTION
-
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() creates a B<OSSL_SERIALIZER_CTX>
-with a suitable attached output routine for B<EVP_PKEY>s.  It will
-search for a serializer implementation that matches the algorithm of
-the B<EVP_PKEY> and the property query given with I<propquery>.  It
-will prefer to find a serializer from the same provider as the key
-data of the B<EVP_PKEY> itself, but failing that, it will choose the
-first serializer that supplies a generic serializing function.
-
-If no suitable serializer was found, OSSL_SERIALIZER_CTX_new_by_EVP_PKEY()
-still creates a B<OSSL_SERIALIZER_CTX>, but with no associated
-serializer (L<OSSL_SERIALIZER_CTX_get_serializer(3)> returns NULL).
-This helps the caller distinguish between an error when creating
-the B<OSSL_SERIALIZER_CTX>, and the lack the serializer support and
-act accordingly.
-
-OSSL_SERIALIZER_CTX_set_cipher() tells the implementation what cipher
-should be used to encrypt serialized keys.  The cipher is given by
-name I<cipher_name>.  The interpretation of that I<cipher_name> is
-implementation dependent.  The implementation may implement the digest
-directly itself or by other implementations, or it may choose to fetch
-it.  If the implementation supports fetching the cipher, then it may
-use I<propquery> as properties to be queried for when fetching.
-I<cipher_name> may also be NULL, which will result in unencrypted
-serialization.
-
-OSSL_SERIALIZER_CTX_set_passphrase() gives the implementation a
-pass phrase to use when encrypting the serialized private key.
-Alternatively, a pass phrase callback may be specified with the
-following functions.
-
-OSSL_SERIALIZER_CTX_set_passphrase_cb() and
-OSSL_SERIALIZER_CTX_set_passphrase_ui() sets up a callback method that
-the implementation can use to prompt for a pass phrase.
-
-=for comment Note that the callback method is called indirectly,
-through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
-
-The macros B<OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ>,
-B<OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ>,
-B<OSSL_SERIALIZER_Parameters_TO_PEM_PQ>,
-B<OSSL_SERIALIZER_PUBKEY_TO_DER_PQ>,
-B<OSSL_SERIALIZER_PrivateKey_TO_DER_PQ>,
-B<OSSL_SERIALIZER_Parameters_TO_DER_PQ>,
-B<OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ>,
-B<OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ>,
-B<OSSL_SERIALIZER_Parameters_TO_TEXT_PQ> are convenience macros with
-property queries to serialize the B<EVP_PKEY> as a public key, private
-key or parameters to B<PEM>, to B<DER>, or to text.
-
-=head1 RETURN VALUES
-
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() returns a pointer to a
-B<OSSL_SERIALIZER_CTX>, or NULL if it couldn't be created.
-
-OSSL_SERIALIZER_CTX_set_cipher(),
-OSSL_SERIALIZER_CTX_set_passphrase(),
-OSSL_SERIALIZER_CTX_set_passphrase_cb(), and
-OSSL_SERIALIZER_CTX_set_passphrase_ui() all return 1 on success, or 0
-on failure.
-
-=head1 NOTES
-
-Parts of the function and macro names are made to match already
-existing OpenSSL names.
-
-B<EVP_PKEY> in OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() matches the type
-name, thus making for the naming pattern
-B<OSSL_SERIALIZER_CTX_new_by_I<TYPE>>() when new types are handled.
-
-B<PUBKEY>, B<PrivateKey> and B<Parameters> in the macro names match
-the B<I<TYPE>> part of B<PEM_write_bio_I<TYPE>> functions as well
-as B<i2d_I<TYPE>_bio> functions.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_SERIALIZER(3)>, L<OSSL_SERIALIZER_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
index dd4d21f..fc9c191 100644 (file)
@@ -35,7 +35,7 @@ make sure to get implementations of this provider and none other.
 The "fips=yes" property can be use to make sure only FIPS approved
 implementations are used for crypto operations.  This may also include
 other non-crypto support operations that are not in the fips provider,
-such as asymmetric key serializers,
+such as asymmetric key encoders,
 see L<OSSL_PROVIDER-default(7)/Asymmetric Key Management>.
 
 =head1 OPERATIONS AND ALGORITHMS
index 5896c5a..06b608b 100644 (file)
@@ -6,7 +6,7 @@ OSSL_PROVIDER-base - OpenSSL base provider
 
 =head1 DESCRIPTION
 
-The OpenSSL base provider supplies the serialization for OpenSSL's
+The OpenSSL base provider supplies the encoding for OpenSSL's
 asymmetric cryptography.
 
 =head2 Properties
@@ -36,7 +36,7 @@ implementations of this provider and none other.
 =back
 
 These may be used in a property query string with fetching functions to select
-which data are to be serialized.  Either the private key material, the public
+which data are to be encoded.  Either the private key material, the public
 key material or the domain parameters can be selected.
 
 =over 4
@@ -50,32 +50,32 @@ key material or the domain parameters can be selected.
 =back
 
 These may be used in a property query string with fetching functions to select
-the serialization output format.  Either the DER, PEM and plaintext are
+the encoding output format.  Either the DER, PEM and plaintext are
 currently permitted.
 
 =head1 OPERATIONS AND ALGORITHMS
 
 The OpenSSL base provider supports these operations and algorithms:
 
-=head2 Asymmetric Key Serializer
+=head2 Asymmetric Key Encoder
 
-In addition to "provider=base", some of these serializers define the
+In addition to "provider=base", some of these encoders define the
 property "fips=yes", to allow them to be used together with the FIPS
 provider.
 
 =over 4
 
-=item RSA, see L<OSSL_SERIALIZER-RSA(7)>
+=item RSA, see L<OSSL_ENCODER-RSA(7)>
 
-=item DH, see L<OSSL_SERIALIZER-DH(7)>
+=item DH, see L<OSSL_ENCODER-DH(7)>
 
-=item DSA, see L<OSSL_SERIALIZER-DSA(7)>
+=item DSA, see L<OSSL_ENCODER-DSA(7)>
 
-=item EC, see L<OSSL_SERIALIZER-EC(7)>
+=item EC, see L<OSSL_ENCODER-EC(7)>
 
-=item X25519, see L<OSSL_SERIALIZER-X25519(7)>
+=item X25519, see L<OSSL_ENCODER-X25519(7)>
 
-=item X448, see L<OSSL_SERIALIZER-X448(7)>
+=item X448, see L<OSSL_ENCODER-X448(7)>
 
 =back
 
index f82f8d8..0b477b5 100644 (file)
@@ -192,25 +192,25 @@ The OpenSSL default provider supports these operations and algorithms:
 
 =back
 
-=head2 Asymmetric Key Serializer
+=head2 Asymmetric Key Encoder
 
-The default provider also includes all of the serialization algorithms
+The default provider also includes all of the encoding algorithms
 present in the base provider.  Some of these have the property "fips=yes",
 to allow them to be used together with the FIPS provider.
 
 =over 4
 
-=item RSA, see L<OSSL_SERIALIZER-RSA(7)>
+=item RSA, see L<OSSL_ENCODER-RSA(7)>
 
-=item DH, see L<OSSL_SERIALIZER-DH(7)>
+=item DH, see L<OSSL_ENCODER-DH(7)>
 
-=item DSA, see L<OSSL_SERIALIZER-DSA(7)>
+=item DSA, see L<OSSL_ENCODER-DSA(7)>
 
-=item EC, see L<OSSL_SERIALIZER-EC(7)>
+=item EC, see L<OSSL_ENCODER-EC(7)>
 
-=item X25519, see L<OSSL_SERIALIZER-X25519(7)>
+=item X25519, see L<OSSL_ENCODER-X25519(7)>
 
-=item X448, see L<OSSL_SERIALIZER-X448(7)>
+=item X448, see L<OSSL_ENCODER-X448(7)>
 
 =back
 
similarity index 56%
rename from doc/man7/provider-serializer.pod
rename to doc/man7/provider-encoder.pod
index 0c16628..99787e7 100644 (file)
@@ -2,16 +2,10 @@
 
 =head1 NAME
 
-provider-serializer - The SERIALIZER library E<lt>-E<gt> provider functions
+provider-encoder - The ENCODER library E<lt>-E<gt> provider functions
 
 =head1 SYNOPSIS
 
-=begin comment
-
-Future development will also include deserializing functions.
-
-=end comment
-
  #include <openssl/core_dispatch.h>
 
  /*
@@ -20,39 +14,42 @@ Future development will also include deserializing functions.
   * pointers in OSSL_DISPATCH arrays.
   */
 
- /* Functions to construct / destruct / manipulate the serializer context */
- void *OSSL_FUNC_serializer_newctx(void *provctx);
- void OSSL_FUNC_serializer_freectx(void *ctx);
- int OSSL_FUNC_serializer_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
- const OSSL_PARAM *OSSL_FUNC_serializer_settable_ctx_params(void *provctx)
+ /* Functions to construct / destruct / manipulate the encoder context */
+ void *OSSL_FUNC_encoder_newctx(void *provctx);
+ void OSSL_FUNC_encoder_freectx(void *ctx);
+ int OSSL_FUNC_encoder_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OSSL_FUNC_encoder_settable_ctx_params(void *provctx)
 
- /* Functions to serialize object data */
- int OSSL_FUNC_serializer_serialize_data(void *ctx, const OSSL_PARAM *data,
+ /* Functions to encode object data */
+ int OSSL_FUNC_encoder_encode_data(void *ctx, const OSSL_PARAM *data,
                                          OSSL_CORE_BIO *out,
                                          OSSL_PASSPHRASE_CALLBACK *cb,
                                          void *cbarg);
- int OSSL_FUNC_serializer_serialize_object(void *ctx, void *obj, OSSL_CORE_BIO *out,
+ int OSSL_FUNC_encoder_encode_object(void *ctx, void *obj, OSSL_CORE_BIO *out,
                                            OSSL_PASSPHRASE_CALLBACK *cb,
                                            void *cbarg);
 
 =head1 DESCRIPTION
 
-The SERIALIZER is a generic method to serialize any set of object data
+I<We use the wide term "encode" in this manual.  This includes but is
+not limited to serialization.>
+
+The ENCODER is a generic method to encode any set of object data
 in L<OSSL_PARAM(3)> array form, or any provider side object into
-serialized form, and write it to the given OSSL_CORE_BIO.  If the caller wants
-to get the serialized stream to memory, it should provide a
+encoded form, and write it to the given OSSL_CORE_BIO.  If the caller wants
+to get the encoded stream to memory, it should provide a
 L<BIO_s_membuf(3)>.
 
-The serializer doesn't need to know more about the B<OSSL_CORE_BIO> pointer than
+The encoder doesn't need to know more about the B<OSSL_CORE_BIO> pointer than
 being able to pass it to the appropriate BIO upcalls (see
 L<provider-base(7)/Core functions>).
 
-The serialization using the L<OSSL_PARAM(3)> array form allows a
-serializer to be used for data that's been exported from another
+The encoding using the L<OSSL_PARAM(3)> array form allows a
+encoder to be used for data that's been exported from another
 provider, and thereby allow them to exist independently of each
 other.
 
-The serialization using a provider side object can only be safely used
+The encoding using a provider side object can only be safely used
 with provider data coming from the same provider, for example keys
 with the L<KEYMGMT|provider-keymgmt(7)> provider.
 
@@ -66,34 +63,34 @@ All these "functions" have a corresponding function type definition
 named B<OSSL_{name}_fn>, and a helper function to retrieve the
 function pointer from a B<OSSL_DISPATCH> element named
 B<OSSL_FUNC_{name}>.
-For example, the "function" OSSL_FUNC_serializer_serialize_data() has these:
+For example, the "function" OSSL_FUNC_encoder_encode_data() has these:
 
  typedef int
-     (OSSL_FUNC_serializer_serialize_data_fn)(void *provctx,
+     (OSSL_FUNC_encoder_encode_data_fn)(void *provctx,
                                             const OSSL_PARAM params[],
                                             OSSL_CORE_BIO *out);
- static ossl_inline OSSL_FUNC_serializer_serialize_data_fn
-     OSSL_FUNC_serializer_serialize_data(const OSSL_DISPATCH *opf);
+ static ossl_inline OSSL_FUNC_encoder_encode_data_fn
+     OSSL_FUNC_encoder_encode_data(const OSSL_DISPATCH *opf);
 
 B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
 macros in L<openssl-core_dispatch.h(7)>, as follows:
 
- OSSL_FUNC_serializer_newctx              OSSL_FUNC_SERIALIZER_NEWCTX
- OSSL_FUNC_serializer_freectx             OSSL_FUNC_SERIALIZER_FREECTX
- OSSL_FUNC_serializer_set_ctx_params      OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS
- OSSL_FUNC_serializer_settable_ctx_params OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS
+ OSSL_FUNC_encoder_newctx              OSSL_FUNC_ENCODER_NEWCTX
+ OSSL_FUNC_encoder_freectx             OSSL_FUNC_ENCODER_FREECTX
+ OSSL_FUNC_encoder_set_ctx_params      OSSL_FUNC_ENCODER_SET_CTX_PARAMS
+ OSSL_FUNC_encoder_settable_ctx_params OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS
 
- OSSL_FUNC_serializer_serialize_data      OSSL_FUNC_SERIALIZER_SERIALIZE_DATA
- OSSL_FUNC_serializer_serialize_object    OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT
+ OSSL_FUNC_encoder_encode_data      OSSL_FUNC_ENCODER_ENCODE_DATA
+ OSSL_FUNC_encoder_encode_object    OSSL_FUNC_ENCODER_ENCODE_OBJECT
 
 =head2 Names and properties
 
 The name of an implementation should match the type of object it
-handles.  For example, an implementation that serializes an RSA key
+handles.  For example, an implementation that encodes an RSA key
 should be named accordingly.
 
-To be able to specify exactly what serialization format and what type
-of data a serializer implementation is expected to handle, two
+To be able to specify exactly what encoding format and what type
+of data a encoder implementation is expected to handle, two
 additional properties may be given:
 
 =over 4
@@ -156,77 +153,77 @@ know anything about.
 
 =head2 Context functions
 
-OSSL_FUNC_serializer_newctx() returns a context to be used with the rest of
+OSSL_FUNC_encoder_newctx() returns a context to be used with the rest of
 the functions.
 
-OSSL_FUNC_serializer_freectx() frees the given I<ctx>, if it was created by
-OSSL_FUNC_serializer_newctx().
+OSSL_FUNC_encoder_freectx() frees the given I<ctx>, if it was created by
+OSSL_FUNC_encoder_newctx().
 
-OSSL_FUNC_serializer_set_ctx_params() sets context data according to
+OSSL_FUNC_encoder_set_ctx_params() sets context data according to
 parameters from I<params> that it recognises.  Unrecognised parameters
 should be ignored.
 
-OSSL_FUNC_serializer_settable_ctx_params() returns a constant B<OSSL_PARAM>
-array describing the parameters that OSSL_FUNC_serializer_set_ctx_params()
+OSSL_FUNC_encoder_settable_ctx_params() returns a constant B<OSSL_PARAM>
+array describing the parameters that OSSL_FUNC_encoder_set_ctx_params()
 can handle.
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure used
-by OSSL_FUNC_serializer_set_ctx_params() and OSSL_FUNC_serializer_settable_ctx_params().
+by OSSL_FUNC_encoder_set_ctx_params() and OSSL_FUNC_encoder_settable_ctx_params().
 
-=head2 Serializing functions
+=head2 Encoding functions
 
-=for comment There will be a "Deserializing functions" title as well
+=for comment There will be a "Decoding functions" title as well
 
-OSSL_FUNC_serializer_serialize_data() should take an array of B<OSSL_PARAM>,
+OSSL_FUNC_encoder_encode_data() should take an array of B<OSSL_PARAM>,
 I<data>, and if it contains the data necessary for the object type
 that the implementation handles, it should output the object in
-serialized form to the B<OSSL_CORE_BIO>.
+encoded form to the B<OSSL_CORE_BIO>.
 
-OSSL_FUNC_serializer_serialize_object() should take a pointer to an object
-that it knows intimately, and output that object in serialized form to
+OSSL_FUNC_encoder_encode_object() should take a pointer to an object
+that it knows intimately, and output that object in encoded form to
 the B<OSSL_CORE_BIO>.  The caller I<must> ensure that this function is called
 with a pointer that the provider of this function is familiar with.
 It is not suitable to use with object pointers coming from other
 providers.
 
-Both serialization functions also take an B<OSSL_PASSPHRASE_CALLBACK>
+Both encoding functions also take an B<OSSL_PASSPHRASE_CALLBACK>
 function pointer along with a pointer to application data I<cbarg>,
 which should be used when a pass phrase prompt is needed.
 
-=head2 Serializer parameters
+=head2 Encoder parameters
 
-Parameters currently recognised by built-in serializers are as
+Parameters currently recognised by built-in encoders are as
 follows:
 
 =over 4
 
-=item "cipher" (B<OSSL_SERIALIZER_PARAM_CIPHER>) <UTF8 string>
+=item "cipher" (B<OSSL_ENCODER_PARAM_CIPHER>) <UTF8 string>
 
 The name of the encryption cipher to be used when generating encrypted
-serialization.  This is used when serializing private keys, as well as
+encoding.  This is used when encoding private keys, as well as
 other objects that need protection.
 
-If this name is invalid for the serialization implementation, the
-implementation should refuse to perform the serialization, i.e.
-OSSL_FUNC_serializer_serialize_data() and OSSL_FUNC_serializer_serialize_object()
+If this name is invalid for the encoding implementation, the
+implementation should refuse to perform the encoding, i.e.
+OSSL_FUNC_encoder_encode_data() and OSSL_FUNC_encoder_encode_object()
 should return an error.
 
-=item "properties" (B<OSSL_SERIALIZER_PARAM_PROPERTIES>) <UTF8 string>
+=item "properties" (B<OSSL_ENCODER_PARAM_PROPERTIES>) <UTF8 string>
 
 The properties to be queried when trying to fetch the algorithm given
 with the "cipher" parameter.
 This must be given together with the "cipher" parameter to be
 considered valid.
 
-The serialization implementation isn't obligated to use this value.
+The encoding implementation isn't obligated to use this value.
 However, it is recommended that implementations that do not handle
 property strings return an error on receiving this parameter unless
 its value NULL or the empty string.
 
-=item "passphrase" (B<OSSL_SERIALIZER_PARAM_PASS>) <octet string>
+=item "passphrase" (B<OSSL_ENCODER_PARAM_PASS>) <octet string>
 
 A pass phrase provided by the application.  When this is given, the
-built-in serializers will not attempt to use the passphrase callback.
+built-in encoders will not attempt to use the passphrase callback.
 
 =back
 
@@ -244,16 +241,16 @@ of object it's being prompted for.
 
 =head1 RETURN VALUES
 
-OSSL_FUNC_serializer_newctx() returns a pointer to a context, or NULL on
+OSSL_FUNC_encoder_newctx() returns a pointer to a context, or NULL on
 failure.
 
-OSSL_FUNC_serializer_set_ctx_params() returns 1, unless a recognised
+OSSL_FUNC_encoder_set_ctx_params() returns 1, unless a recognised
 parameters was invalid or caused an error, for which 0 is returned.
 
-OSSL_FUNC_serializer_settable_ctx_params() returns a pointer to an array of
+OSSL_FUNC_encoder_settable_ctx_params() returns a pointer to an array of
 constant B<OSSL_PARAM> elements.
 
-OSSL_FUNC_serializer_serialize_data() and OSSL_FUNC_serializer_serialize_object()
+OSSL_FUNC_encoder_encode_data() and OSSL_FUNC_encoder_encode_object()
 return 1 on success, or 0 on failure.
 
 =head1 SEE ALSO
@@ -262,7 +259,7 @@ L<provider(7)>
 
 =head1 HISTORY
 
-The SERIALIZER interface was introduced in OpenSSL 3.0.
+The ENCODER interface was introduced in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
index 62ff869..2f7f019 100644 (file)
@@ -154,13 +154,13 @@ The number for this operation is B<OSSL_OP_ASYM_CIPHER>.
 The functions the provider can offer are described in
 L<provider-asym_cipher(7)>
 
-=item Serialization
+=item Encoding
 
 In the OpenSSL libraries, the corresponding method object is
-B<OSSL_SERIALIZER>.
-The number for this operation is B<OSSL_OP_SERIALIZER>.
+B<OSSL_ENCODER>.
+The number for this operation is B<OSSL_OP_ENCODER>.
 The functions the provider can offer are described in
-L<provider-serializer(7)>
+L<provider-encoder(7)>
 
 =back
 
@@ -277,7 +277,7 @@ The base provider is built in as part of the F<libcrypto> library.
 Should it be needed (if other providers are loaded and offer
 implementations of the same algorithms), the property "provider=base"
 can be used as a search criterion for these implementations. Some
-non-cryptographic algorithms (such as serializers for loading keys and
+non-cryptographic algorithms (such as encoders for loading keys and
 parameters from files) are not FIPS algorithm implementations in themselves but
 support algorithms from the FIPS provider and are allowed for use in "FIPS
 mode". The property "fips=yes" can be used to select such algorithms.
similarity index 53%
rename from include/crypto/serializer.h
rename to include/crypto/encoder.h
index 84d6b54..f75a031 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <openssl/types.h>
 
-OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
-                                                 const char *properties);
-OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
-                                                     const char *properties);
+OSSL_ENCODER *ossl_encoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+                                           const char *properties);
+OSSL_DECODER *ossl_decoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+                                           const char *properties);
index d0dd6fe..3075bd7 100644 (file)
@@ -155,8 +155,8 @@ typedef struct ossl_ex_data_global_st {
 # define OPENSSL_CTX_RAND_CRNGT_INDEX               7
 # define OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX     8
 # define OPENSSL_CTX_FIPS_PROV_INDEX                9
-# define OPENSSL_CTX_SERIALIZER_STORE_INDEX        10
-# define OPENSSL_CTX_DESERIALIZER_STORE_INDEX      11
+# define OPENSSL_CTX_ENCODER_STORE_INDEX        10
+# define OPENSSL_CTX_DECODER_STORE_INDEX      11
 # define OPENSSL_CTX_SELF_TEST_CB_INDEX            12
 # define OPENSSL_CTX_BIO_PROV_INDEX                13
 # define OPENSSL_CTX_GLOBAL_PROPERTIES             14
index 55144f1..ee589ea 100644 (file)
@@ -191,8 +191,8 @@ OSSL_CORE_MAKE_FUNC(int, provider_self_test, (void *provctx))
 # define OSSL_OP_SIGNATURE                          12
 # define OSSL_OP_ASYM_CIPHER                        13
 /* New section for non-EVP operations */
-# define OSSL_OP_SERIALIZER                         20
-# define OSSL_OP_DESERIALIZER                       21
+# define OSSL_OP_ENCODER                         20
+# define OSSL_OP_DECODER                       21
 /* Highest known operation number */
 # define OSSL_OP__HIGHEST                           21
 
@@ -713,50 +713,50 @@ OSSL_CORE_MAKE_FUNC(int, asym_cipher_set_ctx_params,
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, asym_cipher_settable_ctx_params,
                     (void *provctx))
 
-/* Serializers and deserializers */
-# define OSSL_FUNC_SERIALIZER_NEWCTX                1
-# define OSSL_FUNC_SERIALIZER_FREECTX               2
-# define OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS        3
-# define OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS   4
-# define OSSL_FUNC_SERIALIZER_SERIALIZE_DATA       10
-# define OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT     11
-OSSL_CORE_MAKE_FUNC(void *, serializer_newctx, (void *provctx))
-OSSL_CORE_MAKE_FUNC(void, serializer_freectx, (void *ctx))
-OSSL_CORE_MAKE_FUNC(int, serializer_set_ctx_params,
+/* Encoders and decoders */
+# define OSSL_FUNC_ENCODER_NEWCTX                      1
+# define OSSL_FUNC_ENCODER_FREECTX                     2
+# define OSSL_FUNC_ENCODER_SET_CTX_PARAMS              3
+# define OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS         4
+# define OSSL_FUNC_ENCODER_ENCODE_DATA                10
+# define OSSL_FUNC_ENCODER_ENCODE_OBJECT              11
+OSSL_CORE_MAKE_FUNC(void *, encoder_newctx, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void, encoder_freectx, (void *ctx))
+OSSL_CORE_MAKE_FUNC(int, encoder_set_ctx_params,
                     (void *ctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, serializer_settable_ctx_params,
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, encoder_settable_ctx_params,
                     (void *provctx))
 
-OSSL_CORE_MAKE_FUNC(int, serializer_serialize_data,
+OSSL_CORE_MAKE_FUNC(int, encoder_encode_data,
                     (void *ctx, const OSSL_PARAM[], OSSL_CORE_BIO *out,
                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
-OSSL_CORE_MAKE_FUNC(int, serializer_serialize_object,
+OSSL_CORE_MAKE_FUNC(int, encoder_encode_object,
                     (void *ctx, void *obj, OSSL_CORE_BIO *out,
                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
 
-# define OSSL_FUNC_DESERIALIZER_NEWCTX              1
-# define OSSL_FUNC_DESERIALIZER_FREECTX             2
-# define OSSL_FUNC_DESERIALIZER_GET_PARAMS          3
-# define OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS     4
-# define OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS      5
-# define OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS 6
-# define OSSL_FUNC_DESERIALIZER_DESERIALIZE        10
-# define OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT      11
-OSSL_CORE_MAKE_FUNC(void *, deserializer_newctx, (void *provctx))
-OSSL_CORE_MAKE_FUNC(void, deserializer_freectx, (void *ctx))
-OSSL_CORE_MAKE_FUNC(int, deserializer_get_params, (OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_gettable_params,
+# define OSSL_FUNC_DECODER_NEWCTX                      1
+# define OSSL_FUNC_DECODER_FREECTX                     2
+# define OSSL_FUNC_DECODER_GET_PARAMS                  3
+# define OSSL_FUNC_DECODER_GETTABLE_PARAMS             4
+# define OSSL_FUNC_DECODER_SET_CTX_PARAMS              5
+# define OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS         6
+# define OSSL_FUNC_DECODER_DECODE                     10
+# define OSSL_FUNC_DECODER_EXPORT_OBJECT              11
+OSSL_CORE_MAKE_FUNC(void *, decoder_newctx, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void, decoder_freectx, (void *ctx))
+OSSL_CORE_MAKE_FUNC(int, decoder_get_params, (OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, decoder_gettable_params,
                     (void *provctx))
-OSSL_CORE_MAKE_FUNC(int, deserializer_set_ctx_params,
+OSSL_CORE_MAKE_FUNC(int, decoder_set_ctx_params,
                     (void *ctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_settable_ctx_params,
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, decoder_settable_ctx_params,
                     (void *provctx))
 
-OSSL_CORE_MAKE_FUNC(int, deserializer_deserialize,
+OSSL_CORE_MAKE_FUNC(int, decoder_decode,
                     (void *ctx, OSSL_CORE_BIO *in,
                      OSSL_CALLBACK *metadata_cb, void *metadata_cbarg,
                      OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg))
-OSSL_CORE_MAKE_FUNC(int, deserializer_export_object,
+OSSL_CORE_MAKE_FUNC(int, decoder_export_object,
                     (void *ctx, const void *objref, size_t objref_sz,
                      OSSL_CALLBACK *export_cb, void *export_cbarg))
 
index 97c4d65..7538d9c 100644 (file)
@@ -400,23 +400,23 @@ extern "C" {
 #define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION   "tls-negotiated-version"
 
 /*
- * Serializer / deserializer parameters
+ * Encoder / decoder parameters
  */
 /* The passphrase may be passed as a utf8 string or an octet string */
-#define OSSL_SERIALIZER_PARAM_CIPHER            OSSL_ALG_PARAM_CIPHER
-#define OSSL_SERIALIZER_PARAM_PROPERTIES        OSSL_ALG_PARAM_PROPERTIES
-#define OSSL_SERIALIZER_PARAM_PASS              "passphrase"
-
-#define OSSL_DESERIALIZER_PARAM_CIPHER          OSSL_ALG_PARAM_CIPHER
-#define OSSL_DESERIALIZER_PARAM_PROPERTIES      OSSL_ALG_PARAM_PROPERTIES
-#define OSSL_DESERIALIZER_PARAM_PASS            "passphrase"
-#define OSSL_DESERIALIZER_PARAM_INPUT_TYPE      "input-type"
-#define OSSL_DESERIALIZER_PARAM_DATA_TYPE       "data-type"
-#define OSSL_DESERIALIZER_PARAM_DATA            "data"
-#define OSSL_DESERIALIZER_PARAM_REFERENCE       "reference"
+#define OSSL_ENCODER_PARAM_CIPHER       OSSL_ALG_PARAM_CIPHER
+#define OSSL_ENCODER_PARAM_PROPERTIES   OSSL_ALG_PARAM_PROPERTIES
+#define OSSL_ENCODER_PARAM_PASS         "passphrase"
+
+#define OSSL_DECODER_PARAM_CIPHER       OSSL_ALG_PARAM_CIPHER
+#define OSSL_DECODER_PARAM_PROPERTIES   OSSL_ALG_PARAM_PROPERTIES
+#define OSSL_DECODER_PARAM_PASS         "passphrase"
+#define OSSL_DECODER_PARAM_INPUT_TYPE   "input-type"
+#define OSSL_DECODER_PARAM_DATA_TYPE    "data-type"
+#define OSSL_DECODER_PARAM_DATA         "data"
+#define OSSL_DECODER_PARAM_REFERENCE    "reference"
 
 /* Passphrase callback parameters */
-#define OSSL_PASSPHRASE_PARAM_INFO              "info"
+#define OSSL_PASSPHRASE_PARAM_INFO      "info"
 
 /* Keygen callback parameters, from provider to libcrypto */
 #define OSSL_GEN_PARAM_POTENTIAL            "potential" /* integer */
diff --git a/include/openssl/decoder.h b/include/openssl/decoder.h
new file mode 100644 (file)
index 0000000..cb5a404
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OPENSSL_DECODER_H
+# define OPENSSL_DECODER_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <stdarg.h>
+# include <stddef.h>
+# include <openssl/decodererr.h>
+# include <openssl/types.h>
+# include <openssl/core.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+OSSL_DECODER *OSSL_DECODER_fetch(OPENSSL_CTX *libctx, const char *name,
+                                 const char *properties);
+int OSSL_DECODER_up_ref(OSSL_DECODER *encoder);
+void OSSL_DECODER_free(OSSL_DECODER *encoder);
+
+const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *encoder);
+const char *OSSL_DECODER_properties(const OSSL_DECODER *encoder);
+int OSSL_DECODER_number(const OSSL_DECODER *encoder);
+int OSSL_DECODER_is_a(const OSSL_DECODER *encoder, const char *name);
+
+void OSSL_DECODER_do_all_provided(OPENSSL_CTX *libctx,
+                                  void (*fn)(OSSL_DECODER *encoder, void *arg),
+                                  void *arg);
+void OSSL_DECODER_names_do_all(const OSSL_DECODER *encoder,
+                               void (*fn)(const char *name, void *data),
+                               void *data);
+const OSSL_PARAM *OSSL_DECODER_gettable_params(OSSL_DECODER *decoder);
+int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[]);
+
+const OSSL_PARAM *OSSL_DECODER_settable_ctx_params(OSSL_DECODER *encoder);
+OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void);
+int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
+                                const OSSL_PARAM params[]);
+void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx);
+
+/* Utilities that help set specific parameters */
+int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
+                                    const unsigned char *kstr,
+                                    size_t klen);
+int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
+                                         pem_password_cb *cb,
+                                         void *cbarg);
+int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
+                                       const UI_METHOD *ui_method,
+                                       void *ui_data);
+
+/*
+ * Utilities to read the object to decode, with the result sent to cb.
+ * These will discover all provided methods
+ */
+
+int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
+                                    const char *input_type);
+int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder);
+int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
+                               OPENSSL_CTX *libctx, const char *propq);
+int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx);
+
+typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE;
+OSSL_DECODER *
+OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst);
+void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst);
+
+typedef int (OSSL_DECODER_CONSTRUCT)(OSSL_DECODER_INSTANCE *decoder_inst,
+                                     const OSSL_PARAM *params,
+                                     void *construct_data);
+typedef void (OSSL_DECODER_CLEANUP)(void *construct_data);
+
+int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
+                                   OSSL_DECODER_CONSTRUCT *construct);
+int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
+                                        void *construct_data);
+int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
+                                 OSSL_DECODER_CLEANUP *cleanup);
+OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx);
+void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx);
+OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx);
+
+int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
+                        void *reference, size_t reference_sz,
+                        OSSL_CALLBACK *export_cb, void *export_cbarg);
+
+int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in);
+#ifndef OPENSSL_NO_STDIO
+int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *in);
+#endif
+
+/*
+ * Create the OSSL_DECODER_CTX with an associated type.  This will perform
+ * an implicit OSSL_DECODER_fetch(), suitable for the object of that type.
+ */
+OSSL_DECODER_CTX *
+OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, const char *input_type,
+                                 OPENSSL_CTX *libctx, const char *propquery);
+
+# ifdef __cplusplus
+}
+# endif
+#endif
similarity index 68%
rename from include/openssl/deserializererr.h
rename to include/openssl/decodererr.h
index 1c6573a..8da9157 100644 (file)
@@ -8,8 +8,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#ifndef OPENSSL_OSSL_DESERIALIZERERR_H
-# define OPENSSL_OSSL_DESERIALIZERERR_H
+#ifndef OPENSSL_OSSL_DECODERERR_H
+# define OPENSSL_OSSL_DECODERERR_H
 # pragma once
 
 # include <openssl/opensslconf.h>
 # ifdef  __cplusplus
 extern "C"
 # endif
-int ERR_load_OSSL_DESERIALIZER_strings(void);
+int ERR_load_OSSL_DECODER_strings(void);
 
 /*
- * OSSL_DESERIALIZER function codes.
+ * OSSL_DECODER function codes.
  */
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 # endif
 
 /*
- * OSSL_DESERIALIZER reason codes.
+ * OSSL_DECODER reason codes.
  */
-# define OSSL_DESERIALIZER_R_MISSING_GET_PARAMS           100
+# define OSSL_DECODER_R_MISSING_GET_PARAMS           100
 
 #endif
diff --git a/include/openssl/deserializer.h b/include/openssl/deserializer.h
deleted file mode 100644 (file)
index 0133785..0000000
+++ /dev/null
@@ -1,125 +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
- */
-
-#ifndef OPENSSL_DESERIALIZER_H
-# define OPENSSL_DESERIALIZER_H
-# pragma once
-
-# include <openssl/opensslconf.h>
-
-# ifndef OPENSSL_NO_STDIO
-#  include <stdio.h>
-# endif
-# include <stdarg.h>
-# include <stddef.h>
-# include <openssl/deserializererr.h>
-# include <openssl/types.h>
-# include <openssl/core.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx,
-                                           const char *name,
-                                           const char *properties);
-int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *ser);
-void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *ser);
-
-const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *ser);
-const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *ser);
-int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *ser);
-int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *ser,
-                    &nbs