From cce8ae99274619daa9c765490757e771e9d04a64 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Sat, 19 Nov 2022 23:43:27 -0600 Subject: [PATCH] hx509: Pass PKCS#8 keys to lower layers OpenSSL's d2i_ECPrivateKey() is deprecated, so we have to use d2i_PrivateKey(), but d2i_PrivateKey() wants the whole PKCS#8 blob so it can know what kind of key it is. So we need to let the hx509 EC layer get that blob. The internal APIs need some refactoring, so for now we use a hack where we try to parse the private key with and without the PKCS#8 wrapper. --- lib/hx509/collector.c | 10 +++++++++ lib/hx509/crypto.c | 52 ++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/lib/hx509/collector.c b/lib/hx509/collector.c index 7b4680981..f1423aced 100644 --- a/lib/hx509/collector.c +++ b/lib/hx509/collector.c @@ -147,6 +147,16 @@ _hx509_collector_private_key_add(hx509_context context, key_data->data, key_data->length, HX509_KEY_FORMAT_DER, &key->private_key); + if (ret && localKeyId) { + int ret2; + + ret2 = hx509_parse_private_key(context, alg, + localKeyId->data, localKeyId->length, + HX509_KEY_FORMAT_PKCS8, + &key->private_key); + if (ret2 == 0) + ret = 0; + } if (ret) goto out; } diff --git a/lib/hx509/crypto.c b/lib/hx509/crypto.c index 8d368ed9c..05f694b41 100644 --- a/lib/hx509/crypto.c +++ b/lib/hx509/crypto.c @@ -1304,34 +1304,6 @@ hx509_parse_private_key(hx509_context context, *private_key = NULL; - if (format == HX509_KEY_FORMAT_PKCS8) { - PKCS8PrivateKeyInfo ki; - hx509_private_key key; - - ret = decode_PKCS8PrivateKeyInfo(data, len, &ki, NULL); - if (ret) { - hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, - "Failed to parse PKCS#8-encoded private " - "key"); - return HX509_PARSING_KEY_FAILED; - } - - /* Re-enter to parse DER-encoded key from PKCS#8 envelope */ - ret = hx509_parse_private_key(context, &ki.privateKeyAlgorithm, - ki.privateKey.data, ki.privateKey.length, - HX509_KEY_FORMAT_DER, &key); - free_PKCS8PrivateKeyInfo(&ki); - if (ret) { - hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, - "Failed to parse RSA key from PKCS#8 " - "envelope"); - return HX509_PARSING_KEY_FAILED; - } - - *private_key = key; - return ret; - } - ops = hx509_find_private_alg(&keyai->algorithm); if (ops == NULL) { hx509_clear_error_string(context); @@ -1348,6 +1320,30 @@ hx509_parse_private_key(hx509_context context, if (ret) hx509_private_key_free(private_key); + if (ret && format == HX509_KEY_FORMAT_PKCS8) { + PKCS8PrivateKeyInfo ki; + hx509_private_key key; + + /* Re-enter to try parsing the DER-encoded key from PKCS#8 envelope */ + ret = decode_PKCS8PrivateKeyInfo(data, len, &ki, NULL); + if (ret) { + hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, + "Failed to parse PKCS#8-encoded private " + "key"); + return HX509_PARSING_KEY_FAILED; + } + ret = hx509_parse_private_key(context, &ki.privateKeyAlgorithm, + ki.privateKey.data, ki.privateKey.length, + HX509_KEY_FORMAT_DER, &key); + free_PKCS8PrivateKeyInfo(&ki); + if (ret) { + hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED, + "Failed to parse RSA key from PKCS#8 " + "envelope"); + return HX509_PARSING_KEY_FAILED; + } + *private_key = key; + } return ret; }