summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-11-25 11:34:19 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-11-25 15:11:58 +0100
commitb6487b7208656233700061b75b76f212887cc12a (patch)
treeeb648de76ae959020c1a2f729f86a6481110de2c
parent523e329db10e713e946171c7fae5aa3bb9b3e243 (diff)
downloadgnutls-b6487b7208656233700061b75b76f212887cc12a.tar.gz
introduced _gnutls_idna_reverse_map()
This function allows mapping ACE formatted domains to UTF-8.
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/str-unicode.c63
-rw-r--r--lib/str.h2
3 files changed, 66 insertions, 0 deletions
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;