summaryrefslogtreecommitdiff
path: root/lib/x509/common.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2014-11-27 15:06:11 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2014-11-27 15:51:04 +0100
commit0349b3c4c2d33b13fc0757d363714214135c9eff (patch)
treeeb1cb14d7171fd5474c6ad0f246783900db233f8 /lib/x509/common.c
parented3913fdbc8ffe3b552c0d0f593f17c4e1a273d5 (diff)
downloadgnutls-0349b3c4c2d33b13fc0757d363714214135c9eff.tar.gz
Added flag GNUTLS_X509_CRT_LIST_SORT for gnutls_x509_crt_list_import*
That also allows automatically sorting input chains to the gnutls_certificate_credentials_t structure.
Diffstat (limited to 'lib/x509/common.c')
-rw-r--r--lib/x509/common.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c
index f85c6de85e..a34cdd5582 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1978,3 +1978,73 @@ _gnutls_check_valid_key_id(gnutls_datum_t *key_id,
out:
return result;
}
+
+/* Takes a certificate list and orders it with subject, issuer order.
+ *
+ * *clist_size contains the size of the ordered list (which is always less or
+ * equal to the original).
+ * @func: the function to call to elements outside the sort.
+ *
+ * Returns the sorted list which may be the original clist.
+ */
+gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t
+ sorted[DEFAULT_MAX_VERIFY_DEPTH],
+ gnutls_x509_crt_t *clist,
+ unsigned int *clist_size,
+ gnutls_cert_vfunc func)
+{
+ int prev;
+ unsigned int j, i;
+ int issuer[DEFAULT_MAX_VERIFY_DEPTH]; /* contain the index of the issuers */
+
+ /* Do not bother sorting if too many certificates are given.
+ * Prevent any DoS attacks.
+ */
+ if (*clist_size > DEFAULT_MAX_VERIFY_DEPTH)
+ return clist;
+
+ for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++)
+ issuer[i] = -1;
+
+ /* Find the issuer of each certificate and store it
+ * in issuer array.
+ */
+ for (i = 0; i < *clist_size; i++) {
+ for (j = 1; j < *clist_size; j++) {
+ if (i == j)
+ continue;
+
+ if (gnutls_x509_crt_check_issuer(clist[i],
+ clist[j]) != 0) {
+ issuer[i] = j;
+ break;
+ }
+ }
+ }
+
+ if (issuer[0] == -1) {
+ *clist_size = 1;
+ return clist;
+ }
+
+ prev = 0;
+ sorted[0] = clist[0];
+ for (i = 1; i < *clist_size; i++) {
+ prev = issuer[prev];
+ if (prev == -1) { /* no issuer */
+ *clist_size = i;
+ break;
+ }
+ sorted[i] = clist[prev];
+ }
+
+ if (func) {
+ for (i = 1; i < *clist_size; i++) {
+ if (issuer[i] == -1) {
+ func(clist[i]);
+ }
+ }
+ }
+
+ return sorted;
+}