diff options
-rw-r--r-- | apps/rsa.c | 2 | ||||
-rw-r--r-- | crypto/asn1/d2i_pr.c | 2 | ||||
-rw-r--r-- | crypto/asn1/i2d_evp.c | 2 | ||||
-rw-r--r-- | crypto/evp/evp_pkey.c | 6 | ||||
-rw-r--r-- | crypto/pem/pem_local.h | 2 | ||||
-rw-r--r-- | crypto/pem/pem_pk8.c | 2 | ||||
-rw-r--r-- | doc/man3/OSSL_ENCODER_to_bio.pod | 4 | ||||
-rw-r--r-- | doc/man7/openssl-glossary.pod | 10 | ||||
-rw-r--r-- | providers/decoders.inc | 31 | ||||
-rw-r--r-- | providers/encoders.inc | 48 | ||||
-rw-r--r-- | providers/implementations/encode_decode/build.info | 2 | ||||
-rw-r--r-- | providers/implementations/encode_decode/decode_der2key.c | 89 | ||||
-rw-r--r-- | providers/implementations/encode_decode/decode_epki2pki.c | 153 | ||||
-rw-r--r-- | providers/implementations/encode_decode/decode_pem2der.c | 4 | ||||
-rw-r--r-- | providers/implementations/encode_decode/encode_key2any.c | 228 | ||||
-rw-r--r-- | providers/implementations/include/prov/implementations.h | 67 | ||||
-rw-r--r-- | test/endecode_test.c | 10 | ||||
-rw-r--r-- | test/evp_pkey_provided_test.c | 4 |
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 --- a/providers/implementations/encode_decode/decode_pem2der.c +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -101,8 +101,8 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, * These entries should be in longest to shortest order to avoid * mixups. */ - { "ENCRYPTED PRIVATE KEY", "pkcs8" }, - { "PRIVATE KEY", "pkcs8" }, + { "ENCRYPTED PRIVATE KEY", "EncryptedPrivateKeyInfo" }, + { "PRIVATE KEY", "PrivateKeyInfo" }, { "PUBLIC KEY", "SubjectPublicKeyInfo" }, { "PARAMETERS", NULL } diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index f986ec124e..855866cbfe 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/im |