summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2014-08-11 10:00:52 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2014-08-11 10:02:01 +0200
commit6f711afc06bc7d1a1b291bd0a03852cfc7ce99d4 (patch)
tree404a7647738a44884f6e8048e9a9f5a35e19f667
parentf94cb533e5d1a87f529a619262b2409f5db5ed37 (diff)
downloadgnutls-6f711afc06bc7d1a1b291bd0a03852cfc7ce99d4.tar.gz
pkcs11: Allow verification with structures that support other than HMAC-SHA1 MACs.
-rw-r--r--lib/algorithms.h1
-rw-r--r--lib/x509/pkcs12.c49
-rw-r--r--lib/x509/pkcs12_encr.c15
-rw-r--r--lib/x509/privkey_pkcs8.c8
-rw-r--r--lib/x509/x509_int.h2
5 files changed, 51 insertions, 24 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h
index ee88e8c305..5cb9818d2d 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -50,6 +50,7 @@ int _gnutls_version_has_explicit_iv (gnutls_protocol_t version);
/* Functions for MACs. */
int _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm);
+#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);
const char *_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t mac);
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index a7218ca93b..db0f6e3802 100644
--- a/lib/x509/pkcs12.c
+++ b/lib/x509/pkcs12.c
@@ -918,7 +918,7 @@ 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),
+ result = _gnutls_pkcs12_string_to_key (GNUTLS_MAC_SHA1, 3 /*MAC*/, salt, sizeof (salt),
iter, pass, sizeof (key), key);
if (result < 0)
{
@@ -1001,7 +1001,8 @@ cleanup:
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;
@@ -1009,8 +1010,11 @@ gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
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;
+
if (pkcs12 == NULL)
{
@@ -1028,22 +1032,40 @@ 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)
+ {
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
+ }
+
+ mac_len = _gnutls_hmac_get_algo_len(algo);
+ 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);
+ result = _gnutls_pkcs12_string_to_key (algo, 3 /*MAC*/, salt.data, salt.size,
+ iter, pass, key_len, key);
if (result < 0)
{
gnutls_assert ();
@@ -1063,7 +1085,7 @@ gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
/* MAC the data
*/
- result = _gnutls_hmac_init (&td1, GNUTLS_MAC_SHA1, key, sizeof (key));
+ result = _gnutls_hmac_init (&td1, algo, key, key_len);
if (result < 0)
{
gnutls_assert ();
@@ -1073,11 +1095,11 @@ gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
_gnutls_hmac (&td1, tmp.data, tmp.size);
_gnutls_free_datum (&tmp);
- _gnutls_hmac_deinit (&td1, sha_mac);
+ _gnutls_hmac_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,
+ asn1_read_value (pkcs12->pkcs12, "macData.mac.digest", mac_output_orig,
&len);
if (result != ASN1_SUCCESS)
{
@@ -1086,7 +1108,8 @@ gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
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 cdb86f6fee..86e5bf0b71 100644
--- a/lib/x509/pkcs12_encr.c
+++ b/lib/x509/pkcs12_encr.c
@@ -55,7 +55,8 @@ _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 (gnutls_mac_algorithm_t algo,
+ unsigned int id, const uint8_t * salt,
unsigned int salt_size, unsigned int iter,
const char *pw, unsigned int req_keylen,
uint8_t * keybuf)
@@ -66,10 +67,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,
@@ -129,10 +131,11 @@ _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_hmac_get_algo_len(algo);
for (;;)
{
- rc = _gnutls_hash_init (&md, GNUTLS_MAC_SHA1);
+ rc = _gnutls_hash_init (&md, algo);
if (rc < 0)
{
gnutls_assert ();
@@ -144,14 +147,14 @@ _gnutls_pkcs12_string_to_key (unsigned int id, const uint8_t * salt,
_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 (algo, 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)
{
@@ -161,7 +164,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 205b74c00a..bba8f47114 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -873,7 +873,7 @@ read_pkcs_schema_params (schema_id * schema, const char *password,
if (enc_params->iv_size)
{
result =
- _gnutls_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
+ _gnutls_pkcs12_string_to_key (GNUTLS_MAC_SHA1, 2 /*IV*/, kdf_params->salt,
kdf_params->salt_size,
kdf_params->iter_count, password,
enc_params->iv_size,
@@ -1767,7 +1767,7 @@ decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
break;
default:
result =
- _gnutls_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
+ _gnutls_pkcs12_string_to_key (GNUTLS_MAC_SHA1, 1 /*KEY*/, kdf_params->salt,
kdf_params->salt_size,
kdf_params->iter_count, password,
key_size, key);
@@ -2113,7 +2113,7 @@ generate_key (schema_id schema,
default:
ret =
- _gnutls_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
+ _gnutls_pkcs12_string_to_key (GNUTLS_MAC_SHA1, 1 /*KEY*/, kdf_params->salt,
kdf_params->salt_size,
kdf_params->iter_count, password,
kdf_params->key_size, key->data);
@@ -2128,7 +2128,7 @@ generate_key (schema_id schema,
if (enc_params->iv_size)
{
ret =
- _gnutls_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
+ _gnutls_pkcs12_string_to_key (GNUTLS_MAC_SHA1, 2 /*IV*/, kdf_params->salt,
kdf_params->salt_size,
kdf_params->iter_count, password,
enc_params->iv_size,
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index 8d6f766067..11f4711292 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -322,7 +322,7 @@ 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 (gnutls_mac_algorithm_t, unsigned int id, const uint8_t * salt,
unsigned int salt_size, unsigned int iter,
const char *pw, unsigned int req_keylen,
uint8_t * keybuf);