summaryrefslogtreecommitdiff
path: root/lib/x509/x509.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x509/x509.c')
-rw-r--r--lib/x509/x509.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 2adb899914..758490100b 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -3073,6 +3073,52 @@ int ret;
return 0;
}
+static int check_if_sorted(gnutls_x509_crt_t * crt, int nr)
+{
+char prev_dn[MAX_DN];
+char dn[MAX_DN];
+size_t prev_dn_size, dn_size;
+int i, ret;
+
+ /* check if the X.509 list is ordered */
+ if (nr > 1)
+ {
+
+ for (i=0;i<nr;i++)
+ {
+ if (i>0)
+ {
+ dn_size = sizeof(dn);
+ ret = gnutls_x509_crt_get_dn(crt[i], dn, &dn_size);
+ if (ret < 0)
+ {
+ ret = gnutls_assert_val(ret);
+ goto cleanup;
+ }
+
+ if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
+ {
+ ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
+ goto cleanup;
+ }
+ }
+
+ prev_dn_size = sizeof(prev_dn);
+ ret = gnutls_x509_crt_get_issuer_dn(crt[i], prev_dn, &prev_dn_size);
+ if (ret < 0)
+ {
+ ret = gnutls_assert_val(ret);
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+
/**
* gnutls_x509_crt_list_import:
@@ -3086,6 +3132,12 @@ int ret;
* to the native gnutls_x509_crt_t format. The output will be stored
* in @certs. They will be automatically initialized.
*
+ * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
+ * import to fail if the certificates in the provided buffer are more
+ * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
+ * flag will cause the function to fail if the provided list is not
+ * sorted from subject to issuer.
+ *
* If the Certificate is PEM encoded it should have a header of "X509
* CERTIFICATE", or "CERTIFICATE".
*
@@ -3205,6 +3257,16 @@ gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
*cert_max = count;
+ if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED)
+ {
+ ret = check_if_sorted(certs, *cert_max);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto error;
+ }
+ }
+
if (nocopy == 0)
return count;
else