diff options
author | Richard Levitte <levitte@openssl.org> | 2020-09-07 12:25:17 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-09-09 16:35:22 +0200 |
commit | 8ae40cf57d2138af92a3479e23f35037ae8c5c30 (patch) | |
tree | 18b15b731f9b593f93716e05884cb0b9ba0a54a5 | |
parent | ce43db7a3fcd18866385a4552f5e4a83adfc0979 (diff) |
ENCODER: Refactor provider implementations, and some cleanup
The encoder implementations were implemented by unnecessarily copying
code into numerous topical source files, making them hard to maintain.
This changes merges all those into two source files, one that encodes
into DER and PEM, the other to text.
Diverse small cleanups are included.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12803)
37 files changed, 2239 insertions, 5033 deletions
diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c index 176f4fab95..76b8386e0c 100644 --- a/crypto/encode_decode/encoder_pkey.c +++ b/crypto/encode_decode/encoder_pkey.c @@ -40,12 +40,7 @@ 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); + return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); } int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx, diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 44e36805f6..df8a7af26c 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2934,6 +2934,7 @@ PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure PROV_R_NOT_A_PRIVATE_KEY:221:not a private key PROV_R_NOT_A_PUBLIC_KEY:220:not a public key PROV_R_NOT_INSTANTIATED:193:not instantiated +PROV_R_NOT_PARAMETERS:224:not parameters PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index ac83f88cc4..ad1df714ea 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -735,7 +735,7 @@ 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, encoder_encode_object, - (void *ctx, void *obj, OSSL_CORE_BIO *out, + (void *ctx, const void *obj, OSSL_CORE_BIO *out, OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)) # define OSSL_FUNC_DECODER_NEWCTX 1 diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index 82eea21049..68bcfb4828 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -131,6 +131,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_NOT_A_PRIVATE_KEY 221 # define PROV_R_NOT_A_PUBLIC_KEY 220 # define PROV_R_NOT_INSTANTIATED 193 +# define PROV_R_NOT_PARAMETERS 224 # define PROV_R_NOT_SUPPORTED 136 # define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 # define PROV_R_NO_KEY_SET 114 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 6d6a254dd6..75f24f88d7 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -136,6 +136,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_PARAMETERS), "not parameters"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH), "not xof or invalid length"}, diff --git a/providers/encoders.inc b/providers/encoders.inc index 4d894a73e5..284703c6e8 100644 --- a/providers/encoders.inc +++ b/providers/encoders.inc @@ -11,102 +11,161 @@ # error Macro ENCODER undefined #endif - ENCODER("RSA", "yes", "text", "private", rsa_priv_text_encoder_functions), - ENCODER("RSA", "yes", "text", "public", rsa_pub_text_encoder_functions), - ENCODER("RSA", "yes", "der", "private", rsa_priv_der_encoder_functions), - ENCODER("RSA", "yes", "der", "public", rsa_pub_der_encoder_functions), - ENCODER("RSA", "yes", "pem", "private", rsa_priv_pem_encoder_functions), - ENCODER("RSA", "yes", "pem", "public", rsa_pub_pem_encoder_functions), + ENCODER("RSA", "yes", "text", "private", + rsa_priv_to_text_encoder_functions), + ENCODER("RSA", "yes", "text", "public", + rsa_pub_to_text_encoder_functions), + ENCODER("RSA", "yes", "der", "private", + rsa_priv_to_der_encoder_functions), + ENCODER("RSA", "yes", "der", "public", + rsa_pub_to_der_encoder_functions), + ENCODER("RSA", "yes", "pem", "private", + rsa_priv_to_pem_encoder_functions), + ENCODER("RSA", "yes", "pem", "public", + rsa_pub_to_pem_encoder_functions), ENCODER("RSA-PSS", "yes", "text", "private", - rsa_priv_text_encoder_functions), - ENCODER("RSA-PSS", "yes", "text", "public", rsa_pub_text_encoder_functions), - ENCODER("RSA-PSS", "yes", "der", "private", rsa_priv_der_encoder_functions), - ENCODER("RSA-PSS", "yes", "der", "public", rsa_pub_der_encoder_functions), - ENCODER("RSA-PSS", "yes", "pem", "private", rsa_priv_pem_encoder_functions), - ENCODER("RSA-PSS", "yes", "pem", "public", rsa_pub_pem_encoder_functions), + rsa_priv_to_text_encoder_functions), + ENCODER("RSA-PSS", "yes", "text", "public", + rsa_pub_to_text_encoder_functions), + ENCODER("RSA-PSS", "yes", "der", "private", + rsa_priv_to_der_encoder_functions), + ENCODER("RSA-PSS", "yes", "der", "public", + rsa_pub_to_der_encoder_functions), + ENCODER("RSA-PSS", "yes", "pem", "private", + rsa_priv_to_pem_encoder_functions), + ENCODER("RSA-PSS", "yes", "pem", "public", + rsa_pub_to_pem_encoder_functions), #ifndef OPENSSL_NO_DH - ENCODER("DH", "yes", "text", "private", dh_priv_text_encoder_functions), - ENCODER("DH", "yes", "text", "public", dh_pub_text_encoder_functions), - ENCODER("DH", "yes", "text", "parameters", dh_param_text_encoder_functions), - ENCODER("DH", "yes", "der", "private", dh_priv_der_encoder_functions), - ENCODER("DH", "yes", "der", "public", dh_pub_der_encoder_functions), - ENCODER("DH", "yes", "der", "parameters", dh_param_der_encoder_functions), - ENCODER("DH", "yes", "pem", "private", dh_priv_pem_encoder_functions), - ENCODER("DH", "yes", "pem", "public", dh_pub_pem_encoder_functions), - ENCODER("DH", "yes", "pem", "parameters", dh_param_pem_encoder_functions), + ENCODER("DH", "yes", "text", "private", + dh_priv_to_text_encoder_functions), + ENCODER("DH", "yes", "text", "public", + dh_pub_to_text_encoder_functions), + ENCODER("DH", "yes", "text", "parameters", + dh_param_to_text_encoder_functions), + ENCODER("DH", "yes", "der", "private", + dh_priv_to_der_encoder_functions), + ENCODER("DH", "yes", "der", "public", + dh_pub_to_der_encoder_functions), + ENCODER("DH", "yes", "der", "parameters", + dh_param_to_der_encoder_functions), + ENCODER("DH", "yes", "pem", "private", + dh_priv_to_pem_encoder_functions), + ENCODER("DH", "yes", "pem", "public", + dh_pub_to_pem_encoder_functions), + ENCODER("DH", "yes", "pem", "parameters", + dh_param_to_pem_encoder_functions), - ENCODER("DHX", "yes", "text", "private", dh_priv_text_encoder_functions), - ENCODER("DHX", "yes", "text", "public", dh_pub_text_encoder_functions), - ENCODER("DHX", "yes", "text", "parameters", dh_param_text_encoder_functions), - ENCODER("DHX", "yes", "der", "private", dh_priv_der_encoder_functions), - ENCODER("DHX", "yes", "der", "public", dh_pub_der_encoder_functions), - ENCODER("DHX", "yes", "der", "parameters", dh_param_der_encoder_functions), - ENCODER("DHX", "yes", "pem", "private", dh_priv_pem_encoder_functions), - ENCODER("DHX", "yes", "pem", "public", dh_pub_pem_encoder_functions), - ENCODER("DHX", "yes", "pem", "parameters", dh_param_pem_encoder_functions), + ENCODER("DHX", "yes", "text", "private", + dh_priv_to_text_encoder_functions), + ENCODER("DHX", "yes", "text", "public", + dh_pub_to_text_encoder_functions), + ENCODER("DHX", "yes", "text", "parameters", + dh_param_to_text_encoder_functions), + ENCODER("DHX", "yes", "der", "private", + dh_priv_to_der_encoder_functions), + ENCODER("DHX", "yes", "der", "public", + dh_pub_to_der_encoder_functions), + ENCODER("DHX", "yes", "der", "parameters", + dh_param_to_der_encoder_functions), + ENCODER("DHX", "yes", "pem", "private", + dh_priv_to_pem_encoder_functions), + ENCODER("DHX", "yes", "pem", "public", + dh_pub_to_pem_encoder_functions), + ENCODER("DHX", "yes", "pem", "parameters", + dh_param_to_pem_encoder_functions), #endif #ifndef OPENSSL_NO_DSA - ENCODER("DSA", "yes", "text", "private", dsa_priv_text_encoder_functions), - ENCODER("DSA", "yes", "text", "public", dsa_pub_text_encoder_functions), + ENCODER("DSA", "yes", "text", "private", + dsa_priv_to_text_encoder_functions), + ENCODER("DSA", "yes", "text", "public", + dsa_pub_to_text_encoder_functions), ENCODER("DSA", "yes", "text", "parameters", - dsa_param_text_encoder_functions), - ENCODER("DSA", "yes", "der", "private", dsa_priv_der_encoder_functions), - ENCODER("DSA", "yes", "der", "public", dsa_pub_der_encoder_functions), - ENCODER("DSA", "yes", "der", "parameters", dsa_param_der_encoder_functions), - ENCODER("DSA", "yes", "pem", "private", dsa_priv_pem_encoder_functions), - ENCODER("DSA", "yes", "pem", "public", dsa_pub_pem_encoder_functions), - ENCODER("DSA", "yes", "pem", "parameters", dsa_param_pem_encoder_functions), + dsa_param_to_text_encoder_functions), + ENCODER("DSA", "yes", "der", "private", + dsa_priv_to_der_encoder_functions), + ENCODER("DSA", "yes", "der", "public", + dsa_pub_to_der_encoder_functions), + ENCODER("DSA", "yes", "der", "parameters", + dsa_param_to_der_encoder_functions), + ENCODER("DSA", "yes", "pem", "private", + dsa_priv_to_pem_encoder_functions), + ENCODER("DSA", "yes", "pem", "public", + dsa_pub_to_pem_encoder_functions), + ENCODER("DSA", "yes", "pem", "parameters", + dsa_param_to_pem_encoder_functions), #endif #ifndef OPENSSL_NO_EC ENCODER("X25519", "yes", "text", "private", - x25519_priv_print_encoder_functions), + x25519_priv_to_text_encoder_functions), ENCODER("X25519", "yes", "text", "public", - x25519_pub_print_encoder_functions), + x25519_pub_to_text_encoder_functions), ENCODER("X25519", "yes", "der", "private", - x25519_priv_der_encoder_functions), - ENCODER("X25519", "yes", "der", "public", x25519_pub_der_encoder_functions), + x25519_priv_to_der_encoder_functions), + ENCODER("X25519", "yes", "der", "public", + x25519_pub_to_der_encoder_functions), ENCODER("X25519", "yes", "pem", "private", - x25519_priv_pem_encoder_functions), - ENCODER("X25519", "yes", "pem", "public", x25519_pub_pem_encoder_functions), + x25519_priv_to_pem_encoder_functions), + ENCODER("X25519", "yes", "pem", "public", + x25519_pub_to_pem_encoder_functions), - ENCODER("X448", "no", "text", "private", x448_priv_print_encoder_functions), - ENCODER("X448", "no", "text", "public", x448_pub_print_encoder_functions), - ENCODER("X448", "no", "der", "private", x448_priv_der_encoder_functions), - ENCODER("X448", "no", "der", "public", x448_pub_der_encoder_functions), - ENCODER("X448", "no", "pem", "private", x448_priv_pem_encoder_functions), - ENCODER("X448", "no", "pem", "public", x448_pub_pem_encoder_functions), + ENCODER("X448", "yes", "text", "private", + x448_priv_to_text_encoder_functions), + ENCODER("X448", "yes", "text", "public", + x448_pub_to_text_encoder_functions), + ENCODER("X448", "yes", "der", "private", + x448_priv_to_der_encoder_functions), + ENCODER("X448", "yes", "der", "public", + x448_pub_to_der_encoder_functions), + ENCODER("X448", "yes", "pem", "private", + x448_priv_to_pem_encoder_functions), + ENCODER("X448", "yes", "pem", "public", + x448_pub_to_pem_encoder_functions), ENCODER("ED25519", "yes", "text", "private", - ed25519_priv_print_encoder_functions), + ed25519_priv_to_text_encoder_functions), ENCODER("ED25519", "yes", "text", "public", - ed25519_pub_print_encoder_functions), + ed25519_pub_to_text_encoder_functions), ENCODER("ED25519", "yes", "der", "private", - ed25519_priv_der_encoder_functions), + ed25519_priv_to_der_encoder_functions), ENCODER("ED25519", "yes", "der", "public", - ed25519_pub_der_encoder_functions), + ed25519_pub_to_der_encoder_functions), ENCODER("ED25519", "yes", "pem", "private", - ed25519_priv_pem_encoder_functions), + ed25519_priv_to_pem_encoder_functions), ENCODER("ED25519", "yes", "pem", "public", - ed25519_pub_pem_encoder_functions), + ed25519_pub_to_pem_encoder_functions), - ENCODER("ED448", "no", "text", "private", - ed448_priv_print_encoder_functions), - ENCODER("ED448", "no", "text", "public", ed448_pub_print_encoder_functions), - ENCODER("ED448", "no", "der", "private", ed448_priv_der_encoder_functions), - ENCODER("ED448", "no", "der", "public", ed448_pub_der_encoder_functions), - ENCODER("ED448", "no", "pem", "private", ed448_priv_pem_encoder_functions), - ENCODER("ED448", "no", "pem", "public", ed448_pub_pem_encoder_functions), + ENCODER("ED448", "yes", "text", "private", + ed448_priv_to_text_encoder_functions), + ENCODER("ED448", "yes", "text", "public", + ed448_pub_to_text_encoder_functions), + ENCODER("ED448", "yes", "der", "private", + ed448_priv_to_der_encoder_functions), + ENCODER("ED448", "yes", "der", "public", + ed448_pub_to_der_encoder_functions), + ENCODER("ED448", "yes", "pem", "private", + ed448_priv_to_pem_encoder_functions), + ENCODER("ED448", "yes", "pem", "public", + ed448_pub_to_pem_encoder_functions), - ENCODER("EC", "yes", "text", "private", ec_priv_text_encoder_functions), - ENCODER("EC", "yes", "text", "public", ec_pub_text_encoder_functions), - ENCODER("EC", "yes", "text", "parameters", ec_param_text_encoder_functions), - ENCODER("EC", "yes", "der", "private", ec_priv_der_encoder_functions), - ENCODER("EC", "yes", "der", "public", ec_pub_der_encoder_functions), - ENCODER("EC", "yes", "der", "parameters", ec_param_der_encoder_functions), - ENCODER("EC", "yes", "pem", "private", ec_priv_pem_encoder_functions), - ENCODER("EC", "yes", "pem", "public", ec_pub_pem_encoder_functions), - ENCODER("EC", "yes", "pem", "parameters", ec_param_pem_encoder_functions), + ENCODER("EC", "yes", "text", "private", + ec_priv_to_text_encoder_functions), + ENCODER("EC", "yes", "text", "public", + ec_pub_to_text_encoder_functions), + ENCODER("EC", "yes", "text", "parameters", + ec_param_to_text_encoder_functions), + ENCODER("EC", "yes", "der", "private", + ec_priv_to_der_encoder_functions), + ENCODER("EC", "yes", "der", "public", + ec_pub_to_der_encoder_functions), + ENCODER("EC", "yes", "der", "parameters", + ec_param_to_der_encoder_functions), + ENCODER("EC", "yes", "pem", "private", + ec_priv_to_pem_encoder_functions), + ENCODER("EC", "yes", "pem", "public", + ec_pub_to_pem_encoder_functions), + ENCODER("EC", "yes", "pem", "parameters", + ec_param_to_pem_encoder_functions), #endif diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info index 3e78849dfc..97e2264418 100644 --- a/providers/implementations/encode_decode/build.info +++ b/providers/implementations/encode_decode/build.info @@ -10,26 +10,12 @@ $DSA_GOAL=../../libimplementations.a $ECX_GOAL=../../libimplementations.a $EC_GOAL=../../libimplementations.a -SOURCE[$ENCODER_GOAL]=encoder_common.c decode_common.c +SOURCE[$ENCODER_GOAL]=endecoder_common.c SOURCE[$DECODER_GOAL]=decode_der2key.c decode_pem2der.c IF[{- !$disabled{dsa} -}] SOURCE[$DECODER_GOAL]=decode_ms2key.c ENDIF -SOURCE[$RSA_GOAL]=encoder_rsa.c encoder_rsa_priv.c encoder_rsa_pub.c -DEPEND[encoder_rsa.o]=../../common/include/prov/der_rsa.h - -IF[{- !$disabled{"dh"} || !$disabled{"dsa"} -}] - SOURCE[$FFC_GOAL]=encoder_ffc_params.c -ENDIF -IF[{- !$disabled{dh} -}] - SOURCE[$DH_GOAL]=encoder_dh.c encoder_dh_priv.c encoder_dh_pub.c encoder_dh_param.c -ENDIF -IF[{- !$disabled{dsa} -}] - SOURCE[$DSA_GOAL]=encoder_dsa.c encoder_dsa_priv.c encoder_dsa_pub.c encoder_dsa_param.c -ENDIF -IF[{- !$disabled{ec} -}] - SOURCE[$ECX_GOAL]=encoder_ecx.c encoder_ecx_priv.c encoder_ecx_pub.c - SOURCE[$EC_GOAL]=encoder_ec.c encoder_ec_priv.c encoder_ec_pub.c encoder_ec_param.c -ENDIF +SOURCE[$DECODER_GOAL]=encode_key2any.c encode_key2text.c +DEPEND[encode_key2any.o]=../../common/include/prov/der_rsa.h diff --git a/providers/implementations/encode_decode/decode_common.c b/providers/implementations/encode_decode/decode_common.c deleted file mode 100644 index 798d8f10b2..0000000000 --- a/providers/implementations/encode_decode/decode_common.c +++ /dev/null @@ -1,116 +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/err.h> -#include <openssl/buffer.h> -#include <openssl/pem.h> /* For public PEM and PVK functions */ -#include <openssl/pkcs12.h> -#include "internal/pem.h" /* For internal PVK and "blob" functions */ -#include "internal/cryptlib.h" -#include "internal/asn1.h" -#include "internal/passphrase.h" -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */ -#include "encoder_local.h" - -int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - unsigned char **data, long *len) -{ - BUF_MEM *mem = NULL; - BIO *in = bio_new_from_core_bio(provctx, cin); - int ok = (asn1_d2i_read_bio(in, &mem) >= 0); - - if (ok) { - *data = (unsigned char *)mem->data; - *len = (long)mem->length; - OPENSSL_free(mem); - } - BIO_free(in); - return ok; -} - -int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - char **pem_name, char **pem_header, - unsigned char **data, long *len) -{ - BIO *in = bio_new_from_core_bio(provctx, cin); - int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0); - - BIO_free(in); - return ok; -} - -#ifndef OPENSSL_NO_DSA -EVP_PKEY *ossl_prov_read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - int *ispub) -{ - BIO *in = bio_new_from_core_bio(provctx, cin); - EVP_PKEY *pkey = ossl_b2i_bio(in, ispub); - - BIO_free(in); - return pkey; -} - -# ifndef OPENSSL_NO_RC4 -EVP_PKEY *ossl_prov_read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) -{ - BIO *in = NULL; - EVP_PKEY *pkey = NULL; - struct ossl_passphrase_data_st pwdata; - - memset(&pwdata, 0, sizeof(pwdata)); - if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg)) - return NULL; - - in = bio_new_from_core_bio(provctx, cin); - pkey = b2i_PVK_bio(in, ossl_pw_pem_password, &pwdata); - BIO_free(in); - - return pkey; -} -# endif -#endif - -int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len, - unsigned char *input_der, long input_der_len, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) -{ - const unsigned char *derp; - X509_SIG *p8 = NULL; - int ok = 0; - - if (!ossl_assert(new_der != NULL && *new_der == NULL) - || !ossl_assert(new_der_len != NULL)) - return 0; - - derp = input_der; - if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) { - char pbuf[PEM_BUFSIZE]; - size_t plen = 0; - - if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) { - ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); - } else { - const X509_ALGOR *alg = NULL; - const ASN1_OCTET_STRING *oct = NULL; - int len = 0; - - X509_SIG_get0(p8, &alg, &oct); - if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length, - new_der, &len, 0) != NULL) - ok = 1; - *new_der_len = len; - } - } - X509_SIG_free(p8); - return ok; -} diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index b8b268217d..011f05803d 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -17,13 +17,71 @@ #include <openssl/core_names.h> #include <openssl/core_object.h> #include <openssl/crypto.h> +#include <openssl/err.h> #include <openssl/params.h> +#include <openssl/pem.h> /* PEM_BUFSIZE and public PEM functions */ +#include <openssl/pkcs12.h> #include <openssl/x509.h> +#include "internal/cryptlib.h" /* ossl_assert() */ +#include "internal/asn1.h" +#include "crypto/ecx.h" #include "prov/bio.h" #include "prov/implementations.h" -#include "encoder_local.h" +#include "prov/providercommonerr.h" +#include "endecoder_local.h" -static OSSL_FUNC_decoder_newctx_fn der2rsa_newctx; +static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, + unsigned char **data, long *len) +{ + BUF_MEM *mem = NULL; + BIO *in = bio_new_from_core_bio(provctx, cin); + int ok = (asn1_d2i_read_bio(in, &mem) >= 0); + + if (ok) { + *data = (unsigned char *)mem->data; + *len = (long)mem->length; + OPENSSL_free(mem); + } + BIO_free(in); + return ok; +} + +static int der_from_p8(unsigned char **new_der, long *new_der_len, + unsigned char *input_der, long input_der_len, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + const unsigned char *derp; + X509_SIG *p8 = NULL; + int ok = 0; + + if (!ossl_assert(new_der != NULL && *new_der == NULL) + || !ossl_assert(new_der_len != NULL)) + return 0; + + derp = input_der; + if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) { + char pbuf[PEM_BUFSIZE]; + size_t plen = 0; + + if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) { + ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); + } else { + const X509_ALGOR *alg = NULL; + const ASN1_OCTET_STRING *oct = NULL; + int len = 0; + + X509_SIG_get0(p8, &alg, &oct); + if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length, + new_der, &len, 0) != NULL) + ok = 1; + *new_der_len = len; + } + } + X509_SIG_free(p8); + return ok; +} + +/* ---------------------------------------------------------------------- */ static OSSL_FUNC_decoder_freectx_fn der2key_freectx; static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params; @@ -109,15 +167,14 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, void *key = NULL; int ok = 0; - if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len)) + if (!read_der(ctx->provctx, cin, &der, &der_len)) return 0; /* * Opportunistic attempt to decrypt. If it doesn't work, we try to * decode our input unencrypted. */ - if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len, - pw_cb, pw_cbarg)) { + 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; @@ -203,6 +260,7 @@ static int der2key_export_object(void *vctx, { EVP_PKEY_##KEYTYPE, KEYTYPEstr, 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) \ { \ return der2key_newctx(prov |