]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
check pathlen constraints.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 2 Nov 2012 12:46:25 +0000 (13:46 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 2 Nov 2012 12:53:59 +0000 (13:53 +0100)
NEWS
lib/gnutls_cert.c
lib/gnutls_int.h
lib/x509/verify.c
tests/suite/chain
tests/suite/x509paths/README

diff --git a/NEWS b/NEWS
index ef4f7035e99fc940866653ade75d26ea59c57b04..79a07b38591de69b3db7e9de1027f440a5e8febe 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ See the end for copying conditions.
 ** libgnutls: gnutls_certificate_verify_peers2() will set flags depending on
 the available revocation data validity.
 
+** libgnutls: Added gnutls_certificate_verification_status_print(),
+a function to print the verification status code in human
+readable text.
+
 ** libgnutls: Added priority string %VERIFY_DISABLE_CRL_CHECKS.
 
 ** libgnutls: Simplified certificate verification by adding
@@ -16,8 +20,8 @@ gnutls_certificate_verify_peers3().
 for SRTP.
 
 ** libgnutls: The X.509 verification functions check the key
-usage bits and output @GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE
-if check fails.
+usage bits and pathlen constraints and on failure output 
+GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE.
 
 ** libgnutls: gnutls_x509_crl_verify() includes the time
 checks.
index 8c2d27d4275f4527ab4feda836d65b3244a7e2f6..f784cc5f812377a1e3910e801d079bb9484eab34 100644 (file)
@@ -934,14 +934,14 @@ gnutls_certificate_verification_status_print (unsigned int status,
   _gnutls_buffer_init (&str);
 
   if (status == 0)
-    _gnutls_buffer_append_str (&str, _("Peer's certificate is trusted. "));
+    _gnutls_buffer_append_str (&str, _("The certificate is trusted. "));
   else
-    _gnutls_buffer_append_str (&str, _("Peer's certificate is NOT trusted. "));
+    _gnutls_buffer_append_str (&str, _("The certificate is NOT trusted. "));
 
   if (type == GNUTLS_CRT_X509)
     {
       if (status & GNUTLS_CERT_REVOKED)
-        _gnutls_buffer_append_str (&str, _("Peer's certificate chain revoked. "));
+        _gnutls_buffer_append_str (&str, _("The certificate chain revoked. "));
 
       if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD)
          _gnutls_buffer_append_str (&str, _("The revocation data are too old. "));
@@ -953,30 +953,33 @@ gnutls_certificate_verification_status_print (unsigned int status,
          _gnutls_buffer_append_str (&str, _("The revocation data are issued with a future date. "));
 
       if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-         _gnutls_buffer_append_str (&str, _("Peer's certificate issuer is unknown. "));
+         _gnutls_buffer_append_str (&str, _("The certificate issuer is unknown. "));
 
       if (status & GNUTLS_CERT_SIGNER_NOT_CA)
-         _gnutls_buffer_append_str (&str, _("Peer's certificate issuer is not a CA. "));
+         _gnutls_buffer_append_str (&str, _("The certificate issuer is not a CA. "));
       }
     else if (type == GNUTLS_CRT_OPENPGP)
       {
-        _gnutls_buffer_append_str (&str, _("Peer's certificate is not trusted. "));
+        _gnutls_buffer_append_str (&str, _("The certificate is not trusted. "));
 
         if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
-          _gnutls_buffer_append_str (&str, _("Could not find a signer of the peer's certificate. "));
+          _gnutls_buffer_append_str (&str, _("Could not find a signer of the certificate. "));
 
         if (status & GNUTLS_CERT_REVOKED)
-          _gnutls_buffer_append_str (&str, _("Peer's certificate is revoked. "));
+          _gnutls_buffer_append_str (&str, _("The certificate is revoked. "));
       }
 
   if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
-    _gnutls_buffer_append_str (&str, _("Peer's certificate chain uses insecure algorithm. "));
+    _gnutls_buffer_append_str (&str, _("The certificate chain uses insecure algorithm. "));
+
+  if (status & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE)
+    _gnutls_buffer_append_str (&str, _("The certificate chain violates the signer's constraints. "));
 
   if (status & GNUTLS_CERT_NOT_ACTIVATED)
-    _gnutls_buffer_append_str (&str, _("Peer's certificate chain uses not yet valid certificate. "));
+    _gnutls_buffer_append_str (&str, _("The certificate chain uses not yet valid certificate. "));
 
   if (status & GNUTLS_CERT_EXPIRED)
-    _gnutls_buffer_append_str (&str, _("Peer's certificate chain uses expired certificate. "));
+    _gnutls_buffer_append_str (&str, _("The certificate chain uses expired certificate. "));
 
   if (status & GNUTLS_CERT_SIGNATURE_FAILURE)
     _gnutls_buffer_append_str (&str, _("The signature in the certificate is invalid. "));
index 68a176ee3cfd3782e7de2d5987615c932d52affb..10811358170d6a93bcb580e4ac800c24e9999fa9 100644 (file)
@@ -202,6 +202,7 @@ typedef enum transport_t
  */
 #define DEFAULT_MAX_VERIFY_DEPTH 16
 #define DEFAULT_MAX_VERIFY_BITS 16*1024
+#define MAX_VERIFY_DEPTH 4096
 
 #include <gnutls_mem.h>
 
index 0a61869cdf5ed59611a0203722681d7581aa6a56..7cbbb6329999af00f306a97f07724ca96fed8896 100644 (file)
@@ -113,13 +113,15 @@ cleanup:
  */
 static int
 check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
+             unsigned int *max_path,
              unsigned int flags)
 {
   gnutls_datum_t cert_signed_data = { NULL, 0 };
   gnutls_datum_t issuer_signed_data = { NULL, 0 };
   gnutls_datum_t cert_signature = { NULL, 0 };
   gnutls_datum_t issuer_signature = { NULL, 0 };
-  int result;
+  int pathlen, result;
+  unsigned int ca_status;
 
   /* Check if the issuer is the same with the
    * certificate. This is added in order for trusted
@@ -176,9 +178,21 @@ check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
             goto cleanup;
           }
       }
+  
+  result = gnutls_x509_crt_get_basic_constraints( issuer, NULL, &ca_status, &pathlen);
+  if (result < 0)
+    {
+      ca_status = 0;
+      pathlen = -1;
+    }
+    
+  if (ca_status != 0 && pathlen != -1)
+    {
+      if ((unsigned)pathlen < *max_path)
+        *max_path = pathlen;
+    }
 
-  result = gnutls_x509_crt_get_ca_status (issuer, NULL);
-  if (result == 1)
+  if (ca_status != 0)
     {
       result = 1;
       goto cleanup;
@@ -392,6 +406,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
                              unsigned int *output,
                              gnutls_x509_crt_t * _issuer,
                              time_t now,
+                             unsigned int *max_path,
                              gnutls_verify_output_function func)
 {
   gnutls_datum_t cert_signed_data = { NULL, 0 };
@@ -402,18 +417,20 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
 
   if (output)
     *output = 0;
-
-  if (tcas_size >= 1)
-    issuer = find_issuer (cert, trusted_cas, tcas_size);
-  else
+    
+  if (*max_path == 0)
     {
-      gnutls_assert ();
-      out = GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
+      out = GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE | GNUTLS_CERT_INVALID;
       if (output)
         *output |= out;
+      gnutls_assert ();
       result = 0;
       goto cleanup;
     }
+  (*max_path)--;
+
+  if (tcas_size >= 1)
+    issuer = find_issuer (cert, trusted_cas, tcas_size);
 
   /* issuer is not in trusted certificate
    * authorities.
@@ -437,12 +454,12 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
       gnutls_assert ();
       return issuer_version;
     }
-
+  
   if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
       ((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
        || issuer_version != 1))
     {
-      if (check_if_ca (cert, issuer, flags) == 0)
+      if (check_if_ca (cert, issuer, max_path, flags) == 0)
         {
           gnutls_assert ();
           out = GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
@@ -603,6 +620,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
   unsigned int status = 0, output;
   time_t now = gnutls_time (0);
   gnutls_x509_crt_t issuer = NULL;
+  unsigned int max_path;
 
   if (clist_size > 1)
     {
@@ -676,9 +694,10 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
    * in self signed etc certificates.
    */
   output = 0;
+  max_path = MAX_VERIFY_DEPTH;
   ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
                                      trusted_cas, tcas_size, flags, &output,
-                                     &issuer, now, func);
+                                     &issuer, now, &max_path, func);
   if (ret == 0)
     {
       /* if the last certificate in the certificate
@@ -707,7 +726,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
       if ((ret =
            _gnutls_verify_certificate2 (certificate_list[i - 1],
                                         &certificate_list[i], 1, flags,
-                                        &output, NULL, now, func)) == 0)
+                                        &output, NULL, now, &max_path, func)) == 0)
         {
           status |= output;
           status |= GNUTLS_CERT_INVALID;
index 35bc541c9300c3947b9b033e95e39bd101601c10..f1967c981132e017a5b4a621ab7a8f5c566ae4f9 100755 (executable)
@@ -24,7 +24,7 @@ CERTTOOL=../../../src/certtool
 
 SUCCESS=" 1 4 7 12 15 16 17 18 24 26 27 30 33 56 57 62 63 "
 FAILURE=" 2 3 5 6 8 9 10 11 13 14 19 20 21 22 23 25 28 29 31 32 54 55 58 59 60 61 "
-KNOWN_BUGS=" 15 16 17 18 19 31 32 54 55 58 59 60 61 "
+KNOWN_BUGS=" 15 16 17 18 19 31 32 "
 
 cd x509paths
 
index 0d5d892b14e85a91cfd4cb20fe361ed1b4fc5902..d56032dcec83ec0f48c4b16477ca49f486fba95b 100644 (file)
@@ -27,4 +27,3 @@ that can verify CRLs on addition. (there is an issue there since the
 CRLs that are being added are typically of an intermediate CA which
 is not in the trust list to verify them)
 
-Chain 54-55,58-61: We don't check path length constraints properly. XXX