summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-07-31 17:47:42 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-07-31 17:51:08 +0200
commitc86c2f88be5644ec8c82d23138fd23bc20184842 (patch)
tree08fdbfe62815abc1fa281e6f6326268164b461d6
parent199ef70e8d1fb87f3547f2cdb0edd20f68d4febd (diff)
downloadgnutls-c86c2f88be5644ec8c82d23138fd23bc20184842.tar.gz
Added GNUTLS_E_CERTIFICATE_LIST_UNSORTED.
If a certificate list is loaded then verify that it is sorted with order to starts with the subject and finished with the trusted root. That way we make sure we don't send data that violate the TLS protocol.
-rw-r--r--NEWS10
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/gnutls_x509.c67
-rw-r--r--lib/includes/gnutls/gnutls.h.in1
4 files changed, 80 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 056d180fb2..6c694bbf58 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,16 @@ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
See the end for copying conditions.
+* Version 3.0.1 (unreleased)
+
+** libgnutls: Verify that a certificate liste specified
+using gnutls_certificate_set_x509_key*(), is sorted
+according to TLS specification (from subject to issuer).
+
+** API and ABI modifications:
+No changes since last version.
+
+
* Version 3.0.0 (released 2011-07-29)
** libgnutls: writev_emu: stop on the first incomplete write. Patch by
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index fa706092b1..ed99d1f3ac 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -331,6 +331,8 @@ static const gnutls_error_entry error_algorithms[] = {
GNUTLS_E_ECC_UNSUPPORTED_CURVE, 1),
ERROR_ENTRY (N_("The requested PKCS #11 object is not available"),
GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE, 1),
+ ERROR_ENTRY (N_("The provided X.509 certificate list is not sorted (in subject to issuer order)"),
+ GNUTLS_E_CERTIFICATE_LIST_UNSORTED, 1),
{NULL, NULL, 0, 0}
};
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 37ba539ab8..fd3537bc39 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -792,10 +792,77 @@ gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
return 0;
}
+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];
+size_t prev_dn_size, dn_size;
+int i, ret;
+
+ /* check if the X.509 list is ordered */
+ if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
+ {
+
+ for (i=0;i<nr;i++)
+ {
+ ret = gnutls_x509_crt_init(&x509);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
+ if (ret < 0)
+ {
+ ret = gnutls_assert_val(ret);
+ goto cleanup;
+ }
+
+ if (i>0)
+ {
+ dn_size = sizeof(dn);
+ ret = gnutls_x509_crt_get_dn(x509, 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(x509, prev_dn, &prev_dn_size);
+ if (ret < 0)
+ {
+ ret = gnutls_assert_val(ret);
+ goto cleanup;
+ }
+
+ gnutls_x509_crt_deinit(x509);
+ }
+ }
+
+ return 0;
+
+cleanup:
+ gnutls_x509_crt_deinit(x509);
+ return ret;
+}
+
int
certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
gnutls_pcert_st * crt, int nr)
{
+int ret;
+
+ ret = check_if_sorted(crt, nr);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
res->cert_list = gnutls_realloc_fast (res->cert_list,
(1 +
res->ncerts) *
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 1d6b5e1d1b..912da27616 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1808,6 +1808,7 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
#define GNUTLS_E_ECC_NO_SUPPORTED_CURVES -321
#define GNUTLS_E_ECC_UNSUPPORTED_CURVE -322
#define GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE -323
+#define GNUTLS_E_CERTIFICATE_LIST_UNSORTED -324
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250