diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-04-05 13:16:07 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-04-05 13:22:54 +0200 |
commit | 2e497d1c3798644b33df9f8ed4c6174428db97d9 (patch) | |
tree | ba15fdff1c6bf770af8ee5e830c7eca033498d82 | |
parent | 5e1f927096419c2675b8b28741d5750563a83b49 (diff) | |
download | gnutls-2e497d1c3798644b33df9f8ed4c6174428db97d9.tar.gz |
_gnutls_parse_general_name2: allow parsing empty names
This allows parsing empty general names such as an empty DNSname
used in name constraints.
-rw-r--r-- | lib/x509/common.c | 52 | ||||
-rw-r--r-- | lib/x509/common.h | 2 | ||||
-rw-r--r-- | lib/x509/x509.c | 2 |
3 files changed, 39 insertions, 17 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c index c3b64cd5de..e2a60890c8 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -1092,24 +1092,26 @@ _gnutls_x509_decode_string(unsigned int etype, * Note that this function always allocates one plus * the required data size (and places a null byte). */ -int -_gnutls_x509_read_value(ASN1_TYPE c, const char *root, - gnutls_datum_t * ret) +static int +x509_read_value(ASN1_TYPE c, const char *root, + gnutls_datum_t * ret, unsigned allow_null) { int len = 0, result; uint8_t *tmp = NULL; unsigned int etype; result = asn1_read_value_type(c, root, NULL, &len, &etype); - if (result == 0 && len == 0) { + if (result == 0 && allow_null == 0 && len == 0) { /* don't allow null strings */ return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR); } if (result != ASN1_MEM_ERROR) { - gnutls_assert(); - result = _gnutls_asn2err(result); - return result; + if (result != ASN1_SUCCESS || allow_null == 0 || len != 0) { + gnutls_assert(); + result = _gnutls_asn2err(result); + return result; + } } if (etype == ASN1_ETYPE_BIT_STRING) { @@ -1123,17 +1125,21 @@ _gnutls_x509_read_value(ASN1_TYPE c, const char *root, goto cleanup; } - result = asn1_read_value(c, root, tmp, &len); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - result = _gnutls_asn2err(result); - goto cleanup; - } + if (len > 0) { + result = asn1_read_value(c, root, tmp, &len); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + goto cleanup; + } - if (etype == ASN1_ETYPE_BIT_STRING) { - ret->size = (len+7) / 8; + if (etype == ASN1_ETYPE_BIT_STRING) { + ret->size = (len+7) / 8; + } else { + ret->size = (unsigned) len; + } } else { - ret->size = (unsigned) len; + ret->size = 0; } tmp[ret->size] = 0; @@ -1146,6 +1152,20 @@ _gnutls_x509_read_value(ASN1_TYPE c, const char *root, return result; } +int +_gnutls_x509_read_value(ASN1_TYPE c, const char *root, + gnutls_datum_t * ret) +{ + return x509_read_value(c, root, ret, 0); +} + +int +_gnutls_x509_read_null_value(ASN1_TYPE c, const char *root, + gnutls_datum_t * ret) +{ + return x509_read_value(c, root, ret, 1); +} + /* Reads a value from an ASN1 tree, then interprets it as the provided * type of string and returns the output in an allocated variable. * diff --git a/lib/x509/common.h b/lib/x509/common.h index b1c5450351..419635691a 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -120,6 +120,8 @@ int _gnutls_x509_export_int_named2(ASN1_TYPE asn1_data, const char *name, int _gnutls_x509_read_value(ASN1_TYPE c, const char *root, gnutls_datum_t * ret); +int _gnutls_x509_read_null_value(ASN1_TYPE c, const char *root, + gnutls_datum_t * ret); int _gnutls_x509_read_string(ASN1_TYPE c, const char *root, gnutls_datum_t * ret, unsigned int etype, unsigned allow_ber); diff --git a/lib/x509/x509.c b/lib/x509/x509.c index c44820812b..a9e479f76a 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -1297,7 +1297,7 @@ _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name, _gnutls_str_cat(nptr, sizeof(nptr), "."); _gnutls_str_cat(nptr, sizeof(nptr), choice_type); - ret = _gnutls_x509_read_value(src, nptr, &tmp); + ret = _gnutls_x509_read_null_value(src, nptr, &tmp); if (ret < 0) { gnutls_assert(); return ret; |