PKCS12_SAFEBAG *bag);
static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
PKCS12_SAFEBAG *bag);
+static PKCS12_SAFEBAG *pkcs12_add_cert_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+ X509 *cert,
+ const char *name,
+ int namelen,
+ unsigned char *keyid,
+ int keyidlen);
static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
{
int i, cbret;
unsigned char keyid[EVP_MAX_MD_SIZE];
unsigned int keyidlen = 0;
+ int namelen = -1;
+ unsigned char *pkeyid = NULL;
+ int pkeyidlen = -1;
/* Set defaults */
if (nid_cert == NID_undef)
}
if (cert) {
- bag = PKCS12_add_cert(&bags, cert);
- if (name && !PKCS12_add_friendlyname(bag, name, -1))
- goto err;
- if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
- goto err;
+ if (name == NULL)
+ name = (char *)X509_alias_get0(cert, &namelen);
+ if (keyidlen > 0) {
+ pkeyid = keyid;
+ pkeyidlen = keyidlen;
+ } else {
+ pkeyid = X509_keyid_get0(cert, &pkeyidlen);
+ }
+
+ bag = pkcs12_add_cert_bag(&bags, cert, name, namelen, pkeyid, pkeyidlen);
if (cb != NULL) {
cbret = cb(bag, cbarg);
if (cbret == -1) {
iter, mac_iter, keytype, NULL, NULL);
}
-PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
+static PKCS12_SAFEBAG *pkcs12_add_cert_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+ X509 *cert,
+ const char *name,
+ int namelen,
+ unsigned char *keyid,
+ int keyidlen)
{
PKCS12_SAFEBAG *bag = NULL;
- char *name;
- int namelen = -1;
- unsigned char *keyid;
- int keyidlen = -1;
/* Add user certificate */
if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL)
goto err;
- /*
- * Use friendlyName and localKeyID in certificate. (if present)
- */
-
- name = (char *)X509_alias_get0(cert, &namelen);
-
- if (name && !PKCS12_add_friendlyname(bag, name, namelen))
+ if (name != NULL && !PKCS12_add_friendlyname(bag, name, namelen))
goto err;
- keyid = X509_keyid_get0(cert, &keyidlen);
-
- if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+ if (keyid != NULL && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
goto err;
if (!pkcs12_add_bag(pbags, bag))
err:
PKCS12_SAFEBAG_free(bag);
return NULL;
+}
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
+{
+ char *name = NULL;
+ int namelen = -1;
+ unsigned char *keyid = NULL;
+ int keyidlen = -1;
+
+ /*
+ * Use friendlyName and localKeyID in certificate. (if present)
+ */
+ name = (char *)X509_alias_get0(cert, &namelen);
+ keyid = X509_keyid_get0(cert, &keyidlen);
+ return pkcs12_add_cert_bag(pbags, cert, name, namelen, keyid, keyidlen);
}
PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags,
}
#endif
+static int pkcs12_recreate_test(void)
+{
+ int ret = 0;
+ X509 *cert = NULL;
+ X509 *cert_parsed = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY *pkey_parsed = NULL;
+ PKCS12 *p12 = NULL;
+ PKCS12 *p12_parsed = NULL;
+ PKCS12 *p12_recreated = NULL;
+ const unsigned char *cert_bytes = CERT1;
+ const unsigned char *key_bytes = KEY1;
+ BIO *bio = NULL;
+
+ cert = d2i_X509(NULL, &cert_bytes, sizeof(CERT1));
+ if (!TEST_ptr(cert))
+ goto err;
+ pkey = d2i_AutoPrivateKey(NULL, &key_bytes, sizeof(KEY1));
+ if (!TEST_ptr(pkey))
+ goto err;
+ p12 = PKCS12_create("pass", NULL, pkey, cert, NULL, NID_aes_256_cbc,
+ NID_aes_256_cbc, 2, 1, 0);
+ if (!TEST_ptr(p12))
+ goto err;
+ if (!TEST_int_eq(ERR_peek_error(), 0))
+ goto err;
+
+ bio = BIO_new(BIO_s_mem());
+ if (!TEST_ptr(bio))
+ goto err;
+ if (!TEST_int_eq(i2d_PKCS12_bio(bio, p12), 1))
+ goto err;
+ p12_parsed = PKCS12_init_ex(NID_pkcs7_data, testctx, NULL);
+ if (!TEST_ptr(p12_parsed))
+ goto err;
+ p12_parsed = d2i_PKCS12_bio(bio, &p12_parsed);
+ if (!TEST_ptr(p12_parsed))
+ goto err;
+ if (!TEST_int_eq(PKCS12_parse(p12_parsed, "pass", &pkey_parsed,
+ &cert_parsed, NULL), 1))
+ goto err;
+
+ /* cert_parsed also contains auxiliary data */
+ p12_recreated = PKCS12_create("new_pass", NULL, pkey_parsed, cert_parsed,
+ NULL, NID_aes_256_cbc, NID_aes_256_cbc,
+ 2, 1, 0);
+ if (!TEST_ptr(p12_recreated))
+ goto err;
+ if (!TEST_int_eq(ERR_peek_error(), 0))
+ goto err;
+
+ ret = 1;
+err:
+ BIO_free(bio);
+ PKCS12_free(p12);
+ PKCS12_free(p12_parsed);
+ PKCS12_free(p12_recreated);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pkey_parsed);
+ X509_free(cert);
+ X509_free(cert_parsed);
+ return ret;
+}
+
typedef enum OPTION_choice {
OPT_ERR = -1,
OPT_EOF = 0,
if (default_libctx)
ADD_TEST(pkcs12_create_test);
#endif
+ if (default_libctx)
+ ADD_TEST(pkcs12_recreate_test);
ADD_ALL_TESTS(test_single_key_enc_pass, OSSL_NELEM(passwords));
ADD_ALL_TESTS(test_single_key_enc_iter, OSSL_NELEM(iters));
ADD_TEST(test_single_key_with_attrs);