diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-04-27 21:43:44 +0300 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-04-27 21:48:01 +0300 |
commit | be8cee7c9247781b83c90a951b1039363f744b50 (patch) | |
tree | fe9915831ce07d7d557e9d25131011c23fb9bc52 | |
parent | 52430ced794813ef6abe8e4d28570595ea9b301f (diff) | |
download | gnutls-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.c | 66 | ||||
-rw-r--r-- | lib/x509/dn.c | 64 |
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; |