PEM_X509_INFO_read_bio_ex(): Generalize to allow parsing any type of private key

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14647)
This commit is contained in:
Dr. David von Oheimb 2021-03-22 16:23:24 +01:00 committed by Dr. David von Oheimb
parent c1fd710297
commit 4957d95208
4 changed files with 54 additions and 73 deletions

View File

@ -22,6 +22,7 @@
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include "crypto/evp.h"
#ifndef OPENSSL_NO_STDIO
STACK_OF(X509_INFO)
@ -54,7 +55,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
const char *propq)
{
X509_INFO *xi = NULL;
char *name = NULL, *header = NULL;
char *name = NULL, *header = NULL, *str;
void *pp;
unsigned char *data = NULL;
const unsigned char *p;
@ -90,22 +91,9 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
}
ERR_clear_last_mark();
start:
if ((strcmp(name, PEM_STRING_X509) == 0) ||
(strcmp(name, PEM_STRING_X509_OLD) == 0)) {
d2i = (D2I_OF(void)) d2i_X509;
if (xi->x509 != NULL) {
if (!sk_X509_INFO_push(ret, xi))
goto err;
if ((xi = X509_INFO_new()) == NULL)
goto err;
goto start;
}
xi->x509 = X509_new_ex(libctx, propq);
if (xi->x509 == NULL)
goto err;
pp = &(xi->x509);
} else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
d2i = (D2I_OF(void)) d2i_X509_AUX;
if (strcmp(name, PEM_STRING_X509) == 0
|| strcmp(name, PEM_STRING_X509_OLD) == 0
|| strcmp(name, PEM_STRING_X509_TRUSTED) == 0) {
if (xi->x509 != NULL) {
if (!sk_X509_INFO_push(ret, xi))
goto err;
@ -113,6 +101,10 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
goto err;
goto start;
}
if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0))
d2i = (D2I_OF(void)) d2i_X509_AUX;
else
d2i = (D2I_OF(void)) d2i_X509;
xi->x509 = X509_new_ex(libctx, propq);
if (xi->x509 == NULL)
goto err;
@ -127,8 +119,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
goto start;
}
pp = &(xi->crl);
} else if (strcmp(name, PEM_STRING_RSA) == 0) {
d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
} else if ((str = strstr(name, PEM_STRING_PKCS8INF)) != NULL) {
if (xi->x_pkey != NULL) {
if (!sk_X509_INFO_push(ret, xi))
goto err;
@ -136,65 +127,25 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
goto err;
goto start;
}
xi->enc_data = NULL;
xi->enc_len = 0;
xi->x_pkey = X509_PKEY_new();
if (xi->x_pkey == NULL)
goto err;
ptype = EVP_PKEY_RSA;
pp = &xi->x_pkey->dec_pkey;
if ((int)strlen(header) > 10) /* assume encrypted */
raw = 1;
} else
#ifndef OPENSSL_NO_DSA
if (strcmp(name, PEM_STRING_DSA) == 0) {
d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
if (xi->x_pkey != NULL) {
if (!sk_X509_INFO_push(ret, xi))
goto err;
if ((xi = X509_INFO_new()) == NULL)
goto err;
goto start;
if (str == name || strcmp(name, PEM_STRING_PKCS8) == 0) {
ptype = EVP_PKEY_NONE;
} else {
/* chop " PRIVATE KEY" */
*--str = '\0';
ptype = evp_pkey_name2type(name);
}
xi->enc_data = NULL;
xi->enc_len = 0;
d2i = (D2I_OF(void)) d2i_AutoPrivateKey;
xi->x_pkey = X509_PKEY_new();
if (xi->x_pkey == NULL)
goto err;
ptype = EVP_PKEY_DSA;
pp = &xi->x_pkey->dec_pkey;
if ((int)strlen(header) > 10) /* assume encrypted */
if ((int)strlen(header) > 10 /* assume encrypted */
|| strcmp(name, PEM_STRING_PKCS8) == 0)
raw = 1;
} else
#endif
#ifndef OPENSSL_NO_EC
if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
d2i = (D2I_OF(void)) d2i_ECPrivateKey;
if (xi->x_pkey != NULL) {
if (!sk_X509_INFO_push(ret, xi))
goto err;
if ((xi = X509_INFO_new()) == NULL)
goto err;
goto start;
}
xi->enc_data = NULL;
xi->enc_len = 0;
xi->x_pkey = X509_PKEY_new();
if (xi->x_pkey == NULL)
goto err;
ptype = EVP_PKEY_EC;
pp = &xi->x_pkey->dec_pkey;
if ((int)strlen(header) > 10) /* assume encrypted */
raw = 1;
} else
#endif
{
} else { /* unknown */
d2i = NULL;
pp = NULL;
}
@ -225,8 +176,6 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
xi->enc_len = (int)len;
data = NULL;
}
} else {
/* unknown */
}
OPENSSL_free(name);
name = NULL;

View File

