diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-10-31 13:00:14 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-10-31 17:01:22 +0100 |
commit | 3e153d4f2564cd0b62c0c5be9c92ce7de8ca1a59 (patch) | |
tree | a876852afbeaf9ff73f59b61ce070c551c55eb1b | |
parent | 5e8009a103a77c22b3877f2b2929ac5b4833d7a2 (diff) | |
download | gnutls-3e153d4f2564cd0b62c0c5be9c92ce7de8ca1a59.tar.gz |
gnutls_x509_crt_set_*dn, gnutls_x509_dn_set_str: honor the reverse property of RFC4514
When converting an RFC4514 string to a DN ensure that the elements
are encoded in reverse order, as required by the RFC.
Resolves #111
-rw-r--r-- | lib/x509/x509_dn.c | 76 |
1 files changed, 64 insertions, 12 deletions
diff --git a/lib/x509/x509_dn.c b/lib/x509/x509_dn.c index c3737dd307..4fa90e5d4b 100644 --- a/lib/x509/x509_dn.c +++ b/lib/x509/x509_dn.c @@ -109,7 +109,8 @@ int dn_attr_crt_set(set_dn_func f, void *crt, const gnutls_datum_t * name, } static int read_attr_and_val(const char **ptr, - gnutls_datum_t * name, gnutls_datum_t * val, unsigned *is_raw) + gnutls_datum_t *name, gnutls_datum_t *val, + unsigned *is_raw) { const unsigned char *p = (void *) *ptr; @@ -164,6 +165,30 @@ static int read_attr_and_val(const char **ptr, return 0; } +typedef struct elem_list_st { + gnutls_datum_t name; + gnutls_datum_t val; + const char *pos; + unsigned is_raw; + struct elem_list_st *next; +} elem_list_st; + +static int add_new_elem(elem_list_st **head, const gnutls_datum_t *name, const gnutls_datum_t *val, const char *pos, unsigned is_raw) +{ + elem_list_st *elem = gnutls_malloc(sizeof(*elem)); + if (elem == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + memcpy(&elem->name, name, sizeof(*name)); + memcpy(&elem->val, val, sizeof(*val)); + elem->pos = pos; + elem->is_raw = is_raw; + elem->next = *head; + *head = elem; + + return 0; +} + static int crt_set_dn(set_dn_func f, void *crt, const char *dn, const char **err) { @@ -171,10 +196,15 @@ crt_set_dn(set_dn_func f, void *crt, const char *dn, const char **err) int ret; gnutls_datum_t name, val; unsigned is_raw; + elem_list_st *list = NULL, *plist, *next; if (crt == NULL || dn == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + /* We parse the string and set all elements to a linked list in + * reverse order. That way we can encode in reverse order, + * the way RFC4514 requires. */ + /* For each element */ while (*p != 0 && *p != '\n') { if (err) @@ -182,27 +212,49 @@ crt_set_dn(set_dn_func f, void *crt, const char *dn, const char **err) is_raw = 0; ret = read_attr_and_val(&p, &name, &val, &is_raw); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto fail; + } /* skip spaces and look for comma */ while (c_isspace(*p)) p++; - ret = dn_attr_crt_set(f, crt, &name, &val, is_raw); - if (ret < 0) - return gnutls_assert_val(ret); - - if (err) - *err = p; + ret = add_new_elem(&list, &name, &val, p, is_raw); + if (ret < 0) { + gnutls_assert(); + goto fail; + } - if (*p != ',' && *p != 0 && *p != '\n') - return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); + if (*p != ',' && *p != 0 && *p != '\n') { + ret = gnutls_assert_val(GNUTLS_E_PARSING_ERROR); + goto fail; + } if (*p == ',') p++; } - return 0; + plist = list; + while(plist) { + if (err) + *err = plist->pos; + ret = dn_attr_crt_set(f, crt, &plist->name, &plist->val, plist->is_raw); + if (ret < 0) + goto fail; + + plist = plist->next; + } + + ret = 0; +fail: + plist = list; + while(plist) { + next = plist->next; + gnutls_free(plist); + plist = next; + } + return ret; } |