summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2016-01-10 14:30:56 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-01-10 14:30:56 +0100
commitb992776d1e77309e9c11a7a1d9a1321caab768f6 (patch)
treed0c4b349955ee659875f92886bc26c60edbe8ef6
parent66694906e6af8c606fb57d03a5ad0a3553baa47d (diff)
downloadgnutls-b992776d1e77309e9c11a7a1d9a1321caab768f6.tar.gz
Allow assigning 'virtual' SAN types via *_set_subject_alt_name()
-rw-r--r--lib/x509/common.c12
-rw-r--r--lib/x509/common.h1
-rw-r--r--lib/x509/crq.c2
-rw-r--r--lib/x509/x509_ext.c69
-rw-r--r--lib/x509/x509_write.c4
5 files changed, 71 insertions, 17 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c
index eb0c411e54..9f76da85d8 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -142,7 +142,17 @@ int _san_othername_to_virtual(const char *oid, size_t size)
}
return GNUTLS_SAN_OTHERNAME;
-}
+}
+
+const char * _virtual_to_othername_oid(unsigned type)
+{
+ switch(type) {
+ case GNUTLS_SAN_OTHERNAME_XMPP:
+ return XMPP_OID;
+ default:
+ return NULL;
+ }
+}
static const struct oid_to_string *get_oid_entry(const char *oid)
{
diff --git a/lib/x509/common.h b/lib/x509/common.h
index b1c5450351..3c42ebdcd1 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -228,6 +228,7 @@ int _gnutls_copy_string(gnutls_datum_t* str, uint8_t *out, size_t *out_size);
int _gnutls_copy_data(gnutls_datum_t* str, uint8_t *out, size_t *out_size);
int _san_othername_to_virtual(const char *oid, size_t oid_size);
+const char *_virtual_to_othername_oid(unsigned type);
int _gnutls_x509_decode_ext(const gnutls_datum_t *der, gnutls_x509_ext_st *out);
int x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index af5afec0e0..0108aaf665 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -2018,7 +2018,7 @@ gnutls_x509_crq_get_extension_by_oid2(gnutls_x509_crq_t crq,
*
* %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
*
- * Other values can be set as binary values with the proper DER encoding.
+ * %GNUTLS_SAN_OTHERNAME_XMPP: as a UTF8 string
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.
diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c
index 889d854845..3393c8a693 100644
--- a/lib/x509/x509_ext.c
+++ b/lib/x509/x509_ext.c
@@ -129,15 +129,66 @@ int gnutls_subject_alt_names_get(gnutls_subject_alt_names_t sans,
return 0;
}
+static
+int assign_virt_type(struct name_st *name, unsigned type, gnutls_datum_t *san, const char *othername_oid)
+{
+ gnutls_datum_t encoded = {NULL, 0};
+ int ret;
+
+ if (type < 1000) {
+ name->type = type;
+ name->san.data = san->data;
+ name->san.size = san->size;
+
+ if (othername_oid) {
+ name->othername_oid.data = (uint8_t *) othername_oid;
+ name->othername_oid.size = strlen(othername_oid);
+ } else {
+ name->othername_oid.data = NULL;
+ name->othername_oid.size = 0;
+ }
+
+ } else { /* virtual types */
+ const char *oid = _virtual_to_othername_oid(type);
+
+ if (oid == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ switch(type) {
+ case GNUTLS_SAN_OTHERNAME_XMPP:
+ ret = _gnutls_x509_encode_string(ASN1_ETYPE_UTF8_STRING,
+ san->data, san->size, &encoded);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ name->type = GNUTLS_SAN_OTHERNAME;
+ name->san.data = encoded.data;
+ name->san.size = encoded.size;
+ name->othername_oid.data = (void*)gnutls_strdup(oid);
+ name->othername_oid.size = strlen(oid);
+ break;
+
+ default:
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+
+ gnutls_free(san->data);
+ }
+
+ return 0;
+}
+
/* This is the same as gnutls_subject_alt_names_set() but will not
- * copy the strings */
+ * copy the strings. It expects all the provided input to be already
+ * allocated by gnutls. */
static
int subject_alt_names_set(struct name_st **names,
unsigned int *size,
unsigned int san_type,
- const gnutls_datum_t * san, char *othername_oid)
+ gnutls_datum_t * san, char *othername_oid)
{
void *tmp;
+ int ret;
tmp = gnutls_realloc(*names, (*size + 1) * sizeof((*names)[0]));
if (tmp == NULL) {
@@ -145,17 +196,9 @@ int subject_alt_names_set(struct name_st **names,
}
*names = tmp;
- (*names)[*size].type = san_type;
- (*names)[*size].san.data = san->data;
- (*names)[*size].san.size = san->size;
-
- if (othername_oid) {
- (*names)[*size].othername_oid.data = (uint8_t *) othername_oid;
- (*names)[*size].othername_oid.size = strlen(othername_oid);
- } else {
- (*names)[*size].othername_oid.data = NULL;
- (*names)[*size].othername_oid.size = 0;
- }
+ ret = assign_virt_type(&(*names)[*size], san_type, san, othername_oid);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
(*size)++;
return 0;
diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c
index 3c8b77641d..fec55f6926 100644
--- a/lib/x509/x509_write.c
+++ b/lib/x509/x509_write.c
@@ -586,8 +586,8 @@ gnutls_x509_crt_set_subject_alternative_name(gnutls_x509_crt_t crt,
* %GNUTLS_SAN_URI: as a text string
*
* %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
- *
- * Other values can be set as binary values with the proper DER encoding.
+ *
+ * %GNUTLS_SAN_OTHERNAME_XMPP: as a UTF8 string
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.