@ -27,7 +27,7 @@ PEM_X509_INFO_read_ex() loads the B<X509_INFO> objects from a file I<fp>.
PEM_X509_INFO_read_bio_ex loads the B<X509_INFO> objects using a bio I<bp>.
Each of the loaded B<X509_INFO> objects can contain a CRL, a certificate,
and/or an RSA/DSA/EC private key.
and/or a private key.
The elements are read sequentially, and as far as they are of different type than
the elements read before, they are combined into the same B<X509_INFO> object.

View File

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIuH8X1xWl9ygCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCw27UHDuBtxWa928AXEEb1BIIE
0A/aH/nMGoifA4TKpLg1SobskugzWV7+N2qh3j9LZrz6GxB9jR64JBx8+eKBu5lv
VeMp/cIuGZscJ56QFZ01tTEyIiP1eeD68eQol2n7KEwk9DKkR2QbQuLDOaR4voqM
rm02uehLnNPJ7d81CrgfqIRi5OF4cWVV20jN7pQMxn8KqW4OYPdOrV1i6mTnsbNz
M5hL9YMud4wppWwA93MLD4TGvQBQSTvreYtLNy1atq1uK4k2KZh2tw/CTNiCo47R
N6Ft+CDJblikodpj/a6ZPJ84qBMonTbc7IMvkeWP0mnzA25ohOW7RfhgWzz/mfx3
/ypX8xqLd8JzmdRFOcc5MFdVcYPmgFzFVtEJ0bBZx6WCW+6OszLkt/7p7raRKirA
/zJJSBmEvQKvwtZ6I/rG6SqMFiTseRuWq0sXa1NX2zlH9y+g68K+7Bt5816l93WD
p0GQgWxXV2J+QJ3fGvxMdQG7qmGWx6dc6yZkFw9e94sTHH74fShTv53OekCgWg2B
58pFBTK9NGtiG5LawtDKMqlYcSKvfqjvKwDokQS104DwM+om0QBLTH+RRxh05jYv
2hx1uwSXoo8oO+AYaYsEQE8z7mYxQr5Ea1gKbtyYPE0Eo5rrH9fYzXN8A1LH7wbL
ywQIZq/lthuJGarTPCFjoHrPW9O+FiQBLsn5Ej2VVm2MQpS3v6m7SnHTWBaPZvkq
GEGw/MZiwkzyULsg7zRKfnNhYBfxdg+gmwIR6x1e4vT6hAFjZbvn1eOlFTLqIBpE
XQCqxaITtW6bCEhvl/c0AKkAWM39XEs/ff1giYza+6SLgLQObHApp+Q/Hk3PaUDq
Wnm/5w8IyQcGDAik0f6JqbQ+licBk5lHlOifO0GFKqePlKLY/Mvx9al2UflzOydG
u9BpXx8sLooLuyycXFhgpZZLp19+79KgPm+ZrXKlKKwTDQwuB+eGxr2wKWCbJb2y
gmnBCtml5apTQx+l630GldMjkhwxOSZJoXy6XKQew85L/J9Jknta3bjGbyL2lEeW
/gfT+L6WrmG3Hf4xGhpkkx6UITzujJbE2/YyxJ+sXlRuYd4ld0Hfn6Ihsajknj8G
jvLb77FvgNndf5SXlqU3sMGcOPizQkMr/AmtHPzBLT8O6OxpeAOWzG3jOvznRsmZ
27nmW4cM/6t/86PvnAssPETFcrC3GqFYWnzdVaWunCz5zn4xIot3633VGR1lbxX4
kTQLBzgBjKuajgVim5Q4obfaqnJEvHkbJaAFJg0y6uId2RIzYo5/onHrVOQR5ulB
qyR8YJjWu3pyq8t5q9Iw3L+pWDOh4AH7/ay0IBu/qxapvybqEXyol3kAJIsY0AKZ
Y5dPA4duWjW0MHNDgliAssKr2t3CTALU9nrBVX1fEPR4Y05JZ9f4OIueu/IGdDIE
snLdqtkY0sOTma9FhKDv1RwsumT/UfOqUJ3ZSJCaKgE/RnzS3YN+j5BYv788micZ
S9nl5KX+q/VSVXxial0nxkGiqs73mASF5JP4iarRihSntGMvn4PPB7Oid5SVLrqk
JFFy7pjL8xuERx0hlShUl2q8/C3DSi0u+QkIhNrUBKZRADzNDkJcfWmKwbhq7HPp
ghzvaDrFtH/4o8t7kd+TVdKjnS0cna43Sj94w3J5/y5Y
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -12,7 +12,7 @@ use OpenSSL::Test::Utils;
setup("test_x509_check_cert_pkey");
plan tests => 9;
plan tests => 11;
sub src_file {
return srctop_file("test", "certs", shift);
@ -60,4 +60,6 @@ ok(run(test(["x509_check_cert_pkey_test",
src_file("wrongkey.pem"), "req", "failed"])));
test_PEM_X509_INFO_read("root-cert.pem", "1");
test_PEM_X509_INFO_read("root-key.pem", "1");
test_PEM_X509_INFO_read("key-pass-12345.pem", "1");
test_PEM_X509_INFO_read("cyrillic_crl.utf8", "1");