summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-11-09 10:48:04 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-11-20 17:31:49 +0100
commita54cec97d068291eb0ad1588f6edf07770aa557f (patch)
tree0387cad863590abd267614a7bfe96d56fe99697d
parent28ac7caaf13f12d009cd8bc649bf82bcb051619f (diff)
downloadgnutls-a54cec97d068291eb0ad1588f6edf07770aa557f.tar.gz
PKCS#7/8: normalize the password according to rfc7613
-rw-r--r--lib/errors.c2
-rw-r--r--lib/includes/gnutls/gnutls.h.in1
-rw-r--r--lib/str-unicode.c4
-rw-r--r--lib/str.h3
-rw-r--r--lib/x509/pkcs7-crypt.c103
5 files changed, 77 insertions, 36 deletions
diff --git a/lib/errors.c b/lib/errors.c
index 9f46374978..cc46c1172e 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -272,6 +272,8 @@ static const gnutls_error_entry error_entries[] = {
GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE),
ERROR_ENTRY(N_("The given password contains invalid characters."),
GNUTLS_E_INVALID_PASSWORD),
+ ERROR_ENTRY(N_("The given string contains invalid UTF-8 characters."),
+ GNUTLS_E_INVALID_UTF8_STRING),
ERROR_ENTRY(N_
("The Message Authentication Code verification failed."),
GNUTLS_E_MAC_VERIFY_FAILED),
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 1149319c29..c8b6227d5b 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -2824,6 +2824,7 @@ unsigned gnutls_fips140_mode_enabled(void);
#define GNUTLS_E_PK_INVALID_PUBKEY -409
#define GNUTLS_E_PK_INVALID_PRIVKEY -410
#define GNUTLS_E_NOT_YET_ACTIVATED -411
+#define GNUTLS_E_INVALID_UTF8_STRING -412
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
diff --git a/lib/str-unicode.c b/lib/str-unicode.c
index 544ce1da84..c83d1daec8 100644
--- a/lib/str-unicode.c
+++ b/lib/str-unicode.c
@@ -40,7 +40,7 @@
* to the normalization rules in RFC7613. If GnuTLS is compiled without
* unicode support this function will return %GNUTLS_E_UNIMPLEMENTED_FEATURE.
*
- * Returns: %GNUTLS_E_PARSING_ERROR on invalid UTF-8 data, or 0 on success.
+ * Returns: %GNUTLS_E_INVALID_UTF8_STRING on invalid UTF-8 data, or 0 on success.
**/
int gnutls_utf8_password_normalize(const unsigned char *password, unsigned password_len,
gnutls_datum_t *out, unsigned flags)
@@ -66,7 +66,7 @@ int gnutls_utf8_password_normalize(const unsigned char *password, unsigned passw
/* check for invalid UTF-8 */
if (u8_check((uint8_t*)password, plen) != NULL) {
gnutls_assert();
- return GNUTLS_E_PARSING_ERROR;
+ return GNUTLS_E_INVALID_UTF8_STRING;
}
/* convert to UTF-32 */
diff --git a/lib/str.h b/lib/str.h
index fe9055b3eb..86a35189a0 100644
--- a/lib/str.h
+++ b/lib/str.h
@@ -40,6 +40,9 @@
int gnutls_utf8_password_normalize(const uint8_t *password, unsigned password_len,
gnutls_datum_t *out, unsigned flags);
+#define _gnutls_utf8_password_normalize(p, plen, out) \
+ gnutls_utf8_password_normalize((unsigned char*)p, plen, out, NORM_INTERNAL)
+
void _gnutls_str_cpy(char *dest, size_t dest_tot_size, const char *src);
void _gnutls_mem_cpy(char *dest, size_t dest_tot_size, const char *src,
size_t src_size);
diff --git a/lib/x509/pkcs7-crypt.c b/lib/x509/pkcs7-crypt.c
index 6d6b743c58..b5f6bb1612 100644
--- a/lib/x509/pkcs7-crypt.c
+++ b/lib/x509/pkcs7-crypt.c
@@ -994,37 +994,48 @@ _gnutls_read_pkcs_schema_params(schema_id * schema, const char *password,
int
_gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
- const char *root, const char *password,
+ const char *root, const char *_password,
const struct pbkdf2_params *kdf_params,
const struct pbe_enc_params *enc_params,
gnutls_datum_t * decrypted_data)
{
- int result;
gnutls_datum_t enc = { NULL, 0 };
uint8_t *key = NULL;
gnutls_datum_t dkey, d_iv;
cipher_hd_st ch;
int ch_init = 0;
- int key_size;
+ int key_size, ret;
unsigned int pass_len = 0;
const struct pkcs_cipher_schema_st *p;
unsigned block_size;
const cipher_entry_st *ce;
+ char *password;
- if (password)
- pass_len = strlen(password);
+ if (_password) {
+ gnutls_datum_t pout;
+ ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
- result = _gnutls_x509_read_value(pkcs8_asn, root, &enc);
- if (result < 0) {
+ password = (char*)pout.data;
+ pass_len = pout.size;
+ } else {
+ password = NULL;
+ pass_len = 0;
+ }
+
+ ret = _gnutls_x509_read_value(pkcs8_asn, root, &enc);
+ if (ret < 0) {
gnutls_assert();
- return _gnutls_asn2err(result);
+ goto cleanup;
}
if (schema == PBES1_DES_MD5) {
- return _gnutls_decrypt_pbes1_des_md5_data(password, pass_len,
+ ret = _gnutls_decrypt_pbes1_des_md5_data(password, pass_len,
kdf_params,
enc_params, &enc,
decrypted_data);
+ goto cleanup;
}
if (kdf_params->key_size == 0) {
@@ -1035,7 +1046,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
key = gnutls_malloc(key_size);
if (key == NULL) {
gnutls_assert();
- result = GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
goto error;
}
@@ -1054,12 +1065,12 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
kdf_params->salt_size,
kdf_params->salt, key_size, key);
else {
- result =
+ ret =
gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
goto error;
}
} else if (p != NULL) { /* PKCS 12 schema */
- result =
+ ret =
_gnutls_pkcs12_string_to_key(mac_to_entry(GNUTLS_MAC_SHA1),
1 /*KEY*/,
kdf_params->salt,
@@ -1067,13 +1078,13 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
kdf_params->iter_count,
password, key_size, key);
- if (result < 0) {
+ if (ret < 0) {
gnutls_assert();
goto error;
}
} else {
gnutls_assert();
- result = GNUTLS_E_UNKNOWN_CIPHER_TYPE;
+ ret = GNUTLS_E_UNKNOWN_CIPHER_TYPE;
goto error;
}
@@ -1082,7 +1093,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
if (ce->type == CIPHER_BLOCK && (enc.size % block_size != 0)) {
gnutls_assert();
- result = GNUTLS_E_ILLEGAL_PARAMETER;
+ ret = GNUTLS_E_ILLEGAL_PARAMETER;
goto error;
}
@@ -1093,21 +1104,22 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
d_iv.data = (uint8_t *) enc_params->iv;
d_iv.size = enc_params->iv_size;
- result =
+
+ ret =
_gnutls_cipher_init(&ch, ce, &dkey, &d_iv, 0);
gnutls_free(key);
key = NULL;
- if (result < 0) {
+ if (ret < 0) {
gnutls_assert();
goto error;
}
ch_init = 1;
- result = _gnutls_cipher_decrypt(&ch, enc.data, enc.size);
- if (result < 0) {
+ ret = _gnutls_cipher_decrypt(&ch, enc.data, enc.size);
+ if (ret < 0) {
gnutls_assert();
goto error;
}
@@ -1120,7 +1132,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
if (pslen > block_size || pslen >= enc.size || pslen == 0) {
gnutls_assert();
- result = GNUTLS_E_ILLEGAL_PARAMETER;
+ ret = GNUTLS_E_ILLEGAL_PARAMETER;
goto error;
}
@@ -1129,7 +1141,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
for (i=0;i<pslen;i++) {
if (enc.data[enc.size-1-i] != pslen) {
gnutls_assert();
- result = GNUTLS_E_ILLEGAL_PARAMETER;
+ ret = GNUTLS_E_ILLEGAL_PARAMETER;
goto error;
}
}
@@ -1139,14 +1151,20 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
_gnutls_cipher_deinit(&ch);
- return 0;
+ ret = 0;
+
+ cleanup:
+ gnutls_free(password);
+
+ return ret;
error:
+ gnutls_free(password);
gnutls_free(enc.data);
gnutls_free(key);
if (ch_init != 0)
_gnutls_cipher_deinit(&ch);
- return result;
+ return ret;
}
/* Writes the PBKDF2 parameters.
@@ -1314,7 +1332,7 @@ write_pbes2_enc_params(ASN1_TYPE pasn, const struct pbe_enc_params *params)
*/
int
_gnutls_pkcs_generate_key(schema_id schema,
- const char *password,
+ const char *_password,
struct pbkdf2_params *kdf_params,
struct pbe_enc_params *enc_params,
gnutls_datum_t * key)
@@ -1323,14 +1341,25 @@ _gnutls_pkcs_generate_key(schema_id schema,
unsigned int pass_len = 0;
int ret;
const struct pkcs_cipher_schema_st *p;
+ char *password = NULL;
- if (password)
- pass_len = strlen(password);
+ if (_password) {
+ gnutls_datum_t pout;
+ ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ password = (char*)pout.data;
+ pass_len = pout.size;
+ } else {
+ password = NULL;
+ pass_len = 0;
+ }
ret = gnutls_rnd(GNUTLS_RND_RANDOM, rnd, 2);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
/* generate salt */
@@ -1346,14 +1375,15 @@ _gnutls_pkcs_generate_key(schema_id schema,
kdf_params->salt_size = 8;
} else {
gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ ret = GNUTLS_E_INVALID_REQUEST;
+ goto cleanup;
}
ret = gnutls_rnd(GNUTLS_RND_RANDOM, kdf_params->salt,
kdf_params->salt_size);
if (ret < 0) {
gnutls_assert();
- return GNUTLS_E_RANDOM_FAILED;
+ goto cleanup;
}
kdf_params->iter_count = 5 * 1024 + rnd[0];
@@ -1364,7 +1394,8 @@ _gnutls_pkcs_generate_key(schema_id schema,
key->data = gnutls_malloc(key->size);
if (key->data == NULL) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
}
/* now generate the key.
@@ -1381,7 +1412,7 @@ _gnutls_pkcs_generate_key(schema_id schema,
enc_params->iv, enc_params->iv_size);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
}
} else { /* PKCS 12 schema */
@@ -1396,7 +1427,7 @@ _gnutls_pkcs_generate_key(schema_id schema,
key->data);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
/* Now generate the IV
@@ -1414,12 +1445,16 @@ _gnutls_pkcs_generate_key(schema_id schema,
enc_params->iv);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
}
}
- return 0;
+ ret = 0;
+
+ cleanup:
+ gnutls_free(password);
+ return ret;
}
/* Encodes the parameters to be written in the encryptionAlgorithm.parameters