[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gnutls fails to use Verisign CA cert without a Basic Constraint
From: |
Douglas E. Engert |
Subject: |
Re: gnutls fails to use Verisign CA cert without a Basic Constraint |
Date: |
Mon, 12 Jan 2009 14:09:49 -0600 |
User-agent: |
Thunderbird 2.0.0.19 (Windows/20081209) |
Simon Josefsson wrote:
"Douglas E. Engert" <address@hidden> writes:
OK, see form below.
You need to send it to address@hidden, I could forward it but I think
they want it directly from the submitter.
OK, sent the form, first time was wrong address.
If you were to create a check_if_same_cert routine the actual code
to shorten the cert chain is only 7 lines, not counting
comments, "{" or "}" lines.
Here is a verify.c patch (Against Ubuntu version) that does the following:
added routine check_if_same_cert() to test if two certs are identical,
using the method used in check_if_ca.
(Note: check_if_ca could call check_if_same_cert too, but it made
the patch file hard to read.)
Adds this code:
+ /* We want to shorten the chain by removing the cert that matches
+ * one of the certs we trust and all the certs after that
+ * i.e. if cert chain is A, B, C, and we trust B, remove B and C
+ * we must leave the first cert on chain. */
+ if (clist_size > 1)
+ {
+ for (i = 1; i < clist_size; i++)
+ {
+ int j;
+ for (j = 0; j < tcas_size; j++)
+ {
+ if (check_if_same_cert ( certificate_list[i], trusted_cas[j], flags)
== 1)
+ {
+ clist_size = i;
+ break;
+ }
+ }
+ /* clist_size may have been changed which gets out of loop */
+ }
+ }
+
Add the recent patches to get the if corrected, and added the patch
for flags &= ~GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
--
Douglas E. Engert <address@hidden>
Argonne National Laboratory
9700 South Cass Avenue
Argonne, Illinois 60439
(630) 252-5444
--- ,verify.c 2009-01-06 14:02:41.000000000 -0600
+++ verify.c 2009-01-12 13:12:34.000000000 -0600
@@ -56,6 +56,79 @@
int tcas_size, unsigned int flags,
unsigned int *output);
+/* Checks if two certs are identical */
+
+static int
+check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2,
+ unsigned int flags)
+{
+ gnutls_datum_t cert1_signed_data = { NULL, 0 };
+ gnutls_datum_t cert2_signed_data = { NULL, 0 };
+ gnutls_datum_t cert1_signature = { NULL, 0 };
+ gnutls_datum_t cert2_signature = { NULL, 0 };
+ int result;
+
+ result =
+ _gnutls_x509_get_signed_data (cert2->cert, "tbsCertificate",
+ &cert2_signed_data);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ result =
+ _gnutls_x509_get_signed_data (cert1->cert, "tbsCertificate",
+ &cert1_signed_data);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ result =
+ _gnutls_x509_get_signature (cert2->cert, "signature", &cert2_signature);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ result =
+ _gnutls_x509_get_signature (cert1->cert, "signature", &cert1_signature);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ /* If the cert1 is the same as the cert2
+ * return true.
+ */
+ if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
+ if (cert1_signed_data.size == cert2_signed_data.size)
+ {
+ if ((memcmp (cert1_signed_data.data, cert2_signed_data.data,
+ cert1_signed_data.size) == 0) &&
+ (cert1_signature.size == cert2_signature.size) &&
+ (memcmp (cert1_signature.data, cert2_signature.data,
+ cert1_signature.size) == 0))
+ {
+ result = 1;
+ goto cleanup;
+ }
+ }
+
+ result = 0;
+
+cleanup:
+ _gnutls_free_datum (&cert1_signed_data);
+ _gnutls_free_datum (&cert2_signed_data);
+ _gnutls_free_datum (&cert1_signature);
+ _gnutls_free_datum (&cert2_signature);
+ return result;
+}
+
/* Checks if the issuer of a certificate is a
* Certificate Authority, or if the certificate is the same
@@ -130,11 +203,23 @@
}
}
- if (gnutls_x509_crt_get_ca_status (issuer, NULL) == 1)
+ result=gnutls_x509_crt_get_ca_status (issuer, NULL);
+ if (result == 1)
{
result = 1;
goto cleanup;
}
+ /* Handle V1 CAs that do not have a basicConstraint, but accept
+ these certs only if the appropriate flags are set. */
+ else if ((result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) &&
+ ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) ||
+ ((flags & GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT) &&
+ (gnutls_x509_crt_check_issuer (issuer, issuer) == 1))))
+ {
+ gnutls_assert ();
+ result = 1;
+ goto cleanup;
+ }
else
gnutls_assert ();
@@ -397,6 +482,28 @@
}
}
+ /* We want to shorten the chain by removing the cert that matches
+ * one of the certs we trust and all the certs after that
+ * i.e. if cert chain is A, B, C, and we trust B, remove B and C
+ * we must leave the first cert on chain. */
+ if (clist_size > 1)
+ {
+ for (i = 1; i < clist_size; i++)
+ {
+ int j;
+ for (j = 0; j < tcas_size; j++)
+ {
+ if (check_if_same_cert ( certificate_list[i], trusted_cas[j], flags)
== 1)
+ {
+ clist_size = i;
+ break;
+ }
+ }
+ /* clist_size may have been changed which gets out of loop */
+ }
+ }
+
+
/* Verify the last certificate in the certificate path
* against the trusted CA certificate list.
*
@@ -446,7 +553,7 @@
* certificates can exist in a supplied chain.
*/
if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT))
- flags ^= GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
+ flags &= ~GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
if ((ret =
_gnutls_verify_certificate2 (certificate_list[i - 1],
&certificate_list[i], 1, flags,
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, (continued)
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Simon Josefsson, 2009/01/10
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Douglas E. Engert, 2009/01/09
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Simon Josefsson, 2009/01/10
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Nikos Mavrogiannopoulos, 2009/01/10
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Simon Josefsson, 2009/01/11
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Douglas E. Engert, 2009/01/12
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Douglas E. Engert, 2009/01/12
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Simon Josefsson, 2009/01/12
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Douglas E. Engert, 2009/01/12
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Simon Josefsson, 2009/01/12
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint,
Douglas E. Engert <=
- Re: gnutls fails to use Verisign CA cert without a Basic Constraint, Douglas E. Engert, 2009/01/14