diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-08-10 10:28:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-08-10 13:28:29 +0200 |
commit | d9eff7f6010f8237f3549e304bf62823807b64d6 (patch) | |
tree | 6b68dd71c0190afdb245477031ee92991f19d03b | |
parent | 46d911df71019294893c0767a21b1be129b3edf4 (diff) | |
download | gnutls-d9eff7f6010f8237f3549e304bf62823807b64d6.tar.gz |
pkcs12: Allow verification with structures that support other than HMAC-SHA1 MACs.
Conflicts:
lib/x509/pkcs12_encr.c
-rw-r--r-- | lib/algorithms.h | 1 | ||||
-rw-r--r-- | lib/x509/pkcs12.c | 57 | ||||
-rw-r--r-- | lib/x509/pkcs12_encr.c | 16 | ||||
-rw-r--r-- | lib/x509/privkey_pkcs8.c | 12 | ||||
-rw-r--r-- | lib/x509/x509_int.h | 3 |
5 files changed, 61 insertions, 28 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h index d57e48fd3f..af102cf3a2 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -134,6 +134,7 @@ inline static int _gnutls_mac_get_key_size(const mac_entry_st * e) return e->key_size; } +#define _gnutls_x509_oid_to_mac(oid) (gnutls_mac_algorithm_t)_gnutls_x509_oid_to_digest(oid) gnutls_digest_algorithm_t _gnutls_x509_oid_to_digest(const char *oid); /* Functions for digests. */ diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c index fa86bde000..378eaf0f46 100644 --- a/lib/x509/pkcs12.c +++ b/lib/x509/pkcs12.c @@ -840,6 +840,7 @@ int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12, const char *pass) mac_hd_st td1; gnutls_datum_t tmp = { NULL, 0 }; uint8_t sha_mac[20]; + const mac_entry_st *me = mac_to_entry(GNUTLS_MAC_SHA1); if (pkcs12 == NULL) { gnutls_assert(); @@ -881,7 +882,7 @@ int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12, const char *pass) /* Generate the key. */ result = - _gnutls_pkcs12_string_to_key(3 /*MAC*/, salt, sizeof(salt), + _gnutls_pkcs12_string_to_key(me, 3 /*MAC*/, salt, sizeof(salt), iter, pass, sizeof(key), key); if (result < 0) { gnutls_assert(); @@ -898,7 +899,7 @@ int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12, const char *pass) /* MAC the data */ - result = _gnutls_mac_init(&td1, mac_to_entry(GNUTLS_MAC_SHA1), + result = _gnutls_mac_init(&td1, me, key, sizeof(key)); if (result < 0) { gnutls_assert(); @@ -959,15 +960,19 @@ int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12, const char *pass) **/ int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass) { - uint8_t key[20]; + uint8_t key[MAX_HASH_SIZE]; + char oid[MAX_OID_SIZE]; int result; unsigned int iter; int len; mac_hd_st td1; gnutls_datum_t tmp = { NULL, 0 }, salt = { NULL, 0}; - uint8_t sha_mac[20]; - uint8_t sha_mac_orig[20]; + uint8_t mac_output[MAX_HASH_SIZE]; + uint8_t mac_output_orig[MAX_HASH_SIZE]; + gnutls_mac_algorithm_t algo; + unsigned mac_len, key_len; + const mac_entry_st *entry; if (pkcs12 == NULL) { gnutls_assert(); @@ -976,7 +981,6 @@ int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass) /* read the iterations */ - result = _gnutls_x509_read_uint(pkcs12->pkcs12, "macData.iterations", &iter); @@ -984,23 +988,44 @@ int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass) iter = 1; /* the default */ } + len = sizeof(oid); + result = + asn1_read_value(pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm", + oid, &len); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + algo = _gnutls_x509_oid_to_mac(oid); + if (algo == GNUTLS_MAC_UNKNOWN) { + unknown_mac: + gnutls_assert(); + return GNUTLS_E_UNKNOWN_HASH_ALGORITHM; + } + + entry = mac_to_entry(algo); + if (entry == NULL) + goto unknown_mac; + + mac_len = _gnutls_mac_get_algo_len(entry); + key_len = mac_len; /* Read the salt from the structure. */ result = _gnutls_x509_read_value(pkcs12->pkcs12, "macData.macSalt", &salt); - if (result != ASN1_SUCCESS) { + if (result < 0) { gnutls_assert(); - result = _gnutls_asn2err(result); goto cleanup; } /* Generate the key. */ result = - _gnutls_pkcs12_string_to_key(3 /*MAC*/, salt.data, salt.size, - iter, pass, sizeof(key), key); + _gnutls_pkcs12_string_to_key(entry, 3 /*MAC*/, salt.data, salt.size, + iter, pass, key_len, key); if (result < 0) { gnutls_assert(); goto cleanup; @@ -1018,8 +1043,7 @@ int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass) /* MAC the data */ - result = _gnutls_mac_init(&td1, mac_to_entry(GNUTLS_MAC_SHA1), - key, sizeof(key)); + result = _gnutls_mac_init(&td1, entry, key, key_len); if (result < 0) { gnutls_assert(); goto cleanup; @@ -1028,19 +1052,20 @@ int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass) _gnutls_mac(&td1, tmp.data, tmp.size); _gnutls_free_datum(&tmp); - _gnutls_mac_deinit(&td1, sha_mac); + _gnutls_mac_deinit(&td1, mac_output); - len = sizeof(sha_mac_orig); + len = sizeof(mac_output_orig); result = asn1_read_value(pkcs12->pkcs12, "macData.mac.digest", - sha_mac_orig, &len); + mac_output_orig, &len); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } - if (memcmp(sha_mac_orig, sha_mac, sizeof(sha_mac)) != 0) { + if ((unsigned)len != mac_len || + memcmp(mac_output_orig, mac_output, len) != 0) { gnutls_assert(); return GNUTLS_E_MAC_VERIFY_FAILED; } diff --git a/lib/x509/pkcs12_encr.c b/lib/x509/pkcs12_encr.c index e194ca4884..481189ffb4 100644 --- a/lib/x509/pkcs12_encr.c +++ b/lib/x509/pkcs12_encr.c @@ -54,7 +54,8 @@ static int _pkcs12_check_pass(const char *pass, size_t plen) * NULL password, and for the password with zero length. */ int -_gnutls_pkcs12_string_to_key(unsigned int id, const uint8_t * salt, +_gnutls_pkcs12_string_to_key(const mac_entry_st * me, + unsigned int id, const uint8_t * salt, unsigned int salt_size, unsigned int iter, const char *pw, unsigned int req_keylen, uint8_t * keybuf) @@ -65,10 +66,11 @@ _gnutls_pkcs12_string_to_key(unsigned int id, const uint8_t * salt, bigint_t num_b1 = NULL, num_ij = NULL; bigint_t mpi512 = NULL; unsigned int pwlen; - uint8_t hash[20], buf_b[64], buf_i[MAX_PASS_LEN * 2 + 64], *p; + uint8_t hash[MAX_HASH_SIZE], buf_b[64], buf_i[MAX_PASS_LEN * 2 + 64], *p; uint8_t d[64]; size_t cur_keylen; size_t n, m, p_size, i_size; + unsigned mac_len; const uint8_t buf_512[] = /* 2^64 */ { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -122,9 +124,10 @@ _gnutls_pkcs12_string_to_key(unsigned int id, const uint8_t * salt, memset(p, 0, p_size); i_size = 64 + p_size; + mac_len = _gnutls_mac_get_algo_len(me); for (;;) { - rc = _gnutls_hash_init(&md, mac_to_entry(GNUTLS_MAC_SHA1)); + rc = _gnutls_hash_init(&md, me); if (rc < 0) { gnutls_assert(); goto cleanup; @@ -134,14 +137,13 @@ _gnutls_pkcs12_string_to_key(unsigned int id, const uint8_t * salt, _gnutls_hash(&md, buf_i, pw ? i_size : 64); _gnutls_hash_deinit(&md, hash); for (i = 1; i < iter; i++) { - rc = _gnutls_hash_fast(GNUTLS_MAC_SHA1, hash, 20, - hash); + rc = _gnutls_hash_fast(me->id, hash, mac_len, hash); if (rc < 0) { gnutls_assert(); goto cleanup; } } - for (i = 0; i < 20 && cur_keylen < req_keylen; i++) + for (i = 0; i < mac_len && cur_keylen < req_keylen; i++) keybuf[cur_keylen++] = hash[i]; if (cur_keylen == req_keylen) { rc = 0; /* ready */ @@ -150,7 +152,7 @@ _gnutls_pkcs12_string_to_key(unsigned int id, const uint8_t * salt, /* need more bytes. */ for (i = 0; i < 64; i++) - buf_b[i] = hash[i % 20]; + buf_b[i] = hash[i % mac_len]; n = 64; rc = _gnutls_mpi_scan(&num_b1, buf_b, n); if (rc < 0) { diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c index 53838ca8d5..81c1c09dd8 100644 --- a/lib/x509/privkey_pkcs8.c +++ b/lib/x509/privkey_pkcs8.c @@ -829,7 +829,8 @@ read_pkcs_schema_params(schema_id * schema, const char *password, if (enc_params->iv_size) { result = - _gnutls_pkcs12_string_to_key(2 /*IV*/, + _gnutls_pkcs12_string_to_key(mac_to_entry(GNUTLS_MAC_SHA1), + 2 /*IV*/, kdf_params->salt, kdf_params-> salt_size, @@ -1684,7 +1685,8 @@ decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn, break; default: result = - _gnutls_pkcs12_string_to_key(1 /*KEY*/, + _gnutls_pkcs12_string_to_key(mac_to_entry(GNUTLS_MAC_SHA1), + 1 /*KEY*/, kdf_params->salt, kdf_params->salt_size, kdf_params->iter_count, @@ -2016,7 +2018,8 @@ generate_key(schema_id schema, default: ret = - _gnutls_pkcs12_string_to_key(1 /*KEY*/, + _gnutls_pkcs12_string_to_key(mac_to_entry(GNUTLS_MAC_SHA1), + 1 /*KEY*/, kdf_params->salt, kdf_params->salt_size, kdf_params->iter_count, @@ -2032,7 +2035,8 @@ generate_key(schema_id schema, */ if (enc_params->iv_size) { ret = - _gnutls_pkcs12_string_to_key(2 /*IV*/, + _gnutls_pkcs12_string_to_key(mac_to_entry(GNUTLS_MAC_SHA1), + 2 /*IV*/, kdf_params->salt, kdf_params-> salt_size, diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index 9011869b8e..1648dcdb2a 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -320,7 +320,8 @@ typedef struct gnutls_pkcs12_bag_int { #define KEY_ID_OID "1.2.840.113549.1.9.21" int -_gnutls_pkcs12_string_to_key(unsigned int id, const uint8_t * salt, +_gnutls_pkcs12_string_to_key(const mac_entry_st * me, + unsigned int id, const uint8_t * salt, unsigned int salt_size, unsigned int iter, const char *pw, unsigned int req_keylen, uint8_t * keybuf); |