]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls_pkcs12_generate_mac2: factor out mac generation logic
authorDaiki Ueno <ueno@gnu.org>
Tue, 14 May 2024 03:40:38 +0000 (12:40 +0900)
committerDaiki Ueno <ueno@gnu.org>
Tue, 14 May 2024 03:40:38 +0000 (12:40 +0900)
This would allow us to easily implement PBMAC1 usage in PKCS#12.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
lib/x509/pkcs12.c

index 4d9ae6e4e4963651cba7fd8a6a5e0671a9537bef..ee16f80a3da10b7a8e1dfb44d329f83ef9ce4b79 100644 (file)
@@ -874,6 +874,77 @@ _gnutls_pkcs12_gost_string_to_key(gnutls_mac_algorithm_t algo,
 }
 #endif
 
+static int generate_mac_pkcs12(const mac_entry_st *me,
+                              const gnutls_datum_t *key,
+                              const gnutls_datum_t *salt, unsigned iter_count,
+                              const gnutls_datum_t *data, asn1_node pkcs12)
+{
+       mac_hd_st hd;
+       uint8_t mac_key_data[MAX_HASH_SIZE];
+       size_t mac_key_size = me->output_size;
+       uint8_t mac_data[MAX_HASH_SIZE];
+       gnutls_datum_t mac;
+       int result;
+
+#if ENABLE_GOST
+       if (me->id == GNUTLS_MAC_GOSTR_94 ||
+           me->id == GNUTLS_MAC_STREEBOG_256 ||
+           me->id == GNUTLS_MAC_STREEBOG_512) {
+               mac_key_size = 32;
+               result = _gnutls_pkcs12_gost_string_to_key(
+                       me->id, salt->data, salt->size, iter_count,
+                       (const char *)key->data, mac_key_size, mac_key_data);
+       } else
+#endif
+               result = _gnutls_pkcs12_string_to_key(
+                       me, 3 /*MAC*/, salt->data, salt->size, iter_count,
+                       (const char *)key->data, mac_key_size, mac_key_data);
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       /* MAC the data.
+        */
+       result = _gnutls_mac_init(&hd, me, mac_key_data, mac_key_size);
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       _gnutls_mac(&hd, data->data, data->size);
+
+       _gnutls_mac_deinit(&hd, mac_data);
+
+       mac.data = mac_data;
+       mac.size = me->output_size;
+
+       result = _gnutls_x509_write_value(pkcs12, "macData.mac.digest", &mac);
+       if (result < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       result = asn1_write_value(
+               pkcs12, "macData.mac.digestAlgorithm.algorithm", me->oid, 1);
+       if (result != ASN1_SUCCESS) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       result = asn1_write_value(
+               pkcs12, "macData.mac.digestAlgorithm.parameters", NULL, 0);
+       if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */
+       _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+
+       return 0;
+}
+
 /**
  * gnutls_pkcs12_generate_mac2:
  * @pkcs12: A pkcs12 type
@@ -888,13 +959,11 @@ _gnutls_pkcs12_gost_string_to_key(gnutls_mac_algorithm_t algo,
 int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12,
                                gnutls_mac_algorithm_t mac, const char *pass)
 {
-       uint8_t salt[8], key[MAX_HASH_SIZE];
+       uint8_t salt_data[8];
+       gnutls_datum_t salt, key;
+       const int iter_count = PKCS12_ITER_COUNT;
        int result;
-       const int iter = PKCS12_ITER_COUNT;
-       mac_hd_st td1;
-       gnutls_datum_t tmp = { NULL, 0 };
-       unsigned mac_size, key_len;
-       uint8_t mac_out[MAX_HASH_SIZE];
+       gnutls_datum_t data = { NULL, 0 };
        const mac_entry_st *me = mac_to_entry(mac);
 
        if (pkcs12 == NULL || me == NULL)
@@ -903,12 +972,12 @@ int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12,
        if (me->oid == NULL)
                return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
 
-       mac_size = _gnutls_mac_get_algo_len(me);
-       key_len = mac_size;
-
        /* Generate the salt.
         */
-       result = gnutls_rnd(GNUTLS_RND_NONCE, salt, sizeof(salt));
+       salt.data = salt_data;
+       salt.size = sizeof(salt_data);
+
+       result = gnutls_rnd(GNUTLS_RND_NONCE, salt.data, salt.size);
        if (result < 0) {
                gnutls_assert();
                return result;
@@ -916,99 +985,42 @@ int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12,
 
        /* Write the salt into the structure.
         */
-       result = asn1_write_value(pkcs12->pkcs12, "macData.macSalt", salt,
-                                 sizeof(salt));
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               result = _gnutls_asn2err(result);
-               goto cleanup;
-       }
-
-       /* write the iterations
-        */
-
-       if (iter > 1) {
-               result = _gnutls_x509_write_uint32(pkcs12->pkcs12,
-                                                  "macData.iterations", iter);
-               if (result < 0) {
-                       gnutls_assert();
-                       goto cleanup;
-               }
-       }
-
-       /* Generate the key.
-        */
-#if ENABLE_GOST
-       if (me->id == GNUTLS_MAC_GOSTR_94 ||
-           me->id == GNUTLS_MAC_STREEBOG_256 ||
-           me->id == GNUTLS_MAC_STREEBOG_512) {
-               key_len = 32;
-               result = _gnutls_pkcs12_gost_string_to_key(
-                       me->id, salt, sizeof(salt), iter, pass, key_len, key);
-       } else
-#endif
-               result = _gnutls_pkcs12_string_to_key(me, 3 /*MAC*/, salt,
-                                                     sizeof(salt), iter, pass,
-                                                     mac_size, key);
+       result = _gnutls_x509_write_value(pkcs12->pkcs12, "macData.macSalt",
+                                         &salt);
        if (result < 0) {
                gnutls_assert();
                goto cleanup;
        }
 
-       /* Get the data to be MACed
+       /* Write the iteration count into the structure.
         */
-       result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &tmp);
+       result = _gnutls_x509_write_uint32(pkcs12->pkcs12, "macData.iterations",
+                                          iter_count);
        if (result < 0) {
                gnutls_assert();
                goto cleanup;
        }
 
