summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2013-04-27 21:43:44 +0300
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2013-04-27 21:48:01 +0300
commitbe8cee7c9247781b83c90a951b1039363f744b50 (patch)
treefe9915831ce07d7d557e9d25131011c23fb9bc52
parent52430ced794813ef6abe8e4d28570595ea9b301f (diff)
downloadgnutls-be8cee7c9247781b83c90a951b1039363f744b50.tar.gz
Always escape printable strings the LDAP way, and avoid escaping hex encoded values. Report and initial patch from Stef Walter.
-rw-r--r--lib/x509/common.c66
-rw-r--r--lib/x509/dn.c64
2 files changed, 62 insertions, 68 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c
index e1b205c9b1..cbdc32a822 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -139,6 +139,56 @@ const char* _gnutls_ldap_string_to_oid (const char* str, unsigned str_len)
return NULL;
}
+/* Escapes a string following the rules from RFC4514.
+ */
+static int
+str_escape (const gnutls_datum_t* str, gnutls_datum_t * escaped)
+{
+ unsigned int j, i;
+ uint8_t *buffer = NULL;
+ int ret;
+
+ if (str == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ /* the string will be at most twice the original */
+ buffer = gnutls_malloc(str->size*2+2);
+ if (buffer == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ for (i = j = 0; i < str->size; i++)
+ {
+ if (str->data[i] == 0)
+ {
+ /* this is handled earlier */
+ ret = gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
+ goto cleanup;
+ }
+
+ if (str->data[i] == ',' || str->data[i] == '+' || str->data[i] == '"'
+ || str->data[i] == '\\' || str->data[i] == '<' || str->data[i] == '>'
+ || str->data[i] == ';' || str->data[i] == 0)
+ buffer[j++] = '\\';
+ else if (i==0 && str->data[i] == '#')
+ buffer[j++] = '\\';
+ else if (i==0 && str->data[i] == ' ')
+ buffer[j++] = '\\';
+ else if (i==(str->size-1) && str->data[i] == ' ')
+ buffer[j++] = '\\';
+
+ buffer[j++] = str->data[i];
+ }
+
+ /* null terminate the string */
+ buffer[j] = 0;
+ escaped->data = buffer;
+ escaped->size = j;
+
+ return 0;
+cleanup:
+ gnutls_free(buffer);
+ return ret;
+}
/**
* gnutls_x509_dn_oid_known:
@@ -375,6 +425,7 @@ _gnutls_x509_dn_to_string (const char *oid, void *value,
{
const struct oid_to_string* oentry;
int ret;
+ gnutls_datum_t tmp;
size_t size;
if (value == NULL || value_size <= 0)
@@ -405,24 +456,27 @@ _gnutls_x509_dn_to_string (const char *oid, void *value,
if (oentry->asn_desc != NULL)
{ /* complex */
- ret = decode_complex_string(oentry, value, value_size, str);
+ ret = decode_complex_string(oentry, value, value_size, &tmp);
if (ret < 0)
return gnutls_assert_val(ret);
}
else
{
ret = _gnutls_x509_decode_string(oentry->etype, value, value_size,
- str);
+ &tmp);
if (ret < 0)
- {
- return gnutls_assert_val(ret);
- }
+ return gnutls_assert_val(ret);
}
+ ret = str_escape(&tmp, str);
+ _gnutls_free_datum (&tmp);
+
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
return 0;
}
-
/* Converts a data string to an LDAP rfc2253 hex string
* something like '#01020304'
*/
diff --git a/lib/x509/dn.c b/lib/x509/dn.c
index 97a2edbb40..811ef155e0 100644
--- a/lib/x509/dn.c
+++ b/lib/x509/dn.c
@@ -33,57 +33,6 @@
* Name (you need a parser just to read a name in the X.509 protoocols!!!)
*/
-/* Escapes a string following the rules from RFC4514.
- */
-static int
-str_escape (const gnutls_datum_t* str, gnutls_datum_t * escaped)
-{
- unsigned int j, i;
- uint8_t *buffer = NULL;
- int ret;
-
- if (str == NULL)
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-
- /* the string will be at most twice the original */
- buffer = gnutls_malloc(str->size*2+2);
- if (buffer == NULL)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-
- for (i = j = 0; i < str->size; i++)
- {
- if (str->data[i] == 0)
- {
- /* this is handled earlier */
- ret = gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
- goto cleanup;
- }
-
- if (str->data[i] == ',' || str->data[i] == '+' || str->data[i] == '"'
- || str->data[i] == '\\' || str->data[i] == '<' || str->data[i] == '>'
- || str->data[i] == ';' || str->data[i] == 0)
- buffer[j++] = '\\';
- else if (i==0 && str->data[i] == '#')
- buffer[j++] = '\\';
- else if (i==0 && str->data[i] == ' ')
- buffer[j++] = '\\';
- else if (i==(str->size-1) && str->data[i] == ' ')
- buffer[j++] = '\\';
-
- buffer[j++] = str->data[i];
- }
-
- /* null terminate the string */
- buffer[j] = 0;
- escaped->data = buffer;
- escaped->size = j;
-
- return 0;
-cleanup:
- gnutls_free(buffer);
- return ret;
-}
-
int
_gnutls_x509_get_dn (ASN1_TYPE asn1_struct,
const char *asn1_rdn_name, gnutls_datum_t * dn)
@@ -94,7 +43,7 @@ _gnutls_x509_get_dn (ASN1_TYPE asn1_struct,
char tmpbuffer2[ASN1_MAX_NAME_SIZE];
char tmpbuffer3[ASN1_MAX_NAME_SIZE];
uint8_t value[MAX_STRING_LEN];
- gnutls_datum_t td = {NULL, 0}, tvd = {NULL, 0}, escaped = {NULL, 0};
+ gnutls_datum_t td = {NULL, 0}, tvd = {NULL, 0};
const char *ldap_desc;
char oid[MAX_OID_SIZE];
int len;
@@ -231,17 +180,9 @@ _gnutls_x509_get_dn (ASN1_TYPE asn1_struct,
goto cleanup;
}
- result = str_escape(&td, &escaped);
- if (result < 0)
- {
- gnutls_assert();
- goto cleanup;
- }
-
- DATA_APPEND (escaped.data, escaped.size);
+ DATA_APPEND (td.data, td.size);
_gnutls_free_datum (&td);
_gnutls_free_datum (&tvd);
- _gnutls_free_datum (&escaped);
}
while (1);
}
@@ -256,7 +197,6 @@ _gnutls_x509_get_dn (ASN1_TYPE asn1_struct,
cleanup:
_gnutls_buffer_clear (&out_str);
cleanup1:
- _gnutls_free_datum (&escaped);
_gnutls_free_datum (&td);
_gnutls_free_datum (&tvd);
return result;