From: Nikos Mavrogiannopoulos Date: Tue, 28 Feb 2017 09:59:28 +0000 (+0100) Subject: Added _gnutls_idna_email_reverse_map X-Git-Tag: gnutls_3_6_0~932 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=322100554eb0bd4d571cc2efb23e4a87fb98cba6;p=thirdparty%2Fgnutls.git Added _gnutls_idna_email_reverse_map This allows printing the reverse map of an IDNA-encoded email. Modified x509/output to include this decoding for RFC822Name. Signed-off-by: Nikos Mavrogiannopoulos --- diff --git a/lib/str-idna.c b/lib/str-idna.c index 9e4548a4d6..bb086fb120 100644 --- a/lib/str-idna.c +++ b/lib/str-idna.c @@ -342,3 +342,39 @@ int _gnutls_idna_email_map(const char *input, unsigned ilen, gnutls_datum_t *out return gnutls_assert_val(GNUTLS_E_INVALID_UTF8_EMAIL); } } + +int _gnutls_idna_email_reverse_map(const char *input, unsigned ilen, gnutls_datum_t *output) +{ + const char *p = input; + + while(*p != 0 && *p != '@') { + if (!c_isprint(*p)) + return gnutls_assert_val(GNUTLS_E_INVALID_UTF8_EMAIL); + p++; + } + + if (*p == '@') { + unsigned name_part = p-input; + int ret; + gnutls_datum_t domain; + + ret = gnutls_idna_reverse_map(p+1, ilen-name_part-1, &domain, 0); + if (ret < 0) + return gnutls_assert_val(ret); + + output->data = gnutls_malloc(name_part+1+domain.size+1); + if (output->data == NULL) { + gnutls_free(domain.data); + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + } + memcpy(output->data, input, name_part); + output->data[name_part] = '@'; + memcpy(&output->data[name_part+1], domain.data, domain.size); + output->data[name_part+domain.size+1] = 0; + output->size = name_part+domain.size+1; + gnutls_free(domain.data); + return 0; + } else { + return gnutls_assert_val(GNUTLS_E_INVALID_UTF8_EMAIL); + } +} diff --git a/lib/str.h b/lib/str.h index b40202eb5c..e5af223f16 100644 --- a/lib/str.h +++ b/lib/str.h @@ -47,6 +47,7 @@ int gnutls_utf8_password_normalize(const uint8_t *password, unsigned password_le ignore_errs?(GNUTLS_UTF8_IGNORE_ERRS):0) int _gnutls_idna_email_map(const char *input, unsigned ilen, gnutls_datum_t *output); +int _gnutls_idna_email_reverse_map(const char *input, unsigned ilen, gnutls_datum_t *output); inline static unsigned _gnutls_str_is_print(const char *str, unsigned size) { diff --git a/lib/x509/output.c b/lib/x509/output.c index a2d789a081..fddf7be907 100644 --- a/lib/x509/output.c +++ b/lib/x509/output.c @@ -70,6 +70,36 @@ static void print_idn_name(gnutls_buffer_st *str, const char *prefix, const char } } +static void print_idn_email(gnutls_buffer_st *str, const char *prefix, const char *type, gnutls_datum_t *name) +{ + unsigned printable = 1; + unsigned is_printed = 0; + gnutls_datum_t out = {NULL, 0}; + int ret; + + if (!_gnutls_str_is_print((char*)name->data, name->size)) + printable = 0; + + is_printed = 0; + if (!printable) { + addf(str, _("%s%s: %.*s (contains illegal chars)\n"), prefix, type, name->size, NON_NULL(name->data)); + is_printed = 1; + } else if (name->data != NULL) { + if (strstr((char*)name->data, "xn--") != NULL) { + ret = _gnutls_idna_email_reverse_map((char*)name->data, name->size, &out); + if (ret >= 0) { + addf(str, _("%s%s: %.*s (%s)\n"), prefix, type, name->size, NON_NULL(name->data), out.data); + is_printed = 1; + gnutls_free(out.data); + } + } + } + + if (is_printed == 0) { + addf(str, _("%s%s: %.*s\n"), prefix, type, name->size, NON_NULL(name->data)); + } +} + static void print_name(gnutls_buffer_st *str, const char *prefix, unsigned type, gnutls_datum_t *name, unsigned ip_is_cidr) { @@ -94,7 +124,7 @@ print_name(gnutls_buffer_st *str, const char *prefix, unsigned type, gnutls_datu break; case GNUTLS_SAN_RFC822NAME: - addf(str, _("%sRFC822Name: %.*s\n"), prefix, name->size, NON_NULL(name->data)); + print_idn_email(str, prefix, "RFC822Name", name); break; case GNUTLS_SAN_URI: