diff options
author | Richard Levitte <levitte@openssl.org> | 2020-10-02 13:56:54 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-10-04 12:58:41 +0200 |
commit | ecadfdadde491572b0bdf3c5a95e7a6a004585c6 (patch) | |
tree | 5598e1c5a8297d2499517b7ae84f1ebed3a40d75 /providers/implementations/encode_decode | |
parent | 4232a9e57f48276974a8891e58db9b06b5db696f (diff) |
DECODER: Handle abstract object data type
The PEM->DER decoder passes the data type of its contents, something
that decoder_process() ignored.
On the other hand, the PEM->DER decoder passed nonsense.
Both issues are fixed here.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13060)
Diffstat (limited to 'providers/implementations/encode_decode')
-rw-r--r-- | providers/implementations/encode_decode/decode_pem2der.c | 62 |
1 files changed, 56 insertions, 6 deletions
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c index 99ca7e8210..9ddc0ae3bb 100644 --- a/providers/implementations/encode_decode/decode_pem2der.c +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -21,6 +21,7 @@ #include <openssl/err.h> #include <openssl/params.h> #include <openssl/pem.h> +#include "internal/nelem.h" #include "prov/bio.h" #include "prov/implementations.h" #include "prov/providercommonerr.h" @@ -109,8 +110,27 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, OSSL_CALLBACK *data_cb, void *data_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { + /* Strings to peal off the pem name */ + static const char *pealable_pem_name_endings[] = { + /* + * These entries should be in longest to shortest order to avoid + * mixups. + */ + "ENCRYPTED PRIVATE KEY", + "PRIVATE KEY", + "PUBLIC KEY", + "PARAMETERS" + + /* + * Libcrypto currently only supports decoding keys with provider side + * decoders, so we don't try to peal any other PEM name. That's an + * exercise for when libcrypto starts to treat other types of objects + * via providers. + */ + }; struct pem2der_ctx_st *ctx = vctx; char *pem_name = NULL, *pem_header = NULL; + size_t pem_name_len, i; unsigned char *der = NULL; long der_len = 0; int ok = 0; @@ -137,16 +157,46 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, goto end; } + /* + * Peal off certain strings from the end of |pem_name|, as they serve + * no further purpose. + */ + for (i = 0, pem_name_len = strlen(pem_name); + i < OSSL_NELEM(pealable_pem_name_endings); + i++) { + size_t peal_len = strlen(pealable_pem_name_endings[i]); + size_t pem_name_offset; + + if (peal_len <= pem_name_len) { + pem_name_offset = pem_name_len - peal_len; + if (strcmp(pem_name + pem_name_offset, + pealable_pem_name_endings[i]) == 0) { + + do { + pem_name[pem_name_offset] = '\0'; + } while (pem_name_offset > 0 + && pem_name[--pem_name_offset] == ' '); + + if (pem_name[0] == '\0') { + OPENSSL_free(pem_name); + pem_name = NULL; + } + break; + } + } + } + { - OSSL_PARAM params[3]; + OSSL_PARAM params[3], *p = params; - params[0] = - OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, - pem_name, 0); - params[1] = + if (pem_name != NULL) + *p++ = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + pem_name, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, der, der_len); - params[2] = OSSL_PARAM_construct_end(); + *p = OSSL_PARAM_construct_end(); ok = data_cb(params, data_cbarg); } |