summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-07-31 21:14:13 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-07-31 21:32:36 +0200
commita034ca1492733a7d84d3887142e5cb358754687e (patch)
treed449fa6b58db1a2c94381ae4dfb4734d9e165351 /lib
parentd6248f4bf6cf1e77adbe7a58c6f959dc7d86582c (diff)
downloadgnutls-a034ca1492733a7d84d3887142e5cb358754687e.tar.gz
Added GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED flag for gnutls_x509_crt_list_import.
It checks whether the list to be imported is properly sorted.
Diffstat (limited to 'lib')
-rw-r--r--lib/gnutls_str.h1
-rw-r--r--lib/gnutls_x509.c4
-rw-r--r--lib/includes/gnutls/x509.h6
-rw-r--r--lib/x509/x509.c62
4 files changed, 70 insertions, 3 deletions
diff --git a/lib/gnutls_str.h b/lib/gnutls_str.h
index bf82072f1a..88916aeed3 100644
--- a/lib/gnutls_str.h
+++ b/lib/gnutls_str.h
@@ -93,6 +93,7 @@ int _gnutls_hex2bin (const opaque * hex_data, int hex_size, opaque * bin_data,
int _gnutls_hostname_compare (const char *certname, size_t certnamesize,
const char *hostname, int level);
#define MAX_CN 256
+#define MAX_DN 1024
#define BUFFER_APPEND(b, x, s) { \
ret = _gnutls_buffer_append_data(b, x, s); \
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index d50f996ff2..6ee0549c5c 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -811,8 +811,8 @@ gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
static int check_if_sorted(gnutls_cert * crt, int nr)
{
gnutls_x509_crt_t x509;
-char prev_dn[MAX_CN];
-char dn[MAX_CN];
+char prev_dn[MAX_DN];
+char dn[MAX_DN];
size_t prev_dn_size, dn_size;
int i, ret;
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index bc7846bbcd..8fd8ca217b 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -92,12 +92,16 @@ extern "C"
* @GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED: Fail if the
* certificates in the buffer are more than the space allocated for
* certificates. The error code will be %GNUTLS_E_SHORT_MEMORY_BUFFER.
+ * @GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED: Fail if the certificates
+ * in the buffer are not ordered starting from subject to issuer.
+ * The error code will be %GNUTLS_E_CERTIFICATE_LIST_UNSORTED.
*
* Enumeration of different certificate import flags.
*/
typedef enum gnutls_certificate_import_flags
{
- GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED = 1
+ GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED = 1,
+ GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED = 2
} gnutls_certificate_import_flags;
int gnutls_x509_crt_init (gnutls_x509_crt_t * cert);
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 45bd720753..50a742ed15 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -248,6 +248,52 @@ cleanup:
return result;
}
+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_get_issuer_dn:
@@ -3076,6 +3122,12 @@ cleanup:
* 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".
*
@@ -3195,6 +3247,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