-       /* MAC the data
+       /* Get the data to be MACed.
         */
-       result = _gnutls_mac_init(&td1, me, key, key_len);
+       result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &data);
        if (result < 0) {
                gnutls_assert();
                goto cleanup;
        }
 
-       _gnutls_mac(&td1, tmp.data, tmp.size);
-       _gnutls_free_datum(&tmp);
-
-       _gnutls_mac_deinit(&td1, mac_out);
-
-       result = asn1_write_value(pkcs12->pkcs12, "macData.mac.digest", mac_out,
-                                 mac_size);
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               result = _gnutls_asn2err(result);
-               goto cleanup;
-       }
-
-       result = asn1_write_value(pkcs12->pkcs12,
-                                 "macData.mac.digestAlgorithm.parameters",
-                                 NULL, 0);
-       if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
-               gnutls_assert();
-               result = _gnutls_asn2err(result);
-               goto cleanup;
-       }
-
-       result = asn1_write_value(pkcs12->pkcs12,
-                                 "macData.mac.digestAlgorithm.algorithm",
-                                 me->oid, 1);
-       if (result != ASN1_SUCCESS) {
-               gnutls_assert();
-               result = _gnutls_asn2err(result);
-               goto cleanup;
-       }
+       /* MAC the data.
+        */
+       key.data = (void *)pass;
+       key.size = strlen(pass);
 
-       /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */
-       _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
-       return 0;
+       result = generate_mac_pkcs12(me, &key, &salt, iter_count, &data,
+                                    pkcs12->pkcs12);
 
 cleanup:
-       _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
-       _gnutls_free_datum(&tmp);
+       if (result < 0)
+               _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+       _gnutls_free_datum(&data);
        return result;
 }