]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added _gnutls_idna_email_reverse_map
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 28 Feb 2017 09:59:28 +0000 (10:59 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 28 Feb 2017 13:15:06 +0000 (14:15 +0100)
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 <nmav@redhat.com>
lib/str-idna.c
lib/str.h
lib/x509/output.c

index 9e4548a4d65feeeb07be956485ce684e771c6c7c..bb086fb1202af7532ceb9ebb6bc481b68ac15339 100644 (file)
@@ -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);
+       }
+}
index b40202eb5c1153b1f6715d1c937702b809081632..e5af223f16f6c6f3aded93446fb3130576854b84 100644 (file)
--- 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)
 {
index a2d789a0813ee48411c9e4032157fb5e773270e7..fddf7be907c9de45ba1924196f231da705e04129 100644 (file)
@@ -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: