summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-05-27 12:34:03 +0200
committerRichard Levitte <levitte@openssl.org>2021-06-09 17:00:10 +0200
commit6a2b8ff392a304bbb106528653397b864acc53fa (patch)
tree75bd836ad9cec6eec65f270fd4db4b893f73b939
parent320fc032b98cc452c5dc96600b16da40b155123b (diff)
Decoding PKCS#8: separate decoding of encrypted and unencrypted PKCS#8
This has us switch from the 'structure' "pkcs8" to "PrivateKeyInfo", which is sensible considering we already have "SubjectPublicKeyInfo". We also add "EncryptedPrivateKeyInfo", and use it for a special decoder that detects and decrypts an EncryptedPrivateKeyInfo structured DER blob into a PrivateKeyInfo structured DER blob and passes that on to the next decoder implementation. The result of this change is that PKCS#8 decryption should only happen once per decoding instead of once for every expected key type. Furthermore, this new decoder implementation sets the data type to the OID of the algorithmIdentifier field, thus reducing how many decoder implementations are tentativaly run further down the call chain. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15498)
-rw-r--r--apps/rsa.c2
-rw-r--r--crypto/asn1/d2i_pr.c2
-rw-r--r--crypto/asn1/i2d_evp.c2
-rw-r--r--crypto/evp/evp_pkey.c6
-rw-r--r--crypto/pem/pem_local.h2
-rw-r--r--crypto/pem/pem_pk8.c2
-rw-r--r--doc/man3/OSSL_ENCODER_to_bio.pod4
-rw-r--r--doc/man7/openssl-glossary.pod10
-rw-r--r--providers/decoders.inc31
-rw-r--r--providers/encoders.inc48
-rw-r--r--providers/implementations/encode_decode/build.info2
-rw-r--r--providers/implementations/encode_decode/decode_der2key.c89
-rw-r--r--providers/implementations/encode_decode/decode_epki2pki.c153
-rw-r--r--providers/implementations/encode_decode/decode_pem2der.c4
-rw-r--r--providers/implementations/encode_decode/encode_key2any.c228
-rw-r--r--providers/implementations/include/prov/implementations.h67
-rw-r--r--test/endecode_test.c10
-rw-r--r--test/evp_pkey_provided_test.c4
18 files changed, 435 insertions, 231 deletions
diff --git a/apps/rsa.c b/apps/rsa.c
index c4f65cac10..3e9d320ea3 100644
--- a/apps/rsa.c
+++ b/apps/rsa.c
@@ -322,7 +322,7 @@ int rsa_main(int argc, char **argv)
if (traditional)
output_structure = "pkcs1"; /* "type-specific" would work too */
else
- output_structure = "pkcs8";
+ output_structure = "PrivateKeyInfo";
}
}
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index 3b28460d4b..720b7fd6c0 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -32,7 +32,7 @@ d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
EVP_PKEY *pkey = NULL, *bak_a = NULL;
EVP_PKEY **ppkey = &pkey;
const char *key_name = NULL;
- const char *input_structures[] = { "type-specific", "pkcs8", NULL };
+ const char *input_structures[] = { "type-specific", "PrivateKeyInfo", NULL };
int i, ret;
if (keytype != EVP_PKEY_NONE) {
diff --git a/crypto/asn1/i2d_evp.c b/crypto/asn1/i2d_evp.c
index e1d5b7c7c4..8b36388263 100644
--- a/crypto/asn1/i2d_evp.c
+++ b/crypto/asn1/i2d_evp.c
@@ -97,7 +97,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
if (evp_pkey_is_provided(a)) {
static const struct type_and_structure_st output_info[] = {
{ "DER", "type-specific" },
- { "DER", "pkcs8" },
+ { "DER", "PrivateKeyInfo" },
{ NULL, }
};
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 420b69399a..683f4bec54 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -79,8 +79,8 @@ EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
p8_data = encoded_data;
len = encoded_len;
- dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "pkcs8", EVP_PKEY_NONE,
- 0, libctx, propq);
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "PrivateKeyInfo",
+ EVP_PKEY_NONE, 0, libctx, propq);
if (dctx == NULL
|| !OSSL_DECODER_from_data(dctx, &p8_data, &len))
/* try legacy */
@@ -115,7 +115,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey)
const unsigned char *pp;
if ((ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection,
- "DER", "pkcs8",
+ "DER", "PrivateKeyInfo",
NULL)) == NULL
|| !OSSL_ENCODER_to_data(ctx, &der, &derlen))
goto error;
diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h
index a84ca80be1..5cc1c76fdb 100644
--- a/crypto/pem/pem_local.h
+++ b/crypto/pem/pem_local.h
@@ -31,7 +31,7 @@
* Properties, named according to the ASN.1 names used throughout libcrypto.
*/
# define PEM_STRUCTURE_PUBKEY "SubjectPublicKeyInfo"
-# define PEM_STRUCTURE_PrivateKey "pkcs8"
+# define PEM_STRUCTURE_PrivateKey "PrivateKeyInfo"
# define PEM_STRUCTURE_Parameters "type-specific"
# define PEM_STRUCTURE_RSAPrivateKey "type-specific"
diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c
index ab86448db9..4742f02fef 100644
--- a/crypto/pem/pem_pk8.c
+++ b/crypto/pem/pem_pk8.c
@@ -74,7 +74,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
const char *outtype = isder ? "DER" : "PEM";
OSSL_ENCODER_CTX *ctx =
OSSL_ENCODER_CTX_new_for_pkey(x, OSSL_KEYMGMT_SELECT_ALL,
- outtype, "pkcs8", propq);
+ outtype, "PrivateKeyInfo", propq);
if (ctx == NULL)
return 0;
diff --git a/doc/man3/OSSL_ENCODER_to_bio.pod b/doc/man3/OSSL_ENCODER_to_bio.pod
index 315f0a5122..365c74ad05 100644
--- a/doc/man3/OSSL_ENCODER_to_bio.pod
+++ b/doc/man3/OSSL_ENCODER_to_bio.pod
@@ -61,7 +61,7 @@ To encode a pkey as PKCS#8 with PEM format into a bio:
OSSL_ENCODER_CTX *ectx;
const char *format = "PEM";
- const char *structure = "pkcs8"; /* PKCS#8 structure */
+ const char *structure = "PrivateKeyInfo"; /* PKCS#8 structure */
const unsigned char *pass = "my password";
ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey,
@@ -86,7 +86,7 @@ AES-256-CBC into a buffer:
OSSL_ENCODER_CTX *ectx;
const char *format = "DER";
- const char *structure = "pkcs8"; /* PKCS#8 structure */
+ const char *structure = "PrivateKeyInfo"; /* PKCS#8 structure */
const unsigned char *pass = "my password";
unsigned char *data = NULL;
size_t datalen;
diff --git a/doc/man7/openssl-glossary.pod b/doc/man7/openssl-glossary.pod
index fad11e5695..16ff2f3176 100644
--- a/doc/man7/openssl-glossary.pod
+++ b/doc/man7/openssl-glossary.pod
@@ -158,11 +158,13 @@ This is defined in IETF RFC 1421:
L<https://tools.ietf.org/html/rfc1421>
-=item PKCS#8 (also known as "pkcs8" in some parts of OpenSSL)
+=item PKCS#8
-PKCS#8 is a specification of an ASN.1 structure that OpenSSL uses for
-storing or transmitting any private key in a key type agnostic manner, and
-has both an unencrypted and an encrypted form.
+PKCS#8 is a specification of ASN.1 structures that OpenSSL uses for storing
+or transmitting any private key in a key type agnostic manner.
+There are two structures worth noting for OpenSSL use, one that contains the
+key data in unencrypted form (known as "PrivateKeyInfo") and an encrypted
+wrapper structure (known as "EncryptedPrivateKeyInfo").
This is specified in RFC 5208:
diff --git a/providers/decoders.inc b/providers/decoders.inc
index a92abe03e2..02b2b32c3f 100644
--- a/providers/decoders.inc
+++ b/providers/decoders.inc
@@ -15,7 +15,8 @@
#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_EncryptedPrivateKeyInfo "EncryptedPrivateKeyInfo"
+#define DECODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo"
#define DECODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo"
#define DECODER_STRUCTURE_DH "dh"
#define DECODER_STRUCTURE_DHX "dhx"
@@ -35,17 +36,17 @@
(ossl_##_structure##_##_input##_to_##_output##_decoder_functions) }
#ifndef OPENSSL_NO_DH
-DECODER_w_structure("DH", der, PKCS8, dh, yes),
+DECODER_w_structure("DH", der, PrivateKeyInfo, 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, PrivateKeyInfo, 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_w_structure("DSA", der, PKCS8, dsa, yes),
+DECODER_w_structure("DSA", der, PrivateKeyInfo, 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),
@@ -53,30 +54,36 @@ DECODER("DSA", msblob, dsa, yes),
DECODER("DSA", pvk, dsa, yes),
#endif
#ifndef OPENSSL_NO_EC
-DECODER_w_structure("EC", der, PKCS8, ec, yes),
+DECODER_w_structure("EC", der, PrivateKeyInfo, 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, PrivateKeyInfo, ed25519, yes),
DECODER_w_structure("ED25519", der, SubjectPublicKeyInfo, ed25519, yes),
-DECODER_w_structure("ED448", der, PKCS8, ed448, yes),
+DECODER_w_structure("ED448", der, PrivateKeyInfo, ed448, yes),
DECODER_w_structure("ED448", der, SubjectPublicKeyInfo, ed448, yes),
-DECODER_w_structure("X25519", der, PKCS8, x25519, yes),
+DECODER_w_structure("X25519", der, PrivateKeyInfo, x25519, yes),
DECODER_w_structure("X25519", der, SubjectPublicKeyInfo, x25519, yes),
-DECODER_w_structure("X448", der, PKCS8, x448, yes),
+DECODER_w_structure("X448", der, PrivateKeyInfo, x448, yes),
DECODER_w_structure("X448", der, SubjectPublicKeyInfo, x448, yes),
# ifndef OPENSSL_NO_SM2
-DECODER_w_structure("SM2", der, PKCS8, sm2, yes),
+DECODER_w_structure("SM2", der, PrivateKeyInfo, sm2, yes),
DECODER_w_structure("SM2", der, SubjectPublicKeyInfo, sm2, yes),
# endif
#endif
-DECODER_w_structure("RSA", der, PKCS8, rsa, yes),
+DECODER_w_structure("RSA", der, PrivateKeyInfo, 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, PrivateKeyInfo, rsapss, yes),
DECODER_w_structure("RSA-PSS", der, SubjectPublicKeyInfo, rsapss, yes),
DECODER("RSA", msblob, rsa, yes),
DECODER("RSA", pvk, rsa, yes),
DECODER("DER", pem, der, yes),
+/*
+ * A decoder that recognises PKCS#8 EncryptedPrivateKeyInfo structure
+ * and decrypts it, passing on the unencrypted PrivateKeyInfo in DER
+ * form to the next decoder.
+ */
+DECODER_w_structure("DER", der, EncryptedPrivateKeyInfo, der, yes),
diff --git a/providers/encoders.inc b/providers/encoders.inc
index 71f4f13848..a1034f45de 100644
--- a/providers/encoders.inc
+++ b/providers/encoders.inc
@@ -15,7 +15,7 @@
#define ENCODER_STRUCTURE_type_specific_params "type-specific"
#define ENCODER_STRUCTURE_type_specific "type-specific"
#define ENCODER_STRUCTURE_type_specific_no_pub "type-specific"
-#define ENCODER_STRUCTURE_PKCS8 "pkcs8"
+#define ENCODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo"
#define ENCODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo"
#define ENCODER_STRUCTURE_DH "dh"
#define ENCODER_STRUCTURE_DHX "dhx"
@@ -127,70 +127,70 @@ ENCODER("DSA", dsa, yes, pvk),
#endif
/*
- * Entries for PKCS#8 and SubjectPublicKeyInfo.
+ * Entries for PKCS#8 (PrivateKeyInfo) and SubjectPublicKeyInfo.
* The "der" ones are added convenience for any user that wants to use
* OSSL_ENCODER directly.
* The "pem" ones also support PEM_write_bio_PrivateKey() and
* PEM_write_bio_PUBKEY().
*/
-ENCODER_w_structure("RSA", rsa, yes, der, PKCS8),
-ENCODER_w_structure("RSA", rsa, yes, pem, PKCS8),
+ENCODER_w_structure("RSA", rsa, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("RSA", rsa, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("RSA", rsa, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("RSA", rsa, yes, pem, SubjectPublicKeyInfo),
-ENCODER_w_structure("RSA-PSS", rsapss, yes, der, PKCS8),
-ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, PKCS8),
+ENCODER_w_structure("RSA-PSS", rsapss, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("RSA-PSS", rsapss, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, SubjectPublicKeyInfo),
#ifndef OPENSSL_NO_DH
-ENCODER_w_structure("DH", dh, yes, der, PKCS8),
-ENCODER_w_structure("DH", dh, yes, pem, PKCS8),
+ENCODER_w_structure("DH", dh, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("DH", dh, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("DH", dh, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("DH", dh, yes, pem, SubjectPublicKeyInfo),
-ENCODER_w_structure("DHX", dhx, yes, der, PKCS8),
-ENCODER_w_structure("DHX", dhx, yes, pem, PKCS8),
+ENCODER_w_structure("DHX", dhx, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("DHX", dhx, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("DHX", dhx, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("DHX", dhx, yes, pem, SubjectPublicKeyInfo),
#endif
#ifndef OPENSSL_NO_DSA
-ENCODER_w_structure("DSA", dsa, yes, der, PKCS8),
-ENCODER_w_structure("DSA", dsa, yes, pem, PKCS8),
+ENCODER_w_structure("DSA", dsa, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("DSA", dsa, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("DSA", dsa, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("DSA", dsa, yes, pem, SubjectPublicKeyInfo),
#endif
#ifndef OPENSSL_NO_EC
-ENCODER_w_structure("EC", ec, yes, der, PKCS8),
-ENCODER_w_structure("EC", ec, yes, pem, PKCS8),
+ENCODER_w_structure("EC", ec, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("EC", ec, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("EC", ec, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("EC", ec, yes, pem, SubjectPublicKeyInfo),
-ENCODER_w_structure("X25519", x25519, yes, der, PKCS8),
-ENCODER_w_structure("X25519", x25519, yes, pem, PKCS8),
+ENCODER_w_structure("X25519", x25519, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("X25519", x25519, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("X25519", x25519, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("X25519", x25519, yes, pem, SubjectPublicKeyInfo),
-ENCODER_w_structure("X448", x448, yes, der, PKCS8),
-ENCODER_w_structure("X448", x448, yes, pem, PKCS8),
+ENCODER_w_structure("X448", x448, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("X448", x448, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("X448", x448, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("X448", x448, yes, pem, SubjectPublicKeyInfo),
-ENCODER_w_structure("ED25519", ed25519, yes, der, PKCS8),
-ENCODER_w_structure("ED25519", ed25519, yes, pem, PKCS8),
+ENCODER_w_structure("ED25519", ed25519, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ED25519", ed25519, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("ED25519", ed25519, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("ED25519", ed25519, yes, pem, SubjectPublicKeyInfo),
-ENCODER_w_structure("ED448", ed448, yes, der, PKCS8),
-ENCODER_w_structure("ED448", ed448, yes, pem, PKCS8),
+ENCODER_w_structure("ED448", ed448, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ED448", ed448, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("ED448", ed448, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("ED448", ed448, yes, pem, SubjectPublicKeyInfo),
# ifndef OPENSSL_NO_SM2
-ENCODER_w_structure("SM2", sm2, yes, der, PKCS8),
-ENCODER_w_structure("SM2", sm2, yes, pem, PKCS8),
+ENCODER_w_structure("SM2", sm2, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, yes, pem, PrivateKeyInfo),
ENCODER_w_structure("SM2", sm2, yes, der, SubjectPublicKeyInfo),
ENCODER_w_structure("SM2", sm2, yes, pem, SubjectPublicKeyInfo),
# endif
diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info
index 537d393261..22f11cbceb 100644
--- a/providers/implementations/encode_decode/build.info
+++ b/providers/implementations/encode_decode/build.info
@@ -6,7 +6,7 @@ $DECODER_GOAL=../../libdefault.a
SOURCE[$ENCODER_GOAL]=endecoder_common.c
-SOURCE[$DECODER_GOAL]=decode_der2key.c decode_pem2der.c \
+SOURCE[$DECODER_GOAL]=decode_der2key.c decode_epki2pki.c decode_pem2der.c \
decode_msblob2key.c decode_pvk2key.c
SOURCE[$ENCODER_GOAL]=encode_key2any.c encode_key2text.c encode_key2ms.c
diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c
index 22ee075b19..7de44ed75d 100644
--- a/providers/implementations/encode_decode/decode_der2key.c
+++ b/providers/implementations/encode_decode/decode_der2key.c
@@ -41,8 +41,7 @@ typedef int check_key_fn(void *, struct der2key_ctx_st *ctx);
typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx);
typedef void free_key_fn(void *);
typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long,
- struct der2key_ctx_st *,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
+ struct der2key_ctx_st *);
struct keytype_desc_st {
const char *keytype_name;
const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */
@@ -65,7 +64,7 @@ struct keytype_desc_st {
d2i_of_void *d2i_private_key; /* From type-specific DER */
d2i_of_void *d2i_public_key; /* From type-specific DER */
d2i_of_void *d2i_key_params; /* From type-specific DER */
- d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PKCS#8, possibly encrypted */
+ d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PrivateKeyInfo */
d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */
/*
@@ -114,36 +113,13 @@ typedef void *key_from_pkcs8_t(const PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *libctx, const char *propq);
static void *der2key_decode_p8(const unsigned char **input_der,
long input_der_len, struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg,
key_from_pkcs8_t *key_from_pkcs8)
{
- X509_SIG *p8 = NULL;
PKCS8_PRIV_KEY_INFO *p8inf = NULL;
const X509_ALGOR *alg = NULL;
void *key = NULL;
- ctx->flag_fatal = 0;
-
- ERR_set_mark();
- if ((p8 = d2i_X509_SIG(NULL, input_der, input_der_len)) != NULL) {
- char pbuf[PEM_BUFSIZE];
- size_t plen = 0;
-
- ERR_clear_last_mark();
-
- if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg))
- ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE);
- else
- p8inf = PKCS8_decrypt_ex(p8, pbuf, plen, PROV_LIBCTX_OF(ctx->provctx), NULL);
- if (p8inf == NULL)
- ctx->flag_fatal = 1;
- X509_SIG_free(p8);
- } else {
- /* Pop any errors that might have been raised by d2i_X509_SIG. */
- ERR_pop_to_mark();
- p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len);
- }
- if (p8inf != NULL
+ if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len)) != NULL
&& PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)
&& OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type)
key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), NULL);
@@ -247,8 +223,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
derp = der;
if (ctx->desc->d2i_PKCS8 != NULL) {
- key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx,
- pw_cb, pw_cbarg);
+ key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx);
if (ctx->flag_fatal)
goto end;
} else if (ctx->desc->d2i_private_key != NULL) {
@@ -360,10 +335,9 @@ static int der2key_export_object(void *vctx,
# define dh_d2i_key_params (d2i_of_void *)d2i_DHparams
static void *dh_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
- struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+ struct der2key_ctx_st *ctx)
{
- return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+ return der2key_decode_p8(der, der_len, ctx,
(key_from_pkcs8_t *)ossl_dh_key_from_pkcs8);
}
@@ -396,10 +370,9 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx)
# define dsa_d2i_key_params (d2i_of_void *)d2i_DSAparams
static void *dsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
- struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+ struct der2key_ctx_st *ctx)
{
- return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+ return der2key_decode_p8(der, der_len, ctx,
(key_from_pkcs8_t *)ossl_dsa_key_from_pkcs8);
}
@@ -422,10 +395,9 @@ static void dsa_adjust(void *key, struct der2key_ctx_st *ctx)
# define ec_d2i_key_params (d2i_of_void *)d2i_ECParameters
static void *ec_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
- struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+ struct der2key_ctx_st *ctx)
{
- return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+ return der2key_decode_p8(der, der_len, ctx,
(key_from_pkcs8_t *)ossl_ec_key_from_pkcs8);
}
@@ -452,10 +424,9 @@ static void ec_adjust(void *key, struct der2key_ctx_st *ctx)
*/
static void *ecx_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
- struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+ struct der2key_ctx_st *ctx)
{
- return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+ return der2key_decode_p8(der, der_len, ctx,
(key_from_pkcs8_t *)ossl_ecx_key_from_pkcs8);
}
@@ -511,10 +482,9 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx)
# define sm2_d2i_key_params (d2i_of_void *)d2i_ECParameters
static void *sm2_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
- struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+ struct der2key_ctx_st *ctx)
{
- return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+ return der2key_decode_p8(der, der_len, ctx,
(key_from_pkcs8_t *)ossl_ec_key_from_pkcs8);
}
@@ -533,10 +503,9 @@ static void *sm2_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
#define rsa_d2i_key_params NULL
static void *rsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
- struct der2key_ctx_st *ctx,
- OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+ struct der2key_ctx_st *ctx)
{
- return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+ return der2key_decode_p8(der, der_len, ctx,
(key_from_pkcs8_t *)ossl_rsa_key_from_pkcs8);
}
@@ -650,8 +619,8 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx)
keytype##_adjust, \
keytype##_free
-#define DO_PKCS8(keytype) \
- "pkcs8", keytype##_evp_type, \
+#define DO_PrivateKeyInfo(keytype) \
+ "PrivateKeyInfo", keytype##_evp_type, \
( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ), \
NULL, \
NULL, \
@@ -785,42 +754,42 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx)
}
#ifndef OPENSSL_NO_DH
-MAKE_DECODER("DH", dh, dh, PKCS8);
+MAKE_DECODER("DH", dh, dh, PrivateKeyInfo);
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, PrivateKeyInfo);
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
-MAKE_DECODER("DSA", dsa, dsa, PKCS8);
+MAKE_DECODER("DSA", dsa, dsa, PrivateKeyInfo);
MAKE_DECODER("DSA", dsa, dsa, SubjectPublicKeyInfo);
MAKE_DECODER("DSA", dsa, dsa, type_specific);
MAKE_DECODER("DSA", dsa, dsa, DSA);
#endif
#ifndef OPENSSL_NO_EC
-MAKE_DECODER("EC", ec, ec, PKCS8);
+MAKE_DECODER("EC", ec, ec, PrivateKeyInfo);
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, PrivateKeyInfo);
MAKE_DECODER("X25519", x25519, ecx, SubjectPublicKeyInfo);
-MAKE_DECODER("X448", x448, ecx, PKCS8);
+MAKE_DECODER("X448", x448, ecx, PrivateKeyInfo);
MAKE_DECODER("X448", x448, ecx, SubjectPublicKeyInfo);
-MAKE_DECODER("ED25519", ed25519, ecx, PKCS8);
+MAKE_DECODER("ED25519", ed25519, ecx, PrivateKeyInfo);
MAKE_DECODER("ED25519", ed25519, ecx, SubjectPublicKeyInfo);
-MAKE_DECODER("ED448", ed448, ecx, PKCS8);
+MAKE_DECODER("ED448", ed448, ecx, PrivateKeyInfo);
MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo);
# ifndef OPENSSL_NO_SM2
-MAKE_DECODER("SM2", sm2, ec, PKCS8);
+MAKE_DECODER("SM2", sm2, ec, PrivateKeyInfo);
MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo);
# endif
#endif
-MAKE_DECODER("RSA", rsa, rsa, PKCS8);
+MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo);
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, PrivateKeyInfo);
MAKE_DECODER("RSA-PSS", rsapss, rsapss, SubjectPublicKeyInfo);
diff --git a/providers/implementations/encode_decode/decode_epki2pki.c b/providers/implementations/encode_decode/decode_epki2pki.c
new file mode 100644
index 0000000000..c0d014aef1
--- /dev/null
+++ b/providers/implementations/encode_decode/decode_epki2pki.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2020-2021 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/core_names.h>
+#include <openssl/core_object.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+#include <openssl/proverr.h>
+#include "internal/asn1.h"
+#include "internal/sizes.h"
+#include "prov/bio.h"
+#include "prov/implementations.h"
+#include "endecoder_local.h"
+
+static OSSL_FUNC_decoder_newctx_fn epki2pki_newctx;
+static OSSL_FUNC_decoder_freectx_fn epki2pki_freectx;
+static OSSL_FUNC_decoder_decode_fn epki2pki_decode;
+
+/*
+ * Context used for EncryptedPrivateKeyInfo to PrivateKeyInfo decoding.
+ */
+struct epki2pki_ctx_st {
+ PROV_CTX *provctx;
+};
+
+static void *epki2pki_newctx(void *provctx)
+{
+ struct epki2pki_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ if (ctx != NULL)
+ ctx->provctx = provctx;
+ return ctx;
+}
+
+static void epki2pki_freectx(void *vctx)
+{
+ struct epki2pki_ctx_st *ctx = vctx;
+
+ OPENSSL_free(ctx);
+}
+
+/*
+ * The selection parameter in epki2pki_decode() is not used by this function
+ * because it's not relevant just to decode EncryptedPrivateKeyInfo to
+ * PrivateKeyInfo.
+ */
+static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
+ OSSL_CALLBACK *data_cb, void *data_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+ struct epki2pki_ctx_st *ctx = vctx;
+ BUF_MEM *mem = NULL;
+ unsigned char *der = NULL;
+ const unsigned char *pder = NULL;
+ long der_len = 0;
+ X509_SIG *p8 = NULL;
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ const X509_ALGOR *alg = NULL;
+ BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin);
+ int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+
+ BIO_free(in);
+
+ /* We return "empty handed". This is not an error. */
+ if (!ok)
+ return 1;
+
+ pder = der = (unsigned char *)mem->data;
+ der_len = (long)mem->length;
+ OPENSSL_free(mem);
+
+ ok = 1; /* Assume good */
+ ERR_set_mark();
+ if ((p8 = d2i_X509_SIG(NULL, &pder, der_len)) != NULL) {
+ char pbuf[1024];
+ size_t plen = 0;
+
+ ERR_clear_last_mark();
+
+ if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE);
+ } else {
+ const ASN1_OCTET_STRING *oct;
+ unsigned char *new_der = NULL;
+ int new_der_len = 0;
+
+ X509_SIG_get0(p8, &alg, &oct);
+ if (!PKCS12_pbe_crypt_ex(alg, pbuf, plen,
+ oct->data, oct->length,
+ &new_der, &new_der_len, 0,
+ PROV_LIBCTX_OF(ctx->provctx), NULL)) {
+ ok = 0;
+ } else {
+ OPENSSL_free(der);
+ der = new_der;
+ der_len = new_der_len;
+ }
+ alg = NULL;
+ }
+ X509_SIG_free(p8);
+ } else {
+ ERR_pop_to_mark();
+ }
+
+ ERR_set_mark();
+ pder = der;
+ p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &pder, der_len);
+ ERR_pop_to_mark();
+
+ if (p8inf != NULL && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)) {
+ /*
+ * We have something and recognised it as PrivateKeyInfo, so let's
+ * pass all the applicable data to the callback.
+ */
+ char keytype[OSSL_MAX_NAME_SIZE];
+ OSSL_PARAM params[5], *p = params;
+ int objtype = OSSL_OBJECT_PKEY;
+
+ OBJ_obj2txt(keytype, sizeof(keytype), alg->algorithm, 0);
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+ keytype, 0);
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+ "PrivateKeyInfo", 0);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
+ der, der_len);
+ *p++ = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
+ *p = OSSL_PARAM_construct_end();
+
+ ok = data_cb(params, data_cbarg);
+ }
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ OPENSSL_free(der);
+ return ok;
+}
+
+const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions[] = {
+ { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))epki2pki_newctx },
+ { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))epki2pki_freectx },
+ { OSSL_FUNC_DECODER_DECODE, (void (*)(void))epki2pki_decode },
+ { 0, NULL }
+};
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c
index 318efcc6af..16f3322354 100644