[openssl] master update

dev at ddvo.net dev at ddvo.net
Thu Apr 8 13:19:36 UTC 2021


The branch master has been updated
       via  6d9e045ef724df0ddc8c8f66dcfdff4f8ba0bc03 (commit)
       via  4957d9520822f79abbb6c3cd8fe0b79837c2e64f (commit)
       via  c1fd710297a21336ec0410fe86784c322945b805 (commit)
       via  321ac1f2973c01f4a4a2719e4400c26ff01c3231 (commit)
      from  987a66a6fcf3dffa987896551cb94de66f38cdea (commit)


- Log -----------------------------------------------------------------
commit 6d9e045ef724df0ddc8c8f66dcfdff4f8ba0bc03
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu Mar 25 16:20:48 2021 +0100

    d2i_PrivateKey_decoder(): Fix premature exit on unsuccessful OSSL_DECODER_CTX_new_for_pkey()
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14647)

commit 4957d9520822f79abbb6c3cd8fe0b79837c2e64f
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Mar 22 16:23:24 2021 +0100

    PEM_X509_INFO_read_bio_ex(): Generalize to allow parsing any type of private key
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14647)

commit c1fd710297a21336ec0410fe86784c322945b805
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Mar 22 14:16:56 2021 +0100

    d2i_PrivateKey{,_ex}() and PEM_X509_INFO_read_bio_ex(): Fix handling of RSA/DSA/EC private key
    
    This is needed to correct d2i_PrivateKey() after it was changed by commit 576892d78f80cf9a.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14647)

commit 321ac1f2973c01f4a4a2719e4400c26ff01c3231
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Sat Mar 20 23:32:15 2021 +0100

    PEM_X509_INFO_read,{_bio}_ex(): Complete documentation in PEM_X509_INFO_read_bio_ex.pod
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14647)

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/d2i_pr.c                               | 21 +++--
 crypto/pem/pem_info.c                              | 96 ++++++----------------
 doc/man3/PEM_X509_INFO_read_bio_ex.pod             | 30 ++++---
 doc/man3/d2i_PrivateKey.pod                        | 13 ++-
 test/certs/ec_privkey_with_chain.pem               | 74 +++++++++++++++++
 .../key-pass-12345.pem}                            |  0
 test/recipes/60-test_x509_check_cert_pkey.t        | 47 +++++++----
 test/x509_check_cert_pkey_test.c                   | 42 +++++++++-
 8 files changed, 210 insertions(+), 113 deletions(-)
 create mode 100644 test/certs/ec_privkey_with_chain.pem
 copy test/{recipes/80-test_cmp_http_data/Mock/new_pass_12345.key => certs/key-pass-12345.pem} (100%)

diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index fb0ae08356..94bd341d58 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -29,7 +29,7 @@ d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
 {
     OSSL_DECODER_CTX *dctx = NULL;
     size_t len = length;
-    EVP_PKEY *pkey = NULL;
+    EVP_PKEY *pkey = NULL, *bak_a = NULL;
     EVP_PKEY **ppkey = &pkey;
     const char *key_name = NULL;
     const char *input_structures[] = { "type-specific", "pkcs8", NULL };
@@ -40,24 +40,29 @@ d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
         if (key_name == NULL)
             return NULL;
     }
-    if (a != NULL && *a != NULL)
-        ppkey = a;
 
     for (i = 0;  i < (int)OSSL_NELEM(input_structures); ++i) {
         const unsigned char *p = *pp;
 
+        if (a != NULL && (bak_a = *a) != NULL)
+            ppkey = a;
         dctx = OSSL_DECODER_CTX_new_for_pkey(ppkey, "DER",
                                              input_structures[i], key_name,
                                              EVP_PKEY_KEYPAIR, libctx, propq);
+        if (a != NULL)
+            *a = bak_a;
         if (dctx == NULL)
-            return NULL;
+            continue;
 
         ret = OSSL_DECODER_from_data(dctx, pp, &len);
         OSSL_DECODER_CTX_free(dctx);
         if (ret) {
             if (*ppkey != NULL
-                && evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY))
+                && evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) {
+                if (a != NULL)
+                    *a = *ppkey;
                 return *ppkey;
+            }
             *pp = p;
             goto err;
         }
