From b6487b7208656233700061b75b76f212887cc12a Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 25 Nov 2016 11:34:19 +0100 Subject: introduced _gnutls_idna_reverse_map() This function allows mapping ACE formatted domains to UTF-8. --- lib/libgnutls.map | 1 + lib/str-unicode.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/str.h | 2 ++ 3 files changed, 66 insertions(+) diff --git a/lib/libgnutls.map b/lib/libgnutls.map index a15c1a3ca9..04b55d9b1a 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1199,4 +1199,5 @@ GNUTLS_PRIVATE_3_4 { _gnutls_x509_name_constraints_merge; _gnutls_server_name_set_raw; _gnutls_idna_map; + _gnutls_idna_reverse_map; }; diff --git a/lib/str-unicode.c b/lib/str-unicode.c index 07a93985f1..9820f86afb 100644 --- a/lib/str-unicode.c +++ b/lib/str-unicode.c @@ -209,6 +209,64 @@ int _gnutls_idna_map(const char *input, unsigned ilen, gnutls_datum_t *out, unsi return ret; } +/*- + * _gnutls_idna_reverse_map: + * @input: contain the ACE (IDNA) formatted domain name + * @ilen: the length of the provided string + * @out: the result in an null-terminated allocated UTF-8 string + * @flags: should be zero + * + * This function will convert the IDNA2003 ACE name to a UTF-8 domain name. + * + * If GnuTLS is compiled without libidn2 support, then this function + * will return %GNUTLS_E_UNIMPLEMENTED_FEATURE. + * + * Returns: A negative error code on error, or 0 on success. + * + * Since: 3.5.7 + -*/ +int _gnutls_idna_reverse_map(const char *input, unsigned ilen, gnutls_datum_t *out, unsigned flags) +{ + char *u8 = NULL; + int rc, ret; + gnutls_datum_t istr; + + if (ilen == 0) { + out->data = (uint8_t*)gnutls_strdup(""); + out->size = 0; + if (out->data == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + return 0; + } + + ret = _gnutls_set_strdatum(&istr, input, ilen); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + rc = idna_to_unicode_8z8z((char*)istr.data, &u8, IDNA_ALLOW_UNASSIGNED); + if (rc != IDNA_SUCCESS) { + gnutls_assert(); + _gnutls_debug_log("unable to convert ACE name '%s' to UTF-8 format: %s\n", istr.data, idna_strerror(rc)); + ret = GNUTLS_E_INVALID_UTF8_STRING; + goto fail; + } + + if (gnutls_malloc != malloc) { + ret = _gnutls_set_strdatum(out, u8, strlen(u8)); + } else { + out->data = (unsigned char*)u8; + out->size = strlen(u8); + u8 = NULL; + ret = 0; + } + fail: + idn_free(u8); + gnutls_free(istr.data); + return ret; +} + #else # undef gnutls_idna_map @@ -216,6 +274,11 @@ int _gnutls_idna_map(const char *input, unsigned ilen, gnutls_datum_t *out, unsi { return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); } + +int _gnutls_idna_reverse_map(const char *input, unsigned ilen, gnutls_datum_t *out, unsigned flags) +{ + return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); +} #endif /* HAVE_LIBIDN2 */ int _gnutls_idna_email_map(const char *input, unsigned ilen, gnutls_datum_t *output) diff --git a/lib/str.h b/lib/str.h index e9ae3f0204..fe8b38e2b3 100644 --- a/lib/str.h +++ b/lib/str.h @@ -66,6 +66,8 @@ int __gnutls_idna_map(const char *input, unsigned ilen, gnutls_datum_t *out, uns int _gnutls_idna_map(const char * input, unsigned ilen, gnutls_datum_t *out, unsigned flags); #endif +int _gnutls_idna_reverse_map(const char * input, unsigned ilen, gnutls_datum_t *out, unsigned flags); + inline static unsigned _gnutls_str_is_print(const char *str, unsigned size) { unsigned i; -- cgit v1.2.1