summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2016-11-20 17:03:02 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-11-20 19:23:42 +0100
commit48bf033618f81c2b8ad41485c471669e9446c06a (patch)
treec1024e60be44bf81a46665726e973633110db12a
parentf0a1af21552e9ba6e6bf6ce54edb3d464258791f (diff)
downloadgnutls-48bf033618f81c2b8ad41485c471669e9446c06a.tar.gz
tolerate non-valid UTF8 passwords when decrypting
-rw-r--r--lib/includes/gnutls/gnutls.h.in1
-rw-r--r--lib/srp.c8
-rw-r--r--lib/str-unicode.c19
-rw-r--r--lib/str.h7
-rw-r--r--lib/tpm.c18
-rw-r--r--lib/x509/crq.c2
-rw-r--r--lib/x509/pkcs7-crypt.c4
-rw-r--r--lib/x509/privkey_openssl.c2
8 files changed, 39 insertions, 22 deletions
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index c8b6227d5b..df46d01764 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -2518,6 +2518,7 @@ typedef struct gnutls_buffer_st *gnutls_buffer_t;
int gnutls_buffer_append_data(gnutls_buffer_t, const void *data, size_t data_size);
+#define GNUTLS_UTF8_IGNORE_ERRS 1
int gnutls_utf8_password_normalize(const unsigned char *password, unsigned password_len,
gnutls_datum_t *out, unsigned flags);
diff --git a/lib/srp.c b/lib/srp.c
index 7fb8c6329b..868c7066a0 100644
--- a/lib/srp.c
+++ b/lib/srp.c
@@ -288,7 +288,7 @@ error:
static int
_gnutls_calc_srp_sha(const char *username, const char *_password,
uint8_t * salt, int salt_size, size_t * size,
- void *digest)
+ void *digest, unsigned allow_invalid_pass)
{
digest_hd_st td;
uint8_t res[MAX_HASH_SIZE];
@@ -299,7 +299,7 @@ _gnutls_calc_srp_sha(const char *username, const char *_password,
*size = 20;
- ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout);
+ ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout, allow_invalid_pass);
if (ret < 0)
return gnutls_assert_val(ret);
password = (char*)pout.data;
@@ -338,7 +338,7 @@ _gnutls_calc_srp_x(char *username, char *password, uint8_t * salt,
{
return _gnutls_calc_srp_sha(username, password, salt,
- salt_size, size, digest);
+ salt_size, size, digest, 1);
}
@@ -747,7 +747,7 @@ gnutls_srp_verifier(const char *username, const char *password,
uint8_t digest[20];
ret = _gnutls_calc_srp_sha(username, password, salt->data,
- salt->size, &digest_size, digest);
+ salt->size, &digest_size, digest, 0);
if (ret < 0) {
gnutls_assert();
return ret;
diff --git a/lib/str-unicode.c b/lib/str-unicode.c
index c83d1daec8..315482d654 100644
--- a/lib/str-unicode.c
+++ b/lib/str-unicode.c
@@ -40,7 +40,12 @@
* to the normalization rules in RFC7613. If GnuTLS is compiled without
* unicode support this function will return %GNUTLS_E_UNIMPLEMENTED_FEATURE.
*
+ * If the flag %GNUTLS_UTF8_IGNORE_ERRS is specified, any UTF-8 encoding
+ * errors will be ignored, and in that case the output will be a copy of the input.
+ *
* Returns: %GNUTLS_E_INVALID_UTF8_STRING on invalid UTF-8 data, or 0 on success.
+ *
+ * Since: 3.5.7
**/
int gnutls_utf8_password_normalize(const unsigned char *password, unsigned password_len,
gnutls_datum_t *out, unsigned flags)
@@ -66,7 +71,17 @@ 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_INVALID_UTF8_STRING;
+ if (flags & GNUTLS_UTF8_IGNORE_ERRS) {
+ out->data = gnutls_malloc(password_len+1);
+ if (out->data == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ out->size = password_len;
+ memcpy(out->data, password, password_len);
+ out->data[password_len] = 0;
+ return 0;
+ } else {
+ return GNUTLS_E_INVALID_UTF8_STRING;
+ }
}
/* convert to UTF-32 */
@@ -132,7 +147,7 @@ int gnutls_utf8_password_normalize(const unsigned char *password, unsigned passw
int gnutls_utf8_password_normalize(const uint8_t *password, unsigned password_len,
gnutls_datum_t *out, unsigned flags)
{
- if (!(flags & NORM_INTERNAL))
+ if (!(flags & GNUTLS_UTF8_NORM_INTERNAL))
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
out->data = gnutls_malloc(password_len+1);
diff --git a/lib/str.h b/lib/str.h
index 86a35189a0..54c0652553 100644
--- a/lib/str.h
+++ b/lib/str.h
@@ -36,12 +36,13 @@
# define N_(String) String
#endif
-#define NORM_INTERNAL 1
+#define GNUTLS_UTF8_NORM_INTERNAL (1<<16)
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)
+#define _gnutls_utf8_password_normalize(p, plen, out, ignore_errs) \
+ gnutls_utf8_password_normalize((unsigned char*)p, plen, out, \
+ ignore_errs?(GNUTLS_UTF8_NORM_INTERNAL|GNUTLS_UTF8_IGNORE_ERRS):GNUTLS_UTF8_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,
diff --git a/lib/tpm.c b/lib/tpm.c
index 66a10c071d..23e44799a5 100644
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -3,7 +3,7 @@
*
* Copyright © 2012 Free Software Foundation.
* Copyright © 2008-2012 Intel Corporation.
- * Copyright © 2015 Red Hat, Inc.
+ * Copyright © 2015-2016 Red Hat, Inc.
*
* Author: David Woodhouse <dwmw2@infradead.org>
* Author: Nikos Mavrogiannopoulos
@@ -366,7 +366,7 @@ static TSS_RESULT myTspi_Policy_SetSecret(TSS_HPOLICY hPolicy,
#define SAFE_LEN(x) (x==NULL?0:strlen(x))
-static int tpm_open_session(struct tpm_ctx_st *s, const char *_srk_password)
+static int tpm_open_session(struct tpm_ctx_st *s, const char *_srk_password, unsigned allow_invalid_pass)
{
int err, ret;
char *password = NULL;
@@ -379,7 +379,7 @@ static int tpm_open_session(struct tpm_ctx_st *s, const char *_srk_password)
if (_srk_password != NULL) {
gnutls_datum_t pout;
- ret = _gnutls_utf8_password_normalize(_srk_password, strlen(_srk_password), &pout);
+ ret = _gnutls_utf8_password_normalize(_srk_password, strlen(_srk_password), &pout, allow_invalid_pass);
if (ret < 0) {
gnutls_assert();
goto out_tspi_ctx;
@@ -589,7 +589,7 @@ import_tpm_key(gnutls_privkey_t pkey,
if (_key_password != NULL) {
gnutls_datum_t pout;
- ret = _gnutls_utf8_password_normalize(_key_password, strlen(_key_password), &pout);
+ ret = _gnutls_utf8_password_normalize(_key_password, strlen(_key_password), &pout, 1);
if (ret < 0) {
gnutls_assert();
goto out_ctx;
@@ -599,7 +599,7 @@ import_tpm_key(gnutls_privkey_t pkey,
/* normalization of srk_password happens in tpm_open_session() */
- ret = tpm_open_session(s, srk_password);
+ ret = tpm_open_session(s, srk_password, 1);
if (ret < 0) {
gnutls_assert();
goto out_ctx;
@@ -1123,7 +1123,7 @@ import_tpm_pubkey(gnutls_pubkey_t pkey,
int err, ret;
struct tpm_ctx_st s;
- ret = tpm_open_session(&s, srk_password);
+ ret = tpm_open_session(&s, srk_password, 1);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -1403,7 +1403,7 @@ gnutls_tpm_privkey_generate(gnutls_pk_algorithm_t pk, unsigned int bits,
else
tpm_flags |= TSS_KEY_SIZE_16384;
- ret = tpm_open_session(&s, srk_password);
+ ret = tpm_open_session(&s, srk_password, 0);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -1462,7 +1462,7 @@ gnutls_tpm_privkey_generate(gnutls_pk_algorithm_t pk, unsigned int bits,
goto err_sa;
}
- ret = _gnutls_utf8_password_normalize(key_password, strlen(key_password), &pout);
+ ret = _gnutls_utf8_password_normalize(key_password, strlen(key_password), &pout, 0);
if (ret < 0) {
gnutls_assert();
goto err_sa;
@@ -1770,7 +1770,7 @@ int gnutls_tpm_privkey_delete(const char *url, const char *srk_password)
if (durl.uuid_set == 0)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- ret = tpm_open_session(&s, srk_password);
+ ret = tpm_open_session(&s, srk_password, 1);
if (ret < 0)
return gnutls_assert_val(ret);
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index a3a00c5ba8..4135db26e7 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -1092,7 +1092,7 @@ gnutls_x509_crq_set_challenge_password(gnutls_x509_crq_t crq,
if (pass) {
gnutls_datum_t out;
- result = _gnutls_utf8_password_normalize(pass, strlen(pass), &out);
+ result = _gnutls_utf8_password_normalize(pass, strlen(pass), &out, 0);
if (result < 0)
return gnutls_assert_val(result);
diff --git a/lib/x509/pkcs7-crypt.c b/lib/x509/pkcs7-crypt.c
index b5f6bb1612..0e23f6b73a 100644
--- a/lib/x509/pkcs7-crypt.c
+++ b/lib/x509/pkcs7-crypt.c
@@ -1013,7 +1013,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, ASN1_TYPE pkcs8_asn,
if (_password) {
gnutls_datum_t pout;
- ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout);
+ ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout, 1);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -1345,7 +1345,7 @@ _gnutls_pkcs_generate_key(schema_id schema,
if (_password) {
gnutls_datum_t pout;
- ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout);
+ ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout, 0);
if (ret < 0)
return gnutls_assert_val(ret);
diff --git a/lib/x509/privkey_openssl.c b/lib/x509/privkey_openssl.c
index 643b3788f7..c611fe8f48 100644
--- a/lib/x509/privkey_openssl.c
+++ b/lib/x509/privkey_openssl.c
@@ -45,7 +45,7 @@ openssl_hash_password(const char *_password, gnutls_datum_t * key,
if (_password != NULL) {
gnutls_datum_t pout;
- ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout);
+ ret = _gnutls_utf8_password_normalize(_password, strlen(_password), &pout, 1);
if (ret < 0)
return gnutls_assert_val(ret);