@@ -76,7 +81,7 @@ d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp,
     EVP_PKEY *ret;
     const unsigned char *p = *pp;
 
-    if ((a == NULL) || (*a == NULL)) {
+    if (a == NULL || *a == NULL) {
         if ((ret = EVP_PKEY_new()) == NULL) {
             ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
             return NULL;
@@ -127,7 +132,7 @@ d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp,
     }
     *pp = p;
     if (a != NULL)
-        (*a) = ret;
+        *a = ret;
     return ret;
  err:
     if (a == NULL || *a != ret)
@@ -195,7 +200,7 @@ static EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a,
         if (ret == NULL)
             return NULL;
         *pp = p;
-        if (a) {
+        if (a != NULL) {
             *a = ret;
         }
         return ret;
diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c
index 54e29ab41f..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;
         }
@@ -209,7 +160,8 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
                     goto err;
                 p = data;
                 if (ptype) {
-                    if (!d2i_PrivateKey(ptype, pp, &p, len)) {
+                    if (d2i_PrivateKey_ex(ptype, pp, &p, len,
+                                          libctx, propq) == NULL) {
                         ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB);
                         goto err;
                     }
@@ -217,15 +169,13 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk,
                     ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB);
                     goto err;
                 }
-            } else {            /* encrypted RSA data */
+            } else {            /* encrypted key data */
                 if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
                     goto err;
                 xi->enc_data = (char *)data;
                 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 ceab8dbd68..cdff0561e9 100644
--- a/doc/man3/PEM_X509_INFO_read_bio_ex.pod
+++ b/doc/man3/PEM_X509_INFO_read_bio_ex.pod
@@ -3,8 +3,7 @@
 =head1 NAME
 
 PEM_X509_INFO_read_bio_ex, PEM_X509_INFO_read_ex
-- read a PEM-encoded data structure from a bio into one or more B<X509_INFO>
-object's
+- read PEM-encoded data structures into one or more B<X509_INFO> objects
 
 =head1 SYNOPSIS
 
@@ -23,17 +22,27 @@ object's
 
 =head1 DESCRIPTION
 
-The loaded B<X509_INFO> object's can contain a CRL, a certificate and a
-corresponding private key.
-
 PEM_X509_INFO_read_ex() loads the B<X509_INFO> objects from a file I<fp>.
-The library context I<libctx> and property query <propq> are used for fetching
-algorithms from providers.
 
-PEM_X509_INFO_read_bio_ex loads the B<X509_INFO> objects using a bio
-I<bp>. The library context I<libctx> and property query <propq> are used for
-fetching algorithms from providers.
+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 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.
+The idea behind this is that if, for instance, a certificate is followed by
+a private key, the private key is supposed to correspond to the certificate.
 
+If the input stack I<sk> is NULL a new stack is allocated,
+else the given stack is extended.
+
+The optional I<cb> and I<u> parameters can be used for providing a pass phrase
+needed for decrypting encrypted PEM structures (normally only private keys).
+See L<PEM_read_bio_PrivateKey(3)> and L<passphrase-encoding(7)> for details.
+
+The library context I<libctx> and property query <propq> are used for fetching
+algorithms from providers.
 
 =head1 RETURN VALUES
 
@@ -43,6 +52,7 @@ a stack of B<X509_INFO> objects or NULL on failure.
 =head1 SEE ALSO
 
 L<PEM_read_bio_ex(3)>,
+L<PEM_read_bio_PrivateKey(3)>,
 L<passphrase-encoding(7)>
 
 =head1 HISTORY
diff --git a/doc/man3/d2i_PrivateKey.pod b/doc/man3/d2i_PrivateKey.pod
index 4e918f14c6..c28aae817e 100644
--- a/doc/man3/d2i_PrivateKey.pod
+++ b/doc/man3/d2i_PrivateKey.pod
@@ -50,13 +50,16 @@ i2d_PrivateKey_fp
 =head1 DESCRIPTION
 
 d2i_PrivateKey_ex() decodes a private key using algorithm I<type>. It attempts
-to use any key specific format or PKCS#8 unencrypted PrivateKeyInfo format. The
-I<type> parameter should be a public key algorithm constant such as
+to use any key-specific format or PKCS#8 unencrypted PrivateKeyInfo format.
+The I<type> parameter should be a public key algorithm constant such as
 B<EVP_PKEY_RSA>. An error occurs if the decoded key does not match I<type>. Some
 private key decoding implementations may use cryptographic algorithms (for
 example to automatically derive the public key if it is not explicitly
 included in the encoding). In this case the supplied library context I<libctx>
 and property query string I<propq> are used.
+If successful and the I<a> parameter is not NULL the function assigns the
+returned B<EVP_PKEY> structure pointer to I<*a>, overwriting any previous value.
+
 d2i_PrivateKey() does the same as d2i_PrivateKey_ex() except that the default
 library context and property query string are used.
 d2i_PublicKey() does the same for public keys.
@@ -87,10 +90,6 @@ All these functions use DER format and unencrypted keys. Applications wishing
 to encrypt or decrypt private keys should use other functions such as
 d2i_PKCS8PrivateKey() instead.
 
-If the I<*a> is not NULL when calling d2i_PrivateKey() or d2i_AutoPrivateKey()
-(i.e. an existing structure is being reused) and the key format is PKCS#8
-then I<*a> will be freed and replaced on a successful call.
-
 To decode a key with type B<EVP_PKEY_EC>, d2i_PublicKey() requires I<*a> to be
 a non-NULL EVP_PKEY structure assigned an EC_KEY structure referencing the proper
 EC_GROUP.
@@ -100,7 +99,7 @@ EC_GROUP.
 The d2i_PrivateKey_ex(), d2i_PrivateKey(), d2i_AutoPrivateKey_ex(),
 d2i_AutoPrivateKey(), d2i_PrivateKey_ex_bio(), d2i_PrivateKey_bio(),
 d2i_PrivateKey_ex_fp(), d2i_PrivateKey_fp(), d2i_PublicKey(), d2i_KeyParams()
-and d2i_KeyParams_bio() functions return a valid B<EVP_KEY> structure or B<NULL>
+and d2i_KeyParams_bio() functions return a valid B<EVP_PKEY> structure or NULL
 if an error occurs. The error code can be obtained by calling
 L<ERR_get_error(3)>.
 
diff --git a/test/certs/ec_privkey_with_chain.pem b/test/certs/ec_privkey_with_chain.pem
new file mode 100644
index 0000000000..fcdf42a121
--- /dev/null
+++ b/test/certs/ec_privkey_with_chain.pem
@@ -0,0 +1,74 @@
+Private Key for CN=Ca-ENROLLMENT-INTERMEDIATE-3
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIFGgYhBJYVKeQgTP0hsIv3NGTcG1+dooIFdRbEbCWrUvoAoGCCqGSM49
+AwEHoUQDQgAEYJfmnfC2iI6xjUarHNOY5TbNFD8MZVdb1PszPdbeuGs7hgiEcSWI
+hRjawFslN3XiubZeMPtN5nX8vudvtnNYVA==
+-----END EC PRIVATE KEY-----
+
+Subject: CN=Ca-ENROLLMENT-INTERMEDIATE-3
+Issuer: CN=Ca-ENROLLMENT-INTERMEDIATE-2
+Valid from Thu Sep 03 10:45:37 CEST 2020 to Sun Sep 01 10:45:37 CEST 2030
+Serial: 1599122797485
+-----BEGIN CERTIFICATE-----
+MIIB3zCCAYWgAwIBAgIGAXRTJXOtMAoGCCqGSM49BAMCMCcxJTAjBgNVBAMMHENh
+LUVOUk9MTE1FTlQtSU5URVJNRURJQVRFLTIwHhcNMjAwOTAzMDg0NTM3WhcNMzAw
+OTAxMDg0NTM3WjAnMSUwIwYDVQQDDBxDYS1FTlJPTExNRU5ULUlOVEVSTUVESUFU
+RS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYJfmnfC2iI6xjUarHNOY5TbN
+FD8MZVdb1PszPdbeuGs7hgiEcSWIhRjawFslN3XiubZeMPtN5nX8vudvtnNYVKOB
+nDCBmTAdBgNVHQ4EFgQUpdEIxYuP40cHdbcVTKRsT5/1PEMwVAYDVR0jBE0wS4AU
+TfcTbSV0o6Zwb+Rg0fvscn3R97WhK6QpMCcxJTAjBgNVBAMMHENhLUVOUk9MTE1F
+TlQtSU5URVJNRURJQVRFLTGCBgF0UyVzpDASBgNVHRMBAf8ECDAGAQH/AgECMA4G
+A1UdDwEB/wQEAwIBhjAKBggqhkjOPQQDAgNIADBFAiEAmIyD1fuTtMTuJwSccOg2
+jR+7HX67yTx1ozZOOrAsdBACIAo14mDvZYrFUke3r69690gCbiNUEQgbhIwCLYTQ
+2qbo
+-----END CERTIFICATE-----
+
+Subject: CN=Ca-ENROLLMENT-INTERMEDIATE-2
+Issuer: CN=Ca-ENROLLMENT-INTERMEDIATE-1
+Valid from Thu Sep 03 10:45:37 CEST 2020 to Sun Sep 01 10:45:37 CEST 2030
+Serial: 1599122797476
+-----BEGIN CERTIFICATE-----
+MIIB1jCCAXugAwIBAgIGAXRTJXOkMAoGCCqGSM49BAMCMCcxJTAjBgNVBAMMHENh
+LUVOUk9MTE1FTlQtSU5URVJNRURJQVRFLTEwHhcNMjAwOTAzMDg0NTM3WhcNMzAw
+OTAxMDg0NTM3WjAnMSUwIwYDVQQDDBxDYS1FTlJPTExNRU5ULUlOVEVSTUVESUFU
+RS0yMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEU4USFKQ1laHIiT1hC+ynawpl
+GFrEqt51RroMKIJclV+y+V8PQIAOAIMIDvpuxmDsnLr/I1QZO5Ui8pZdX379F6OB
+kjCBjzAdBgNVHQ4EFgQUTfcTbSV0o6Zwb+Rg0fvscn3R97UwSgYDVR0jBEMwQYAU
+HSCEFJcZjBVN6QtcmyGcFap0KR2hIaQfMB0xGzAZBgNVBAMMEkNhLUVOUk9MTE1F
+TlQtUk9PVIIGAXRTJXOfMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQD
+AgGGMAoGCCqGSM49BAMCA0kAMEYCIQC8F6GxJoW9XiD8m/rEECipJntU3iVNstHk
+Mdyx/wWvEAIhAIbw3IddLmt4dt1ce+sweFzrYSuGMH3LVSoIs6XhRqHx
+-----END CERTIFICATE-----
+
+Subject: CN=Ca-ENROLLMENT-INTERMEDIATE-1
+Issuer: CN=Ca-ENROLLMENT-ROOT
+Valid from Thu Sep 03 10:45:37 CEST 2020 to Sun Sep 01 10:45:37 CEST 2030
+Serial: 1599122797471
+-----BEGIN CERTIFICATE-----
+MIIByjCCAXGgAwIBAgIGAXRTJXOfMAoGCCqGSM49BAMCMB0xGzAZBgNVBAMMEkNh
+LUVOUk9MTE1FTlQtUk9PVDAeFw0yMDA5MDMwODQ1MzdaFw0zMDA5MDEwODQ1Mzda
+MCcxJTAjBgNVBAMMHENhLUVOUk9MTE1FTlQtSU5URVJNRURJQVRFLTEwWTATBgcq
+hkjOPQIBBggqhkjOPQMBBwNCAAR9uWgfHScQFcB87LaQKvSFPhngP4hHIsFdh5cY
+7ji2HYNfrkl2uWLKJfMiOFT06c1byplGzyj0ju8VWNV5Tee7o4GSMIGPMB0GA1Ud
+DgQWBBQdIIQUlxmMFU3pC1ybIZwVqnQpHTBKBgNVHSMEQzBBgBScYjWnQ+g/rclT
+YjwpMptoEfes3KEhpB8wHTEbMBkGA1UEAwwSQ2EtRU5ST0xMTUVOVC1ST09UggYB
+dFMlc5owEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZI
+zj0EAwIDRwAwRAIgRXLkNZAXLbhCyyL4614DuSm++fJ90A9JPU/uVpivz+MCIGlR
+G8F6eiU7ZeKPr/JON1BxLRXBZyI+Pfidj06Zvfvx
+-----END CERTIFICATE-----
+
+Subject: CN=Ca-ENROLLMENT-ROOT
+Issuer: CN=Ca-ENROLLMENT-ROOT
+Valid from Thu Sep 03 10:45:37 CEST 2020 to Sun Sep 01 10:45:37 CEST 2030
+Serial: 1599122797466
+-----BEGIN CERTIFICATE-----
+MIIBczCCARmgAwIBAgIGAXRTJXOaMAoGCCqGSM49BAMCMB0xGzAZBgNVBAMMEkNh
+LUVOUk9MTE1FTlQtUk9PVDAeFw0yMDA5MDMwODQ1MzdaFw0zMDA5MDEwODQ1Mzda
+MB0xGzAZBgNVBAMMEkNhLUVOUk9MTE1FTlQtUk9PVDBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABJd2nkxUVJqZ0NkEloOc3I7atQvkYmHg7UAOXp/QtwusVXfgG5lZ
+5qLayDuxlQNgcBDMilKBMnB2SNT+/IcQwEyjRTBDMB0GA1UdDgQWBBScYjWnQ+g/
+rclTYjwpMptoEfes3DASBgNVHRMBAf8ECDAGAQH/AgEKMA4GA1UdDwEB/wQEAwIB
+hjAKBggqhkjOPQQDAgNIADBFAiEAqGN70wgX6B1KU++k2inz04EPRTRqk5KLxHaW
+1jBXCbwCIGTNjmSi5J2mp+RL5UCP0ji41uPtwENC4mX4hJ+pOMIa
+-----END CERTIFICATE-----
+
diff --git a/test/recipes/80-test_cmp_http_data/Mock/new_pass_12345.key b/test/certs/key-pass-12345.pem
similarity index 100%
copy from test/recipes/80-test_cmp_http_data/Mock/new_pass_12345.key
copy to test/certs/key-pass-12345.pem
diff --git a/test/recipes/60-test_x509_check_cert_pkey.t b/test/recipes/60-test_x509_check_cert_pkey.t
index b6011ef764..d7c83acb80 100644
--- a/test/recipes/60-test_x509_check_cert_pkey.t
+++ b/test/recipes/60-test_x509_check_cert_pkey.t
@@ -12,35 +12,54 @@ use OpenSSL::Test::Utils;
 
 setup("test_x509_check_cert_pkey");
 
-plan tests => 6;
+plan tests => 11;
+
+sub src_file {
+    return srctop_file("test", "certs", shift);
+}
+
+sub test_PEM_X509_INFO_read {
+    my $file = shift;
+    my $num = shift;
+    ok(run(test(["x509_check_cert_pkey_test", src_file($file), $num])),
+        "test_PEM_X509_INFO_read $file");
+}
 
 # rsa
 ok(run(test(["x509_check_cert_pkey_test",
-             srctop_file("test", "certs", "servercert.pem"),
-             srctop_file("test", "certs", "serverkey.pem"), "cert", "ok"])));
+             src_file("servercert.pem"),
+             src_file("serverkey.pem"), "cert", "ok"])));
 # mismatched rsa
 ok(run(test(["x509_check_cert_pkey_test",
-             srctop_file("test", "certs", "servercert.pem"),
-             srctop_file("test", "certs", "wrongkey.pem"), "cert", "failed"])));
+             src_file("servercert.pem"),
+             src_file("wrongkey.pem"), "cert", "failed"])));
 SKIP: {
     skip "DSA disabled", 1, if disabled("dsa");
     # dsa
     ok(run(test(["x509_check_cert_pkey_test",
-		 srctop_file("test", "certs", "server-dsa-cert.pem"),
-		 srctop_file("test", "certs", "server-dsa-key.pem"), "cert", "ok"])));
+		 src_file("server-dsa-cert.pem"),
+		 src_file("server-dsa-key.pem"), "cert", "ok"])));
 }
 # ecc
 SKIP: {
-    skip "EC disabled", 1 if disabled("ec");
+    skip "EC disabled", 2 if disabled("ec");
     ok(run(test(["x509_check_cert_pkey_test",
-                 srctop_file("test", "certs", "server-ecdsa-cert.pem"),
-                 srctop_file("test", "certs", "server-ecdsa-key.pem"), "cert", "ok"])));
+                 src_file("server-ecdsa-cert.pem"),
+                 src_file("server-ecdsa-key.pem"), "cert", "ok"])));
+
+    test_PEM_X509_INFO_read("ec_privkey_with_chain.pem", "5");
+
 }
 # certificate request (rsa)
 ok(run(test(["x509_check_cert_pkey_test",
-             srctop_file("test", "certs", "x509-check.csr"),
-             srctop_file("test", "certs", "x509-check-key.pem"), "req", "ok"])));
+             src_file("x509-check.csr"),
+             src_file("x509-check-key.pem"), "req", "ok"])));
 # mismatched certificate request (rsa)
 ok(run(test(["x509_check_cert_pkey_test",
-             srctop_file("test", "certs", "x509-check.csr"),
-             srctop_file("test", "certs", "wrongkey.pem"), "req", "failed"])));
+             src_file("x509-check.csr"),
+             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");
diff --git a/test/x509_check_cert_pkey_test.c b/test/x509_check_cert_pkey_test.c
index cf26ed9228..3e075e9bbe 100644
--- a/test/x509_check_cert_pkey_test.c
+++ b/test/x509_check_cert_pkey_test.c
@@ -106,15 +106,47 @@ failed:
     return ret;
 }
 
