{
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 };
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;
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;
}
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;
}
*pp = p;
if (a != NULL)
- (*a) = ret;
+ *a = ret;
return ret;
err:
if (a == NULL || *a != ret)
if (ret == NULL)
return NULL;
*pp = p;
- if (a) {
+ if (a != NULL) {
*a = ret;
}
return ret;
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;
}
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;
=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.
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.
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)>.
--- /dev/null
+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-----
+
setup("test_x509_check_cert_pkey");
-plan tests => 6;
+plan tests => 9;
+
+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("cyrillic_crl.utf8", "1");
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;
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))