summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-07-31 21:11:49 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-07-31 21:16:46 +0200
commit85986c82ec5edf498196476bcf671a36cf4ed091 (patch)
tree551fad53f8ccfb299dd8a71e3cf751d0285a2291 /lib
parentc86c2f88be5644ec8c82d23138fd23bc20184842 (diff)
downloadgnutls-85986c82ec5edf498196476bcf671a36cf4ed091.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 3fb230598a..41f6425f9e 100644
--- a/lib/gnutls_str.h
+++ b/lib/gnutls_str.h
@@ -97,6 +97,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 fd3537bc39..1ec822cab5 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -795,8 +795,8 @@ gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
static int check_if_sorted(gnutls_pcert_st * 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 f6bfdd8e78..09d26090f9 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 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