+static const char *file; /* path of a cert/CRL/key file in PEM format */
+static const char *num;  /* expected number of certs/CRLs/keys included */
+
+static int test_PEM_X509_INFO_read_bio(void)
+{
+    BIO *in;
+    STACK_OF(X509_INFO) *sk;
+    X509_INFO *it;
+    int i, count = 0;
+    int expected = 0;
+
+    if (!TEST_ptr((in = BIO_new_file(file, "r"))))
+        return 0;
+    sk = PEM_X509_INFO_read_bio(in, NULL, NULL, "");
+    BIO_free(in);
+    sscanf(num, "%d", &expected);
+    for (i = 0; i < sk_X509_INFO_num(sk); i++) {
+        it = sk_X509_INFO_value(sk, i);
+        if (it->x509 != NULL)
+            count++;
+        if (it->crl != NULL)
+            count++;
+        if (it->x_pkey != NULL)
+            count++;
+    }
+    sk_X509_INFO_pop_free(sk, X509_INFO_free);
+    return TEST_int_eq(count, expected);
+}
+
 const OPTIONS *test_get_options(void)
 {
     enum { OPT_TEST_ENUM };
     static const OPTIONS test_options[] = {
-        OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("cert key type expected\n"),
+        OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("cert key type expected\n"
+                                          "     or [options] file num\n"),
         { OPT_HELP_STR, 1, '-', "cert\tcertificate or CSR filename in PEM\n" },
         { OPT_HELP_STR, 1, '-', "key\tprivate key filename in PEM\n" },
         { OPT_HELP_STR, 1, '-', "type\t\tvalue must be 'cert' or 'req'\n" },
         { OPT_HELP_STR, 1, '-', "expected\tthe expected return value, either 'ok' or 'failed'\n" },
+        { OPT_HELP_STR, 1, '-', "file\tPEM format file containing certs, keys, and/OR CRLs\n" },
+        { OPT_HELP_STR, 1, '-', "num\texpected number of credentials to be loaded from file\n" },
         { NULL }
     };
     return test_options;
@@ -127,6 +159,14 @@ int setup_tests(void)
         return 0;
     }
 
+    if (test_get_argument_count() == 2) {
+        if (!TEST_ptr(file = test_get_argument(0))
+                || !TEST_ptr(num = test_get_argument(1)))
+            return 0;
+        ADD_TEST(test_PEM_X509_INFO_read_bio);
+        return 1;
+    }
+
     if (!TEST_ptr(c = test_get_argument(0))
             || !TEST_ptr(k = test_get_argument(1))
             || !TEST_ptr(t = test_get_argument(2))


More information about the openssl-commits mailing list