}
#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
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)
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;
/* 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;
}