summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-04-05 13:16:07 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-04-05 13:22:54 +0200
commit2e497d1c3798644b33df9f8ed4c6174428db97d9 (patch)
treeba15fdff1c6bf770af8ee5e830c7eca033498d82
parent5e1f927096419c2675b8b28741d5750563a83b49 (diff)
downloadgnutls-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.c52
-rw-r--r--lib/x509/common.h2
-rw-r--r--lib/x509/x509.c2
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;