]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
pkcs12: Add support for PKCS#12 containers with empty or no password
authorTobias Brunner <tobias@strongswan.org>
Wed, 18 Oct 2023 15:22:08 +0000 (17:22 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Nov 2023 11:26:07 +0000 (12:26 +0100)
src/libstrongswan/plugins/pkcs12/pkcs12_decode.c

index bed02cc423119a204c8a1de8f6656d6979cd4f52..c214147ef289e4f8cdc78b4b2053515ccb5e11f3 100644 (file)
@@ -321,43 +321,62 @@ end:
        return success;
 }
 
+/**
+ * Verify the given MAC using the given password.
+ */
+static bool verify_mac_pw(signer_t *signer, hash_algorithm_t hash, chunk_t salt,
+                                                 uint64_t iterations, chunk_t data, chunk_t mac,
+                                                 chunk_t pw)
+{
+       chunk_t key, calculated;
+       bool success = FALSE;
+
+       key = chunk_alloca(signer->get_key_size(signer));
+       calculated = chunk_alloca(signer->get_block_size(signer));
+
+       if (pkcs12_derive_key(hash, pw, salt, iterations, PKCS12_KEY_MAC, key) &&
+               signer->set_key(signer, key) &&
+               signer->get_signature(signer, data, calculated.ptr) &&
+               chunk_equals_const(mac, calculated))
+       {
+               success = TRUE;
+       }
+       memwipe(key.ptr, key.len);
+       return success;
+}
+
 /**
  * Verify the given MAC with available passwords.
  */
 static bool verify_mac(hash_algorithm_t hash, chunk_t salt,
                                           uint64_t iterations, chunk_t data, chunk_t mac)
 {
-       integrity_algorithm_t integ;
        enumerator_t *enumerator;
        shared_key_t *shared;
        signer_t *signer;
-       chunk_t key, calculated;
        bool success = FALSE;
 
-       integ = hasher_algorithm_to_integrity(hash, mac.len);
-       signer = lib->crypto->create_signer(lib->crypto, integ);
+       signer = lib->crypto->create_signer(lib->crypto,
+                                                               hasher_algorithm_to_integrity(hash, mac.len));
        if (!signer)
        {
                return FALSE;
        }
-       key = chunk_alloca(signer->get_key_size(signer));
-       calculated = chunk_alloca(signer->get_block_size(signer));
+
+       /* try without and with an empty password, which is not the same thing */
+       if (verify_mac_pw(signer, hash, salt, iterations, data, mac, chunk_empty) ||
+               verify_mac_pw(signer, hash, salt, iterations, data, mac, chunk_from_str("")))
+       {
+               signer->destroy(signer);
+               return TRUE;
+       }
 
        enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
                                                                                SHARED_PRIVATE_KEY_PASS, NULL, NULL);
        while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
        {
-               if (!pkcs12_derive_key(hash, shared->get_key(shared), salt, iterations,
-                                                          PKCS12_KEY_MAC, key))
-               {
-                       break;
-               }
-               if (!signer->set_key(signer, key) ||
-                       !signer->get_signature(signer, data, calculated.ptr))
-               {
-                       break;
-               }
-               if (chunk_equals_const(mac, calculated))
+               if (verify_mac_pw(signer, hash, salt, iterations, data, mac,
+                                                 shared->get_key(shared)))
                {
                        success = TRUE;
                        break;