diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-11-20 17:03:02 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-11-20 19:23:42 +0100 |
commit | 48bf033618f81c2b8ad41485c471669e9446c06a (patch) | |
tree | c1024e60be44bf81a46665726e973633110db12a | |
parent | f0a1af21552e9ba6e6bf6ce54edb3d464258791f (diff) | |
download | gnutls-48bf033618f81c2b8ad41485c471669e9446c06a.tar.gz |
tolerate non-valid UTF8 passwords when decrypting
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 1 | ||||
-rw-r--r-- | lib/srp.c | 8 | ||||
-rw-r--r-- | lib/str-unicode.c | 19 | ||||
-rw-r--r-- | lib/str.h | 7 | ||||
-rw-r--r-- | lib/tpm.c | 18 | ||||
-rw-r--r-- | lib/x509/crq.c | 2 | ||||
-rw-r--r-- | lib/x509/pkcs7-crypt.c | 4 | ||||
-rw-r--r-- | lib/x509/privkey_openssl.c | 2 |
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); @@ -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); @@ -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, @@ -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); |