From c5507dff5f5b2936937442b43f6c021b4f8a493d Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Sat, 10 Dec 2022 00:40:44 -0500 Subject: Simplify krb5_chpw_message() UTF-8 processing Only validate the message as a UTF-8 string, rather than normalizing it. --- src/include/k5-unicode.h | 2 ++ src/lib/krb5/krb/chpw.c | 10 ++++------ src/lib/krb5/unicode/ucstr.c | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/include/k5-unicode.h b/src/include/k5-unicode.h index e51ab2f..45c1788 100644 --- a/src/include/k5-unicode.h +++ b/src/include/k5-unicode.h @@ -127,4 +127,6 @@ int krb5int_utf8_normcmp( const krb5_data *, unsigned); +krb5_boolean k5_utf8_validate(const krb5_data *data); + #endif /* K5_UNICODE_H */ diff --git a/src/lib/krb5/krb/chpw.c b/src/lib/krb5/krb/chpw.c index cdec595..803c80f 100644 --- a/src/lib/krb5/krb/chpw.c +++ b/src/lib/krb5/krb/chpw.c @@ -477,7 +477,6 @@ krb5_chpw_message(krb5_context context, const krb5_data *server_string, char **message_out) { krb5_error_code ret; - krb5_data *string; char *msg; *message_out = NULL; @@ -493,11 +492,10 @@ krb5_chpw_message(krb5_context context, const krb5_data *server_string, /* If server_string contains a valid UTF-8 string, return that. */ if (server_string->length > 0 && memchr(server_string->data, 0, server_string->length) == NULL && - krb5int_utf8_normalize(server_string, &string, - KRB5_UTF8_APPROX) == 0) { - *message_out = string->data; /* already null terminated */ - free(string); - return 0; + k5_utf8_validate(server_string)) { + *message_out = k5memdup0(server_string->data, server_string->length, + &ret); + return (*message_out == NULL) ? ENOMEM : 0; } /* server_string appears invalid, so try to be helpful. */ diff --git a/src/lib/krb5/unicode/ucstr.c b/src/lib/krb5/unicode/ucstr.c index e3ed9bc..0257882 100644 --- a/src/lib/krb5/unicode/ucstr.c +++ b/src/lib/krb5/unicode/ucstr.c @@ -18,6 +18,7 @@ #include "k5-int.h" #include "k5-utf8.h" #include "k5-unicode.h" +#include "k5-input.h" #include "ucdata/ucdata.h" #include @@ -100,6 +101,32 @@ krb5int_ucstr2upper( } } +/* Return true if data contains valid UTF-8 sequences. */ +krb5_boolean +k5_utf8_validate(const krb5_data *data) +{ + struct k5input in; + int len, tmplen, i; + const uint8_t *bytes; + + k5_input_init(&in, data->data, data->length); + while (!in.status && in.len > 0) { + len = KRB5_UTF8_CHARLEN(in.ptr); + if (len < 1 || len > 4) + return FALSE; + bytes = k5_input_get_bytes(&in, len); + if (bytes == NULL) + return FALSE; + if (KRB5_UTF8_CHARLEN2(bytes, tmplen) != len) + return FALSE; + for (i = 1; i < len; i++) { + if ((bytes[i] & 0xc0) != 0x80) + return FALSE; + } + } + return !in.status; +} + #define TOUPPER(c) (islower(c) ? toupper(c) : (c)) #define TOLOWER(c) (isupper(c) ? tolower(c) : (c)) -- cgit v1.1