diff options
author | Richard Levitte <levitte@openssl.org> | 2020-12-10 14:00:05 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-12-17 12:02:08 +0100 |
commit | e77c13f8b73ff937819d6551ddd616fe01b989d0 (patch) | |
tree | 432c7d3674821c90d3186faf1a5b95d550f0ff7a /crypto/pem/pvkfmt.c | |
parent | DECODER EVP_PKEY: Don't store all the EVP_KEYMGMTs (diff) | |
download | openssl-e77c13f8b73ff937819d6551ddd616fe01b989d0.tar.xz openssl-e77c13f8b73ff937819d6551ddd616fe01b989d0.zip |
MSBLOB & PVK: Make it possible to write EVP_PKEYs with provided internal key
So far, the MSBLOB and PVK writers could only handle EVP_PKEYs with
legacy internal keys.
Specially to be able to compile the loader_attic engine, we use the C
macro OPENSSL_NO_PROVIDER_CODE to avoid building the provider specific
things when we don't need them. The alternative is to suck half of
crypto/evp/ into loader_attic, and that's just not feasible.
Fixes #13503
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13661)
Diffstat (limited to 'crypto/pem/pvkfmt.c')
-rw-r--r-- | crypto/pem/pvkfmt.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index b0aa76b3f5..de673be005 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -18,13 +18,14 @@ */ #include "internal/deprecated.h" -#include "internal/cryptlib.h" #include <openssl/pem.h> -#include "crypto/pem.h" #include <openssl/rand.h> #include <openssl/bn.h> #include <openssl/dsa.h> #include <openssl/rsa.h> +#include "internal/cryptlib.h" +#include "crypto/pem.h" +#include "crypto/evp.h" /* * Utility function: read a DWORD (4 byte unsigned integer) in little endian @@ -461,9 +462,19 @@ static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) { unsigned char *p; unsigned int bitlen = 0, magic = 0, keyalg = 0; - int outlen, noinc = 0; - int pktype = EVP_PKEY_id(pk); + int outlen = -1, noinc = 0; + int pktype; +#ifndef OPENSSL_NO_PROVIDER_CODE + EVP_PKEY *pkcopy = NULL; + + if (evp_pkey_is_provided(pk)) { + if (!evp_pkey_copy_downgraded(&pkcopy, pk)) + goto end; + pk = pkcopy; + } +#endif + pktype = EVP_PKEY_id(pk); if (pktype == EVP_PKEY_RSA) { bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic); keyalg = MS_KEYALG_RSA_KEYX; @@ -473,18 +484,20 @@ static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) keyalg = MS_KEYALG_DSS_SIGN; #endif } - if (bitlen == 0) - return -1; + if (bitlen == 0) { + goto end; + } outlen = 16 + blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); if (out == NULL) - return outlen; + goto end; if (*out) p = *out; else { if ((p = OPENSSL_malloc(outlen)) == NULL) { ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); - return -1; + outlen = -1; + goto end; } *out = p; noinc = 1; @@ -507,6 +520,10 @@ static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) #endif if (!noinc) *out += outlen; + end: +#ifndef OPENSSL_NO_PROVIDER_CODE + EVP_PKEY_free(pkcopy); +#endif return outlen; } |