summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2014-04-19 01:09:21 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2014-04-19 01:10:49 +0200
commit34384369873dc8267419b4d9c2f99f6e7e703efc (patch)
tree88251bee93893e9f9bf53fde55024aeb65a2db0b /lib
parentdb327838d7861ac485caf8b71f6f591e9cbbc184 (diff)
downloadgnutls-34384369873dc8267419b4d9c2f99f6e7e703efc.tar.gz
Corrected decoding of XMPP SAN othername.
This also corrects the semantics of the get_*_othername_oid() functions, such as gnutls_x509_crt_get_subject_alt_othername_oid().
Diffstat (limited to 'lib')
-rw-r--r--lib/x509/common.c14
-rw-r--r--lib/x509/common.h4
-rw-r--r--lib/x509/output.c5
-rw-r--r--lib/x509/x509.c40
4 files changed, 44 insertions, 19 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 77a90a7336..3376fe3cc9 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -131,6 +131,17 @@ static const struct oid_to_string _oid2str[] = {
{NULL, 0, NULL, 0, NULL, 0}
};
+int _san_othername_to_virtual(const char *oid, size_t size)
+{
+ if (oid) {
+ if ((unsigned) size == (sizeof(XMPP_OID)-1)
+ && memcmp(oid, XMPP_OID, sizeof(XMPP_OID)-1) == 0)
+ return GNUTLS_SAN_OTHERNAME_XMPP;
+ }
+
+ return GNUTLS_SAN_OTHERNAME;
+}
+
static const struct oid_to_string *get_oid_entry(const char *oid)
{
unsigned int i = 0;
@@ -1048,8 +1059,9 @@ _gnutls_x509_read_value(ASN1_TYPE c, const char *root,
if (etype == ASN1_ETYPE_BIT_STRING) {
ret->size = (len+7) / 8;
- } else
+ } else {
ret->size = (unsigned) len;
+ }
tmp[ret->size] = 0;
ret->data = tmp;
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 76c5e80704..022010df0c 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -69,6 +69,8 @@
#define SIG_GOST_R3410_2001_OID "1.2.643.2.2.3"
#define ISO_SIG_RSA_SHA1_OID "1.3.14.3.2.29"
+#define XMPP_OID "1.3.6.1.5.5.7.8.5"
+
#define ASN1_NULL "\x05\x00"
#define ASN1_NULL_SIZE 2
@@ -198,4 +200,6 @@ bool _gnutls_is_same_dn(gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2);
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);
+
#endif
diff --git a/lib/x509/output.c b/lib/x509/output.c
index 3ba6c04850..33a1b28729 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -802,7 +802,6 @@ print_altname(gnutls_buffer_st * str, const char *prefix,
return;
}
-
if (err == GNUTLS_SAN_OTHERNAME) {
char *oid = NULL;
size_t oidsize;
@@ -824,8 +823,8 @@ print_altname(gnutls_buffer_st * str, const char *prefix,
if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) {
gnutls_free(buffer);
addf(str,
- "error: get_subject/issuer_alt_othername_oid: %s\n",
- gnutls_strerror(err));
+ "error: get_subject/issuer_alt_othername_oid: %s (%d)\n",
+ gnutls_strerror(err), err);
return;
}
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 2b1933a1fe..d13c231a99 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -847,7 +847,7 @@ gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert, void *ret,
inline static int is_type_printable(int type)
{
if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
- type == GNUTLS_SAN_URI)
+ type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP)
return 1;
else
return 0;
@@ -1081,8 +1081,6 @@ gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
}
-#define XMPP_OID "1.3.6.1.5.5.7.8.5"
-
/* returns the type and the name on success.
* Type is also returned as a parameter in case of an error.
*
@@ -1090,7 +1088,7 @@ gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
* in case of GeneralName, it must be -1
* @dname: the name returned
* @ret_type: The type of the name
- * @othername_oid: if the name is AnotherName return the OID
+ * @othername_oid: if the name is otherName return the OID
*
*/
int
@@ -1153,11 +1151,10 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
}
if (othername_oid) {
- if ((unsigned) tmp.size == (sizeof(XMPP_OID)-1)
- && memcmp(tmp.data, XMPP_OID, sizeof(XMPP_OID)-1) == 0)
- type = GNUTLS_SAN_OTHERNAME_XMPP;
+ dname->size = tmp.size;
+ dname->data = tmp.data;
} else {
- char oid[42];
+ char oid[MAX_OID_SIZE];
if (src_name[0] != 0)
snprintf(nptr, sizeof(nptr),
@@ -1168,15 +1165,16 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
"?%u.otherName.type-id", seq);
len = sizeof(oid);
+
result = asn1_read_value(src, nptr, oid, &len);
if (result != ASN1_SUCCESS) {
gnutls_assert();
ret = _gnutls_asn2err(result);
goto cleanup;
}
+ if (len > 0) len--;
- if ((unsigned) len == (sizeof(XMPP_OID)-1)
- && memcmp(oid, XMPP_OID, sizeof(XMPP_OID)-1) == 0) {
+ if (_san_othername_to_virtual(oid, len) == GNUTLS_SAN_OTHERNAME_XMPP) {
gnutls_datum_t out;
ret =
@@ -1194,12 +1192,15 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
/* out is already null terminated */
ret = type;
goto cleanup;
+ } else {
+ dname->size = tmp.size;
+ dname->data = tmp.data;
}
}
} else if (type == GNUTLS_SAN_DN) {
_gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
ret = _gnutls_x509_get_dn(src, nptr, dname);
- if (result < 0) {
+ if (ret < 0) {
gnutls_assert();
goto cleanup;
}
@@ -1272,6 +1273,7 @@ get_alt_name(gnutls_x509_crt_t cert, const char *extension_id,
{
int ret;
gnutls_datum_t dnsname = {NULL, 0};
+ gnutls_datum_t ooid = {NULL, 0};
gnutls_datum_t res;
gnutls_subject_alt_names_t sans = NULL;
unsigned int type;
@@ -1307,19 +1309,27 @@ get_alt_name(gnutls_x509_crt_t cert, const char *extension_id,
goto cleanup;
}
- ret = gnutls_subject_alt_names_get(sans, seq, &type, &res, NULL);
+ ret = gnutls_subject_alt_names_get(sans, seq, &type, &res, &ooid);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
+ if (othername_oid && type == GNUTLS_SAN_OTHERNAME) {
+ type = _san_othername_to_virtual((char*)ooid.data, ooid.size);
+ }
+
if (alt_type)
*alt_type = type;
- if (is_type_printable(type)) {
- ret = _gnutls_copy_string(&res, alt, alt_size);
+ if (othername_oid) {
+ ret = _gnutls_copy_string(&ooid, alt, alt_size);
} else {
- ret = _gnutls_copy_data(&res, alt, alt_size);
+ if (is_type_printable(type)) {
+ ret = _gnutls_copy_string(&res, alt, alt_size);
+ } else {
+ ret = _gnutls_copy_data(&res, alt, alt_size);
+ }
}
if (ret < 0) {