summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-03-22 16:23:24 +0100
committerDr. David von Oheimb <dev@ddvo.net>2021-04-08 15:18:58 +0200
commit4957d9520822f79abbb6c3cd8fe0b79837c2e64f (patch)
tree50415ae6eaedbb4a97c6fa245c019be136dec73f
parentc1fd710297a21336ec0410fe86784c322945b805 (diff)
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)
-rw-r--r--crypto/pem/pem_info.c91
-rw-r--r--doc/man3/PEM_X509_INFO_read_bio_ex.pod2
-rw-r--r--test/certs/key-pass-12345.pem30
-rw-r--r--test/recipes/60-test_x509_check_cert_pkey.t4
4 files changed, 54 insertions, 73 deletions
diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c
index 2714009103..cd75a95e2a 100644
--- a/crypto/pem/pem_info.c
+++ b/crypto/pem/pem_info.c
@@ -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,30 +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;
- 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_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;
+ } else if ((str = strstr(name, PEM_STRING_PKCS8INF)) != NULL) {
if (xi->x_pkey != NULL) {
if (!sk_X509_INFO_push(ret, xi))
goto err;
@@ -158,43 +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_DSA;
- pp = &xi->x_pkey->dec_pkey;
- if ((int)strlen(header) > 10) /* assume encrypted */
- 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;
+ 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_EC;
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
- {
+ } 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;
diff --git a/doc/man3/PEM_X509_INFO_read_bio_ex.pod b/doc/man3/PEM_X509_INFO_read_bio_ex.pod
index f0add6537f..cdff0561e9 100644
--- a/doc/man3/PEM_X509_INFO_read_bio_ex.pod
+++ b/doc/man3/PEM_X509_INFO_read_bio_ex.pod
@@ -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.
diff --git a/test/certs/key-pass-12345.pem b/test/certs/key-pass-12345.pem
new file mode 100644
index 0000000000..e1aabfeb79
--- /dev/null
+++ b/test/certs/key-pass-12345.pem
@@ -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-----
diff --git a/test/recipes/60-test_x509_check_cert_pkey.t b/test/recipes/60-test_x509_check_cert_pkey.t
index 2c0f2e4009..d7c83acb80 100644
--- a/test/recipes/60-test_x509_check_cert_pkey.t
+++ b/test/recipes/60-test_x509_check_cert_pkey.t
@@ -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");