* https://www.openssl.org/source/license.html
*/
-#ifndef DECODER
-# error Macro DECODER undefined
+#ifndef DECODER_PROVIDER
+# error Macro DECODER_PROVIDER undefined
#endif
+#define DECODER_STRUCTURE_type_specific_keypair "type-specific"
+#define DECODER_STRUCTURE_type_specific_params "type-specific"
+#define DECODER_STRUCTURE_type_specific "type-specific"
+#define DECODER_STRUCTURE_type_specific_no_pub "type-specific"
+#define DECODER_STRUCTURE_PKCS8 "pkcs8"
+#define DECODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo"
+#define DECODER_STRUCTURE_DH "dh"
+#define DECODER_STRUCTURE_DHX "dhx"
+#define DECODER_STRUCTURE_DSA "dsa"
+#define DECODER_STRUCTURE_EC "ec"
+#define DECODER_STRUCTURE_RSA "rsa"
+
+/* Arguments are prefixed with '_' to avoid build breaks on certain platforms */
+#define DECODER(_name, _input, _output, _fips) \
+ { _name, \
+ "provider=" DECODER_PROVIDER ",fips=" #_fips ",input=" #_input, \
+ (ossl_##_input##_to_##_output##_decoder_functions) }
+#define DECODER_w_structure(_name, _input, _structure, _output, _fips) \
+ { _name, \
+ "provider=" DECODER_PROVIDER ",fips=" #_fips ",input=" #_input \
+ ",structure=" DECODER_STRUCTURE_##_structure, \
+ (ossl_##_structure##_##_input##_to_##_output##_decoder_functions) }
+
#ifndef OPENSSL_NO_DH
- DECODER("DH", "yes", "der", ossl_der_to_dh_decoder_functions),
- DECODER("DHX", "yes", "der", ossl_der_to_dhx_decoder_functions),
+DECODER_w_structure("DH", der, PKCS8, dh, yes),
+DECODER_w_structure("DH", der, SubjectPublicKeyInfo, dh, yes),
+DECODER_w_structure("DH", der, type_specific_params, dh, yes),
+DECODER_w_structure("DH", der, DH, dh, yes),
+DECODER_w_structure("DHX", der, PKCS8, dhx, yes),
+DECODER_w_structure("DHX", der, SubjectPublicKeyInfo, dhx, yes),
+DECODER_w_structure("DHX", der, type_specific_params, dhx, yes),
+DECODER_w_structure("DHX", der, DHX, dhx, yes),
#endif
#ifndef OPENSSL_NO_DSA
- DECODER("DSA", "yes", "der", ossl_der_to_dsa_decoder_functions),
- DECODER("DSA", "yes", "mblob", ossl_msblob_to_dsa_decoder_functions),
+DECODER_w_structure("DSA", der, PKCS8, dsa, yes),
+DECODER_w_structure("DSA", der, SubjectPublicKeyInfo, dsa, yes),
+DECODER_w_structure("DSA", der, type_specific, dsa, yes),
+DECODER_w_structure("DSA", der, DSA, dsa, yes),
+DECODER("DSA", msblob, dsa, yes),
# ifndef OPENSSL_NO_RC4
- DECODER("DSA", "yes", "pvk", ossl_pvk_to_dsa_decoder_functions),
+DECODER("DSA", pvk, dsa, yes),
# endif
#endif
#ifndef OPENSSL_NO_EC
- DECODER("EC", "yes", "der", ossl_der_to_ec_decoder_functions),
- DECODER("ED25519", "yes", "der", ossl_der_to_ed25519_decoder_functions),
- DECODER("ED448", "yes", "der", ossl_der_to_ed448_decoder_functions),
- DECODER("X25519", "yes", "der", ossl_der_to_x25519_decoder_functions),
- DECODER("X448", "yes", "der", ossl_der_to_x448_decoder_functions),
+DECODER_w_structure("EC", der, PKCS8, ec, yes),
+DECODER_w_structure("EC", der, SubjectPublicKeyInfo, ec, yes),
+DECODER_w_structure("EC", der, type_specific_no_pub, ec, yes),
+DECODER_w_structure("EC", der, EC, ec, yes),
+DECODER_w_structure("ED25519", der, PKCS8, ed25519, yes),
+DECODER_w_structure("ED25519", der, SubjectPublicKeyInfo, ed25519, yes),
+DECODER_w_structure("ED448", der, PKCS8, ed448, yes),
+DECODER_w_structure("ED448", der, SubjectPublicKeyInfo, ed448, yes),
+DECODER_w_structure("X25519", der, PKCS8, x25519, yes),
+DECODER_w_structure("X25519", der, SubjectPublicKeyInfo, x25519, yes),
+DECODER_w_structure("X448", der, PKCS8, x448, yes),
+DECODER_w_structure("X448", der, SubjectPublicKeyInfo, x448, yes),
#endif
- DECODER("RSA", "yes", "der", ossl_der_to_rsa_decoder_functions),
- DECODER("RSA-PSS", "yes", "der", ossl_der_to_rsapss_decoder_functions),
+DECODER_w_structure("RSA", der, PKCS8, rsa, yes),
+DECODER_w_structure("RSA", der, SubjectPublicKeyInfo, rsa, yes),
+DECODER_w_structure("RSA", der, type_specific_keypair, rsa, yes),
+DECODER_w_structure("RSA", der, RSA, rsa, yes),
+DECODER_w_structure("RSA-PSS", der, PKCS8, rsapss, yes),
+DECODER_w_structure("RSA-PSS", der, SubjectPublicKeyInfo, rsapss, yes),
#ifndef OPENSSL_NO_DSA
- DECODER("RSA", "yes", "mblob", ossl_msblob_to_rsa_decoder_functions),
+DECODER("RSA", msblob, rsa, yes),
# ifndef OPENSSL_NO_RC4
- DECODER("RSA", "yes", "pvk", ossl_pvk_to_rsa_decoder_functions),
+DECODER("RSA", pvk, rsa, yes),
# endif
#endif
- DECODER("DER", "yes", "pem", ossl_pem_to_der_decoder_functions),
-
+DECODER("DER", pem, der, yes),
/* ---------------------------------------------------------------------- */
static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
-static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params;
-static OSSL_FUNC_decoder_get_params_fn der2key_get_params;
static OSSL_FUNC_decoder_decode_fn der2key_decode;
static OSSL_FUNC_decoder_export_object_fn der2key_export_object;
typedef void *(extract_key_fn)(EVP_PKEY *);
typedef void (free_key_fn)(void *);
struct keytype_desc_st {
- int type; /* EVP key type */
- const char *name; /* Keytype */
+ const char *keytype_name;
const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */
+ /* The input structure name */
+ const char *structure_name;
+
+ /*
+ * The EVP_PKEY_xxx type macro. Should be zero for type specific
+ * structures, non-zero when the outermost structure is PKCS#8 or
+ * SubjectPublicKeyInfo. This determines which of the function
+ * pointers below will be used.
+ */
+ int evp_type;
+
+ /* The selection mask for OSSL_FUNC_decoder_does_selection() */
+ int selection_mask;
+
+ /* For type specific decoders, we use the corresponding d2i */
+ d2i_of_void *d2i_private_key;
+ d2i_of_void *d2i_public_key;
+ d2i_of_void *d2i_key_params;
/*
- * These must be the correct EVP_PKEY_get1_{TYPE}() and {TYPE}_free()
- * function for the key.
+ * For PKCS#8 decoders, we use EVP_PKEY extractors, EVP_PKEY_get1_{TYPE}()
*/
extract_key_fn *extract_key;
+ /* {type}_free() */
free_key_fn *free_key;
};
OPENSSL_free(ctx);
}
-static const OSSL_PARAM *der2key_gettable_params(void *provctx)
+static const OSSL_PARAM *
+der2key_gettable_params(void *provctx, const struct keytype_desc_st *desc)
{
static const OSSL_PARAM gettables[] = {
{ OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
OSSL_PARAM_END,
};
+ static const OSSL_PARAM gettables_w_structure[] = {
+ { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
+ { OSSL_DECODER_PARAM_INPUT_STRUCTURE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
+ OSSL_PARAM_END,
+ };
- return gettables;
+ return desc->structure_name != NULL ? gettables_w_structure : gettables;
}
-static int der2key_get_params(OSSL_PARAM params[])
+static int der2key_get_params(OSSL_PARAM params[],
+ const struct keytype_desc_st *desc)
{
OSSL_PARAM *p;
p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER"))
return 0;
+ if (desc->structure_name != NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_STRUCTURE);
+ if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, desc->structure_name))
+ return 0;
+ }
return 1;
}
-static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin,
+static int der2key_check_selection(int selection,
+ const struct keytype_desc_st *desc)
+{
+ /*
+ * The selections are kinda sorta "levels", i.e. each selection given
+ * here is assumed to include those following.
+ */
+ int checks[] = {
+ OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
+ OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+ };
+ size_t i;
+
+ /* The decoder implementations made here support guessing */
+ if (selection == 0)
+ return 1;
+
+ for (i = 0; i < OSSL_NELEM(checks); i++) {
+ int check1 = (selection & checks[i]) != 0;
+ int check2 = (desc->selection_mask & checks[i]) != 0;
+
+ /*
+ * If the caller asked for the currently checked bit(s), return
+ * whether the decoder description says it's supported.
+ */
+ if (check1)
+ return check2;
+ }
+
+ /* This should be dead code, but just to be safe... */
+ return 0;
+}
+
+static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
OSSL_CALLBACK *data_cb, void *data_cbarg,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
{
long new_der_len;
EVP_PKEY *pkey = NULL;
void *key = NULL;
+ int orig_selection = selection;
int ok = 0;
- SET_ERR_MARK();
- if (!read_der(ctx->provctx, cin, &der, &der_len))
- goto err;
-
/*
- * Opportunistic attempt to decrypt. If it doesn't work, we try to
- * decode our input unencrypted.
+ * The caller is allowed to specify 0 as a selection mark, to have the
+ * structure and key type guessed. For type-specific structures, this
+ * is not recommended, as some structures are very similar.
+ * Note that 0 isn't the same as OSSL_KEYMGMT_SELECT_ALL, as the latter
+ * signifies a private key structure, where everything else is assumed
+ * to be present as well.
*/
- if (der_from_p8(&new_der, &new_der_len, der, der_len, pw_cb, pw_cbarg)) {
- OPENSSL_free(der);
- der = new_der;
- der_len = new_der_len;
+ if (selection == 0)
+ selection = ctx->desc->selection_mask;
+ if ((selection & ctx->desc->selection_mask) == 0) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
}
- RESET_ERR_MARK();
- derp = der;
- pkey = d2i_PrivateKey_ex(ctx->desc->type, NULL, &derp, der_len,
- libctx, NULL);
- if (pkey == NULL) {
- RESET_ERR_MARK();
- derp = der;
- pkey = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, NULL);
- }
+ SET_ERR_MARK();
+ if (!read_der(ctx->provctx, cin, &der, &der_len))
+ goto end;
- if (pkey == NULL) {
- RESET_ERR_MARK();
+ if (ctx->desc->extract_key == NULL) {
+ /*
+ * There's no EVP_PKEY extractor, so we use the type specific
+ * functions.
+ */
derp = der;
- pkey = d2i_KeyParams(ctx->desc->type, NULL, &derp, der_len);
- }
- err:
- /*
- * Prune low-level ASN.1 parse errors from error queue, assuming that
- * this is called by decoder_process() in a loop trying several formats.
- */
- CLEAR_ERR_MARK();
-
- if (pkey != NULL) {
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ key = ctx->desc->d2i_private_key(NULL, &derp, der_len);
+ if (key == NULL && orig_selection != 0)
+ goto end;
+ }
+ if (key == NULL
+ && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ key = ctx->desc->d2i_public_key(NULL, &derp, der_len);
+ if (key == NULL && orig_selection != 0)
+ goto end;
+ }
+ if (key == NULL
+ && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) {
+ key = ctx->desc->d2i_key_params(NULL, &derp, der_len);
+ }
+ } else {
/*
- * Tear out the low-level key pointer from the pkey,
- * but only if it matches the expected key type.
- *
- * TODO(3.0): The check should be done with EVP_PKEY_is_a(), but
- * as long as we still have #legacy internal keys, it's safer to
- * use the type numbers inside the provider.
+ * There is a EVP_PKEY extractor, so we use the more generic
+ * EVP_PKEY functions, since they know how to unpack PKCS#8 and
+ * SubjectPublicKeyInfo.
*/
- if (EVP_PKEY_id(pkey) == ctx->desc->type)
- key = ctx->desc->extract_key(pkey);
/*
- * ctx->desc->extract_key() is expected to have incremented |key|'s
- * reference count, so it should be safe to free |pkey| now.
+ * Opportunistic attempt to decrypt. If it doesn't work, we try
+ * to decode our input unencrypted.
*/
- EVP_PKEY_free(pkey);
+ if (der_from_p8(&new_der, &new_der_len, der, der_len,
+ pw_cb, pw_cbarg)) {
+ OPENSSL_free(der);
+ der = new_der;
+ der_len = new_der_len;
+ }
+ RESET_ERR_MARK();
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ derp = der;
+ pkey = d2i_PrivateKey_ex(ctx->desc->evp_type, NULL, &derp, der_len,
+ libctx, NULL);
+ }
+
+ if (pkey == NULL
+ && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ RESET_ERR_MARK();
+ derp = der;
+ pkey = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, NULL);
+ }
+
+ if (pkey != NULL) {
+ /*
+ * Tear out the low-level key pointer from the pkey,
+ * but only if it matches the expected key type.
+ *
+ * TODO: The check should be done with EVP_PKEY_is_a(), but
+ * as long as we still have #legacy internal keys, it's safer
+ * to use the type numbers inside the provider.
+ */
+ if (EVP_PKEY_id(pkey) == ctx->desc->evp_type)
+ key = ctx->desc->extract_key(pkey);
+
+ /*
+ * ctx->desc->extract_key() is expected to have incremented
+ * |key|'s reference count, so it should be safe to free |pkey|
+ * now.
+ */
+ EVP_PKEY_free(pkey);
+ }
}
+ end:
+ /*
+ * Prune low-level ASN.1 parse errors from error queue, assuming
+ * that this is called by decoder_process() in a loop trying several
+ * formats.
+ */
+ CLEAR_ERR_MARK();
+
OPENSSL_free(der);
if (key != NULL) {
OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
params[1] =
OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
- (char *)ctx->desc->name, 0);
+ (char *)ctx->desc->keytype_name,
+ 0);
/* The address of the key becomes the octet string */
params[2] =
OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
return 0;
}
-#define IMPLEMENT_NEWCTX(KEYTYPEstr, KEYTYPE, keytype, extract, free) \
- static const struct keytype_desc_st keytype##_desc = \
- { EVP_PKEY_##KEYTYPE, KEYTYPEstr, \
- ossl_##keytype##_keymgmt_functions, \
- (extract_key_fn *)extract, \
- (free_key_fn *)free }; \
- static OSSL_FUNC_decoder_newctx_fn der2##keytype##_newctx; \
- static void *der2##keytype##_newctx(void *provctx) \
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_DH
+# define dh_evp_type EVP_PKEY_DH
+# define dh_evp_extract (extract_key_fn *)EVP_PKEY_get1_DH
+# define dh_d2i_private_key NULL
+# define dh_d2i_public_key NULL
+# define dh_d2i_key_params (d2i_of_void *)d2i_DHparams
+# define dh_free (free_key_fn *)DH_free
+
+# define dhx_evp_type EVP_PKEY_DHX
+# define dhx_evp_extract (extract_key_fn *)EVP_PKEY_get1_DH
+# define dhx_d2i_private_key NULL
+# define dhx_d2i_public_key NULL
+# define dhx_d2i_key_params (d2i_of_void *)d2i_DHxparams
+# define dhx_free (free_key_fn *)DH_free
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_DSA
+# define dsa_evp_type EVP_PKEY_DSA
+# define dsa_evp_extract (extract_key_fn *)EVP_PKEY_get1_DSA
+# define dsa_d2i_private_key (d2i_of_void *)d2i_DSAPrivateKey
+# define dsa_d2i_public_key (d2i_of_void *)d2i_DSAPublicKey
+# define dsa_d2i_key_params (d2i_of_void *)d2i_DSAparams
+# define dsa_free (free_key_fn *)DSA_free
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_EC
+# define ec_evp_type EVP_PKEY_EC
+# define ec_evp_extract (extract_key_fn *)EVP_PKEY_get1_EC_KEY
+# define ec_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey
+# define ec_d2i_public_key NULL
+# define ec_d2i_key_params (d2i_of_void *)d2i_ECParameters
+# define ec_free (free_key_fn *)EC_KEY_free
+
+/*
+ * ED25519, ED448, X25519, X448 only implement PKCS#8 and SubjectPublicKeyInfo,
+ * so no d2i functions to be had.
+ */
+# define ed25519_evp_type EVP_PKEY_ED25519
+# define ed25519_evp_extract (extract_key_fn *)evp_pkey_get1_ED25519
+# define ed25519_d2i_private_key NULL
+# define ed25519_d2i_public_key NULL
+# define ed25519_d2i_key_params NULL
+# define ed25519_free (free_key_fn *)ecx_key_free
+
+# define ed448_evp_type EVP_PKEY_ED448
+# define ed448_evp_extract (extract_key_fn *)evp_pkey_get1_ED448
+# define ed448_d2i_private_key NULL
+# define ed448_d2i_public_key NULL
+# define ed448_d2i_key_params NULL
+# define ed448_free (free_key_fn *)ecx_key_free
+
+# define x25519_evp_type EVP_PKEY_X25519
+# define x25519_evp_extract (extract_key_fn *)evp_pkey_get1_X25519
+# define x25519_d2i_private_key NULL
+# define x25519_d2i_public_key NULL
+# define x25519_d2i_key_params NULL
+# define x25519_free (free_key_fn *)ecx_key_free
+
+# define x448_evp_type EVP_PKEY_X448
+# define x448_evp_extract (extract_key_fn *)evp_pkey_get1_X448
+# define x448_d2i_private_key NULL
+# define x448_d2i_public_key NULL
+# define x448_d2i_key_params NULL
+# define x448_free (free_key_fn *)ecx_key_free
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#define rsa_evp_type EVP_PKEY_RSA
+#define rsa_evp_extract (extract_key_fn *)EVP_PKEY_get1_RSA
+#define rsa_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey
+#define rsa_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey
+#define rsa_d2i_key_params NULL
+#define rsa_free (free_key_fn *)RSA_free
+
+#define rsapss_evp_type EVP_PKEY_RSA_PSS
+#define rsapss_evp_extract (extract_key_fn *)EVP_PKEY_get1_RSA
+#define rsapss_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey
+#define rsapss_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey
+#define rsapss_d2i_key_params NULL
+#define rsapss_free (free_key_fn *)RSA_free
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * The DO_ macros help define the selection mask and the method functions
+ * for each kind of object we want to decode.
+ */
+#define DO_type_specific_keypair(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_KEYPAIR ), \
+ keytype##_d2i_private_key, \
+ keytype##_d2i_public_key, \
+ NULL, \
+ NULL, \
+ keytype##_free
+
+#define DO_type_specific_pub(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_PUBLIC_KEY ), \
+ NULL, \
+ keytype##_d2i_public_key, \
+ NULL, \
+ NULL, \
+ keytype##_free
+
+#define DO_type_specific_priv(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ), \
+ keytype##_d2i_private_key, \
+ NULL, \
+ NULL, \
+ NULL, \
+ keytype##_free
+
+#define DO_type_specific_params(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ NULL, \
+ NULL, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_type_specific(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL ), \
+ keytype##_d2i_private_key, \
+ keytype##_d2i_public_key, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_type_specific_no_pub(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY \
+ | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ keytype##_d2i_private_key, \
+ NULL, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_PKCS8(keytype) \
+ "pkcs8", keytype##_evp_type, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ keytype##_evp_extract, \
+ keytype##_free
+
+#define DO_SubjectPublicKeyInfo(keytype) \
+ "SubjectPublicKeyInfo", keytype##_evp_type, \
+ ( OSSL_KEYMGMT_SELECT_PUBLIC_KEY ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ keytype##_evp_extract, \
+ keytype##_free
+
+#define DO_DH(keytype) \
+ "DH", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ NULL, \
+ NULL, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_DHX(keytype) \
+ "DHX", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ NULL, \
+ NULL, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_DSA(keytype) \
+ "DSA", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL ), \
+ keytype##_d2i_private_key, \
+ keytype##_d2i_public_key, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_EC(keytype) \
+ "EC", 0, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY \
+ | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ keytype##_d2i_private_key, \
+ NULL, \
+ keytype##_d2i_key_params, \
+ NULL, \
+ keytype##_free
+
+#define DO_RSA(keytype) \
+ "RSA", 0, \
+ ( OSSL_KEYMGMT_SELECT_KEYPAIR ), \
+ keytype##_d2i_private_key, \
+ keytype##_d2i_public_key, \
+ NULL, \
+ NULL, \
+ keytype##_free
+
+/*
+ * MAKE_DECODER is the single driver for creating OSSL_DISPATCH tables.
+ * It takes the following arguments:
+ *
+ * keytype_name The implementation key type as a string.
+ * keytype The implementation key type. This must correspond exactly
+ * to our existing keymgmt keytype names... in other words,
+ * there must exist an ossl_##keytype##_keymgmt_functions.
+ * type The type name for the set of functions that implement the
+ * decoder for the key type. This isn't necessarily the same
+ * as keytype. For example, the key types ed25519, ed448,
+ * x25519 and x448 are all handled by the same functions with
+ * the common type name ecx.
+ * kind The kind of support to implement. This translates into
+ * the DO_##kind macros above, to populate the keytype_desc_st
+ * structure.
+ */
+#define MAKE_DECODER(keytype_name, keytype, type, kind) \
+ static const struct keytype_desc_st kind##_##keytype##_desc = \
+ { keytype_name, ossl_##keytype##_keymgmt_functions, \
+ DO_##kind(keytype) }; \
+ \
+ static OSSL_FUNC_decoder_newctx_fn kind##_der2##keytype##_newctx; \
+ static OSSL_FUNC_decoder_gettable_params_fn \
+ kind##_der2##keytype##_gettable_params; \
+ static OSSL_FUNC_decoder_get_params_fn \
+ kind##_der2##keytype##_get_params; \
+ \
+ static void *kind##_der2##keytype##_newctx(void *provctx) \
+ { \
+ return der2key_newctx(provctx, &kind##_##keytype##_desc); \
+ } \
+ static const OSSL_PARAM * \
+ kind##_der2##keytype##_gettable_params(void *provctx) \
+ { \
+ return \
+ der2key_gettable_params(provctx, &kind##_##keytype##_desc); \
+ } \
+ static int kind##_der2##keytype##_get_params(OSSL_PARAM params[]) \
+ { \
+ return der2key_get_params(params, &kind##_##keytype##_desc); \
+ } \
+ static int kind##_der2##keytype##_does_selection(void *provctx, \
+ int selection) \
{ \
- return der2key_newctx(provctx, &keytype##_desc); \
+ return der2key_check_selection(selection, \
+ &kind##_##keytype##_desc); \
} \
- const OSSL_DISPATCH ossl_der_to_##keytype##_decoder_functions[] = { \
+ const OSSL_DISPATCH \
+ ossl_##kind##_der_to_##keytype##_decoder_functions[] = { \
{ OSSL_FUNC_DECODER_NEWCTX, \
- (void (*)(void))der2##keytype##_newctx }, \
+ (void (*)(void))kind##_der2##keytype##_newctx }, \
{ OSSL_FUNC_DECODER_FREECTX, \
(void (*)(void))der2key_freectx }, \
{ OSSL_FUNC_DECODER_GETTABLE_PARAMS, \
- (void (*)(void))der2key_gettable_params }, \
+ (void (*)(void))kind##_der2##keytype##_gettable_params }, \
{ OSSL_FUNC_DECODER_GET_PARAMS, \
- (void (*)(void))der2key_get_params }, \
+ (void (*)(void))kind##_der2##keytype##_get_params }, \
+ { OSSL_FUNC_DECODER_DOES_SELECTION, \
+ (void (*)(void))kind##_der2##keytype##_does_selection }, \
{ OSSL_FUNC_DECODER_DECODE, \
(void (*)(void))der2key_decode }, \
{ OSSL_FUNC_DECODER_EXPORT_OBJECT, \
}
#ifndef OPENSSL_NO_DH
-IMPLEMENT_NEWCTX("DH", DH, dh, EVP_PKEY_get1_DH, DH_free);
-IMPLEMENT_NEWCTX("DHX", DHX, dhx, EVP_PKEY_get1_DH, DH_free);
+MAKE_DECODER("DH", dh, dh, PKCS8);
+MAKE_DECODER("DH", dh, dh, SubjectPublicKeyInfo);
+MAKE_DECODER("DH", dh, dh, type_specific_params);
+MAKE_DECODER("DH", dh, dh, DH);
+MAKE_DECODER("DHX", dhx, dhx, PKCS8);
+MAKE_DECODER("DHX", dhx, dhx, SubjectPublicKeyInfo);
+MAKE_DECODER("DHX", dhx, dhx, type_specific_params);
+MAKE_DECODER("DHX", dhx, dhx, DHX);
#endif
#ifndef OPENSSL_NO_DSA
-IMPLEMENT_NEWCTX("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free);
+MAKE_DECODER("DSA", dsa, dsa, PKCS8);
+MAKE_DECODER("DSA", dsa, dsa, SubjectPublicKeyInfo);
+MAKE_DECODER("DSA", dsa, dsa, type_specific);
+MAKE_DECODER("DSA", dsa, dsa, DSA);
#endif
#ifndef OPENSSL_NO_EC
-IMPLEMENT_NEWCTX("EC", EC, ec, EVP_PKEY_get1_EC_KEY, EC_KEY_free);
-IMPLEMENT_NEWCTX("X25519", X25519, x25519,
- evp_pkey_get1_X25519, ecx_key_free);
-IMPLEMENT_NEWCTX("X448", X448, x448,
- evp_pkey_get1_X448, ecx_key_free);
-IMPLEMENT_NEWCTX("ED25519", ED25519, ed25519,
- evp_pkey_get1_ED25519, ecx_key_free);
-IMPLEMENT_NEWCTX("ED448", ED448, ed448, evp_pkey_get1_ED448, ecx_key_free);
+MAKE_DECODER("EC", ec, ec, PKCS8);
+MAKE_DECODER("EC", ec, ec, SubjectPublicKeyInfo);
+MAKE_DECODER("EC", ec, ec, type_specific_no_pub);
+MAKE_DECODER("EC", ec, ec, EC);
+MAKE_DECODER("X25519", x25519, ecx, PKCS8);
+MAKE_DECODER("X25519", x25519, ecx, SubjectPublicKeyInfo);
+MAKE_DECODER("X448", x448, ecx, PKCS8);
+MAKE_DECODER("X448", x448, ecx, SubjectPublicKeyInfo);
+MAKE_DECODER("ED25519", ed25519, ecx, PKCS8);
+MAKE_DECODER("ED25519", ed25519, ecx, SubjectPublicKeyInfo);
+MAKE_DECODER("ED448", ed448, ecx, PKCS8);
+MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo);
#endif
-IMPLEMENT_NEWCTX("RSA", RSA, rsa, EVP_PKEY_get1_RSA, RSA_free);
-IMPLEMENT_NEWCTX("RSA-PSS", RSA_PSS, rsapss, EVP_PKEY_get1_RSA, RSA_free);
+MAKE_DECODER("RSA", rsa, rsa, PKCS8);
+MAKE_DECODER("RSA", rsa, rsa, SubjectPublicKeyInfo);
+MAKE_DECODER("RSA", rsa, rsa, type_specific_keypair);
+MAKE_DECODER("RSA", rsa, rsa, RSA);
+MAKE_DECODER("RSA-PSS", rsapss, rsapss, PKCS8);
+MAKE_DECODER("RSA-PSS", rsapss, rsapss, SubjectPublicKeyInfo);