]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added GNUTLS_E_CERTIFICATE_LIST_UNSORTED.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 31 Jul 2011 15:47:42 +0000 (17:47 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 31 Jul 2011 15:51:08 +0000 (17:51 +0200)
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.

NEWS
lib/gnutls_errors.c
lib/gnutls_x509.c
lib/includes/gnutls/gnutls.h.in

diff --git a/NEWS b/NEWS
index 056d180fb2c67a5c813b21b0b7a7bae5e35a8e71..6c694bbf589f066d2a72070e690cdc6c70681ff3 100644 (file)
--- 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
index fa706092b1c200a105368fcbd8a78712625d7b6a..ed99d1f3ac6453b67760eff06feab25e2aea350b 100644 (file)
@@ -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}
 };
 
index 37ba539ab877b20a6a0e558e43a1f303a2e36886..fd3537bc39c61d4a78d722d54adadfa5a5288192 100644 (file)
@@ -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) *
index 1d6b5e1d1bf539d9d5849adda812cdb1a6f88893..912da2761679fa36e8a961e2931577a1fb9524e0 100644 (file)
@@ -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