@@ -395,6 +395,33 @@ static void TestRoundTrip(const char *password, const char *name,
395395 ASSERT_TRUE (certs2);
396396 ASSERT_TRUE (PKCS12_get_key_and_certs (&key2, certs2.get (), &cbs, password));
397397 bssl::UniquePtr<EVP_PKEY> free_key2 (key2);
398+
399+ // Check that writing to a |BIO| does the same thing.
400+ bssl::UniquePtr<BIO> bio (BIO_new (BIO_s_mem ()));
401+ ASSERT_TRUE (bio);
402+ ASSERT_TRUE (i2d_PKCS12_bio (bio.get (), pkcs12.get ()));
403+ const uint8_t *bio_data;
404+ size_t bio_len;
405+ ASSERT_TRUE (BIO_mem_contents (bio.get (), &bio_data, &bio_len));
406+ EXPECT_EQ (Bytes (bio_data, bio_len), Bytes (der, len));
407+
408+ // Check that the result round-trips with |PKCS12_set_mac| as well. The
409+ // resulting bytes will be different due to the regenerated salt, but |pkcs12|
410+ // should still be in a usable state with the same certs and keys encoded.
411+ uint8_t *der2 = nullptr ;
412+ EXPECT_TRUE (PKCS12_set_mac (pkcs12.get (), password, strlen (password), nullptr ,
413+ 0 , mac_iterations, nullptr ));
414+ len = i2d_PKCS12 (pkcs12.get (), &der2);
415+ ASSERT_GT (len, 0 );
416+ bssl::UniquePtr<uint8_t > free_der2 (der2);
417+
418+ CBS_init (&cbs, der2, len);
419+ EVP_PKEY *key3 = nullptr ;
420+ certs2.reset (sk_X509_new_null ());
421+ ASSERT_TRUE (certs2);
422+ ASSERT_TRUE (PKCS12_get_key_and_certs (&key3, certs2.get (), &cbs, password));
423+ bssl::UniquePtr<EVP_PKEY> free_key3 (key3);
424+
398425 // Note |EVP_PKEY_cmp| returns one for equality while |X509_cmp| returns zero.
399426 if (key) {
400427 EXPECT_EQ (1 , EVP_PKEY_cmp (key2, key.get ()));
@@ -421,15 +448,6 @@ static void TestRoundTrip(const char *password, const char *name,
421448 static_cast <size_t >(actual_name_len)));
422449 }
423450 }
424-
425- // Check that writing to a |BIO| does the same thing.
426- bssl::UniquePtr<BIO> bio (BIO_new (BIO_s_mem ()));
427- ASSERT_TRUE (bio);
428- ASSERT_TRUE (i2d_PKCS12_bio (bio.get (), pkcs12.get ()));
429- const uint8_t *bio_data;
430- size_t bio_len;
431- ASSERT_TRUE (BIO_mem_contents (bio.get (), &bio_data, &bio_len));
432- EXPECT_EQ (Bytes (bio_data, bio_len), Bytes (der, len));
433451}
434452
435453TEST (PKCS12Test, RoundTrip) {
@@ -533,7 +551,7 @@ static bssl::UniquePtr<X509> MakeTestCert(EVP_PKEY *key) {
533551 return x509;
534552}
535553
536- static bool PKCS12CreateVector (std::vector< uint8_t > *out , EVP_PKEY *pkey,
554+ static bool PKCS12CreateVector (bssl::UniquePtr<PKCS12> &p12 , EVP_PKEY *pkey,
537555 const std::vector<X509 *> &certs) {
538556 bssl::UniquePtr<STACK_OF (X509)> chain (sk_X509_new_null ());
539557 if (!chain) {
@@ -546,31 +564,17 @@ static bool PKCS12CreateVector(std::vector<uint8_t> *out, EVP_PKEY *pkey,
546564 }
547565 }
548566
549- bssl::UniquePtr<PKCS12> p12 (PKCS12_create (kPassword , nullptr /* name */ , pkey,
550- nullptr /* cert */ , chain.get (), 0 ,
551- 0 , 0 , 0 , 0 ));
567+ p12.reset (PKCS12_create (kPassword , nullptr /* name */ , pkey,
568+ nullptr /* cert */ , chain.get (), 0 , 0 , 0 , 0 , 0 ));
552569 if (!p12) {
553570 return false ;
554571 }
555-
556- int len = i2d_PKCS12 (p12.get (), nullptr );
557- if (len < 0 ) {
558- return false ;
559- }
560- out->resize (static_cast <size_t >(len));
561- uint8_t *ptr = out->data ();
562- return i2d_PKCS12 (p12.get (), &ptr) == len;
572+ return true ;
563573}
564574
565- static void ExpectPKCS12Parse (bssl::Span< const uint8_t > in ,
575+ static void ExpectPKCS12Parse (bssl::UniquePtr<PKCS12> &p12 ,
566576 EVP_PKEY *expect_key, X509 *expect_cert,
567577 const std::vector<X509 *> &expect_ca_certs) {
568- bssl::UniquePtr<BIO> bio (BIO_new_mem_buf (in.data (), in.size ()));
569- ASSERT_TRUE (bio);
570-
571- bssl::UniquePtr<PKCS12> p12 (d2i_PKCS12_bio (bio.get (), nullptr ));
572- ASSERT_TRUE (p12);
573-
574578 EVP_PKEY *key = nullptr ;
575579 X509 *cert = nullptr ;
576580 STACK_OF (X509) *ca_certs = nullptr ;
@@ -618,33 +622,32 @@ TEST(PKCS12Test, Order) {
618622 ASSERT_TRUE (cert3);
619623
620624 // PKCS12_parse uses the key to select the main certificate.
621- std::vector< uint8_t > p12;
622- ASSERT_TRUE (PKCS12CreateVector (& p12, key1.get (),
625+ bssl::UniquePtr<PKCS12 > p12;
626+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
623627 {cert1.get (), cert2.get (), cert3.get ()}));
624628 ExpectPKCS12Parse (p12, key1.get (), cert1.get (), {cert2.get (), cert3.get ()});
625629
626- ASSERT_TRUE (PKCS12CreateVector (& p12, key1.get (),
630+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
627631 {cert3.get (), cert1.get (), cert2.get ()}));
628632 ExpectPKCS12Parse (p12, key1.get (), cert1.get (), {cert3.get (), cert2.get ()});
629633
630- ASSERT_TRUE (PKCS12CreateVector (& p12, key1.get (),
634+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
631635 {cert2.get (), cert3.get (), cert1.get ()}));
632636 ExpectPKCS12Parse (p12, key1.get (), cert1.get (), {cert2.get (), cert3.get ()});
633637
634638 // In case of duplicates, the last one is selected. (It is unlikely anything
635639 // depends on which is selected, but we match OpenSSL.)
636- ASSERT_TRUE (
637- PKCS12CreateVector (&p12, key1.get (), {cert1.get (), cert1b.get ()}));
640+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (), {cert1.get (), cert1b.get ()}));
638641 ExpectPKCS12Parse (p12, key1.get (), cert1b.get (), {cert1.get ()});
639642
640643 // If there is no key, all certificates are returned as "CA" certificates.
641- ASSERT_TRUE (PKCS12CreateVector (& p12, nullptr ,
644+ ASSERT_TRUE (PKCS12CreateVector (p12, nullptr ,
642645 {cert1.get (), cert2.get (), cert3.get ()}));
643646 ExpectPKCS12Parse (p12, nullptr , nullptr ,
644647 {cert1.get (), cert2.get (), cert3.get ()});
645648
646649 // The same happens if there is a key, but it does not match any certificate.
647- ASSERT_TRUE (PKCS12CreateVector (& p12, key1.get (), {cert2.get (), cert3.get ()}));
650+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (), {cert2.get (), cert3.get ()}));
648651 ExpectPKCS12Parse (p12, key1.get (), nullptr , {cert2.get (), cert3.get ()});
649652}
650653
@@ -663,13 +666,8 @@ TEST(PKCS12Test, CreateWithAlias) {
663666 ASSERT_EQ (res, 1 );
664667
665668 std::vector<X509 *> certs = {cert1.get (), cert2.get ()};
666- std::vector<uint8_t > der;
667- ASSERT_TRUE (PKCS12CreateVector (&der, key.get (), certs));
668-
669- bssl::UniquePtr<BIO> bio (BIO_new_mem_buf (der.data (), der.size ()));
670- ASSERT_TRUE (bio);
671- bssl::UniquePtr<PKCS12> p12 (d2i_PKCS12_bio (bio.get (), nullptr ));
672- ASSERT_TRUE (p12);
669+ bssl::UniquePtr<PKCS12> p12;
670+ ASSERT_TRUE (PKCS12CreateVector (p12, key.get (), certs));
673671
674672 EVP_PKEY *parsed_key = nullptr ;
675673 X509 *parsed_cert = nullptr ;
@@ -695,3 +693,48 @@ TEST(PKCS12Test, BasicAlloc) {
695693 bssl::UniquePtr<PKCS12> p12 (PKCS12_new ());
696694 ASSERT_TRUE (p12);
697695}
696+
697+ TEST (PKCS12Test, SetMac) {
698+ bssl::UniquePtr<EVP_PKEY> key1 = MakeTestKey ();
699+ ASSERT_TRUE (key1);
700+ bssl::UniquePtr<X509> cert1 = MakeTestCert (key1.get ());
701+ ASSERT_TRUE (cert1);
702+ bssl::UniquePtr<X509> cert1b = MakeTestCert (key1.get ());
703+ ASSERT_TRUE (cert1b);
704+ bssl::UniquePtr<EVP_PKEY> key2 = MakeTestKey ();
705+ ASSERT_TRUE (key2);
706+ bssl::UniquePtr<X509> cert2 = MakeTestCert (key2.get ());
707+ ASSERT_TRUE (cert2);
708+ bssl::UniquePtr<EVP_PKEY> key3 = MakeTestKey ();
709+ ASSERT_TRUE (key3);
710+ bssl::UniquePtr<X509> cert3 = MakeTestCert (key3.get ());
711+ ASSERT_TRUE (cert3);
712+
713+ // PKCS12_parse uses the key to select the main certificate.
714+ bssl::UniquePtr<PKCS12> p12;
715+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
716+ {cert1.get (), cert2.get (), cert3.get ()}));
717+ EXPECT_TRUE (PKCS12_set_mac (p12.get (), kPassword , strlen (kPassword ), nullptr ,
718+ 0 , 0 , nullptr ));
719+ ExpectPKCS12Parse (p12, key1.get (), cert1.get (), {cert2.get (), cert3.get ()});
720+
721+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
722+ {cert3.get (), cert1.get (), cert2.get ()}));
723+ EXPECT_TRUE (PKCS12_set_mac (p12.get (), kPassword , strlen (kPassword ), nullptr ,
724+ 0 , 0 , nullptr ));
725+ ExpectPKCS12Parse (p12, key1.get (), cert1.get (), {cert3.get (), cert2.get ()});
726+
727+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
728+ {cert2.get (), cert3.get (), cert1.get ()}));
729+ EXPECT_TRUE (PKCS12_set_mac (p12.get (), kPassword , strlen (kPassword ), nullptr ,
730+ 0 , 0 , nullptr ));
731+ ExpectPKCS12Parse (p12, key1.get (), cert1.get (), {cert2.get (), cert3.get ()});
732+
733+ // The same password should be used with |PKCS12_create| and |PKCS12_set_mac|.
734+ ASSERT_TRUE (PKCS12CreateVector (p12, key1.get (),
735+ {cert1.get (), cert2.get (), cert3.get ()}));
736+ EXPECT_FALSE (PKCS12_set_mac (p12.get (), kUnicodePassword ,
737+ strlen (kUnicodePassword ), nullptr , 0 , 0 ,
738+ nullptr ));
739+ }
740+
0 commit comments