diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-02-18 15:59:31 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-02-18 16:47:26 +0100 |
commit | 7f41840d89eb972d9463d38737b5dd8659cc07c2 (patch) | |
tree | 8c18813b36c2a2a30961ccf5173ca032f60d96b7 | |
parent | eb2f067cdabb520457e3741409714eca20f906bf (diff) | |
download | gnutls-7f41840d89eb972d9463d38737b5dd8659cc07c2.tar.gz |
_gnutls_sort_clist: fixed issues when used with func option
This function would incorrectly call func() on elements that were
included in the list, and would not call func() if the size of the
final chain was one.
-rw-r--r-- | lib/x509/common.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c index 8e8ee68fb5..c3b64cd5de 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -2065,6 +2065,8 @@ gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t int prev; unsigned int j, i; int issuer[DEFAULT_MAX_VERIFY_DEPTH]; /* contain the index of the issuers */ + unsigned insorted[DEFAULT_MAX_VERIFY_DEPTH]; /* non zero if clist[i] used in sorted list */ + unsigned orig_size = *clist_size; /* Do not bother sorting if too many certificates are given. * Prevent any DoS attacks. @@ -2072,8 +2074,10 @@ gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t if (*clist_size > DEFAULT_MAX_VERIFY_DEPTH) return clist; - for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) + for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) { issuer[i] = -1; + insorted[i] = 0; + } /* Find the issuer of each certificate and store it * in issuer array. @@ -2091,25 +2095,32 @@ gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t } } + /* always included */ + sorted[0] = clist[0]; + insorted[0] = 1; + if (issuer[0] == -1) { *clist_size = 1; - return clist; + goto exit; } prev = 0; - sorted[0] = clist[0]; for (i = 1; i < *clist_size; i++) { prev = issuer[prev]; - if (prev == -1) { /* no issuer */ + if (prev < 0) { /* no issuer */ *clist_size = i; break; } sorted[i] = clist[prev]; + insorted[prev] = 1; } + exit: if (func) { - for (i = 1; i < *clist_size; i++) { - if (issuer[i] == -1) { + /* call func() on all the elements that were + * not used in the sorted list */ + for (i = 1; i < orig_size; i++) { + if (insorted[i] == 0) { func(clist[i]); } } |