[svn] GnuPG - r4267 - in trunk: . sm
svn author wk
cvs at cvs.gnupg.org
Tue Sep 26 12:00:14 CEST 2006
Author: wk
Date: 2006-09-26 12:00:12 +0200 (Tue, 26 Sep 2006)
New Revision: 4267
Modified:
trunk/NEWS
trunk/sm/ChangeLog
trunk/sm/certchain.c
Log:
Finished implementation of the "relax" flag.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2006-09-25 18:29:20 UTC (rev 4266)
+++ trunk/NEWS 2006-09-26 10:00:12 UTC (rev 4267)
@@ -1,7 +1,10 @@
Noteworthy changes in version 1.9.91
-------------------------------------------------
+ * New "relax" flag for trustlist.txt to allow root CA certificates
+ without BasicContraints.
+
Noteworthy changes in version 1.9.90 (2006-09-25)
-------------------------------------------------
Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog 2006-09-25 18:29:20 UTC (rev 4266)
+++ trunk/sm/ChangeLog 2006-09-26 10:00:12 UTC (rev 4267)
@@ -1,3 +1,9 @@
+2006-09-26 Werner Koch <wk at g10code.com>
+
+ * certchain.c (gpgsm_validate_chain): More changes for the relax
+ feature. Use certificate reference counting instead of the old
+ explicit tests. Added a missing free.
+
2006-09-25 Werner Koch <wk at g10code.com>
* gpgsm.h (struct rootca_flags_s): New.
Modified: trunk/sm/certchain.c
===================================================================
--- trunk/sm/certchain.c 2006-09-25 18:29:20 UTC (rev 4266)
+++ trunk/sm/certchain.c 2006-09-26 10:00:12 UTC (rev 4267)
@@ -695,10 +695,15 @@
gpgsm_dump_cert ("target", cert);
subject_cert = cert;
+ ksba_cert_ref (subject_cert);
maxdepth = 50;
for (;;)
{
+ int is_root;
+ gpg_error_t istrusted_rc;
+ struct rootca_flags_s rootca_flags;
+
xfree (issuer);
xfree (subject);
issuer = ksba_cert_get_issuer (subject_cert, 0);
@@ -711,6 +716,20 @@
goto leave;
}
+ /* Is this a self-issued certificate (i.e. the root certificate)? */
+ is_root = (subject && !strcmp (issuer, subject));
+ if (is_root)
+ {
+ /* Check early whether the certificate is listed as trusted.
+ We used to do this only later but changed it to call the
+ check right here so that we can access special flags
+ associated with that specific root certificate. */
+ istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert,
+ &rootca_flags);
+ }
+
+
+ /* Check the validity period. */
{
ksba_isotime_t not_before, not_after;
@@ -762,10 +781,12 @@
}
}
+ /* Assert that we understand all critical extensions. */
rc = unknown_criticals (subject_cert, listmode, fp);
if (rc)
goto leave;
+ /* Do a policy check. */
if (!opt.no_policy_check)
{
rc = check_cert_policy (subject_cert, listmode, fp);
@@ -780,23 +801,14 @@
/* Is this a self-issued certificate? */
- if (subject && !strcmp (issuer, subject))
- { /* Yes. */
- gpg_error_t istrusted_rc;
- struct rootca_flags_s rootca_flags;
-
- /* Check early whether the certificate is listed as trusted.
- We used to do this only later but changed it to call the
- check right here so that we can access special flags
- associated with that specific root certificate. */
- istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert,
- &rootca_flags);
-
- /* Note, that we could save the following signature check
- because nobody would be so dump to set up a faked chain
- and fail in creating a valid self-signed certificate. */
- if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
+ if (is_root)
+ {
+ if (!istrusted_rc)
+ ; /* No need to check the certificate for a trusted one. */
+ else if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
{
+ /* We only check the signature if the certificate is not
+ trusted for better diagnostics. */
do_list (1, lm, fp,
_("self-signed certificate has a BAD signature"));
if (DBG_X509)
@@ -920,6 +932,7 @@
break; /* Okay: a self-signed certicate is an end-point. */
}
+ /* Take care that the chain does not get too long. */
depth++;
if (depth > maxdepth)
{
@@ -928,7 +941,7 @@
goto leave;
}
- /* find the next cert up the tree */
+ /* Find the next cert up the tree. */
keydb_search_reset (kh);
rc = find_up (kh, subject_cert, issuer, 0);
if (rc)
@@ -1013,10 +1026,38 @@
goto leave;
}
+ is_root = 0;
+ istrusted_rc = -1;
+
+ /* Check that a CA is allowed to issue certificates. */
{
int chainlen;
+
rc = allowed_ca (issuer_cert, &chainlen, listmode, fp);
if (rc)
+ {
+ /* Not allowed. Check whether this is a trusted root
+ certificate and whether we allow special exceptions.
+ We could carry the result of the test over to the
+ regular root check at the top of the loop but for
+ clarity we won't do that. Given that the majority of
+ certificates carry proper BasicContraints our way of
+ overriding an error in the way is justified for
+ performance reasons. */
+ if (gpgsm_is_root_cert (issuer_cert))
+ {
+ is_root = 1;
+ istrusted_rc = gpgsm_agent_istrusted (ctrl, issuer_cert,
+ &rootca_flags);
+ if (!istrusted_rc && rootca_flags.relax)
+ {
+ /* Ignore the error due to the relax flag. */
+ rc = 0;
+ chainlen = -1;
+ }
+ }
+ }
+ if (rc)
goto leave;
if (chainlen >= 0 && (depth - 1) > chainlen)
{
@@ -1028,6 +1069,7 @@
}
}
+ /* Is the certificate allowed to sign other certificates. */
if (!listmode)
{
rc = gpgsm_cert_use_cert_p (issuer_cert);
@@ -1041,9 +1083,14 @@
}
}
- /* Check for revocations etc. */
+ /* Check for revocations etc. Note that for a root certioficate
+ this test is done a second time later. This should eventually
+ be fixed. */
if ((flags & 1))
rc = 0;
+ else if (is_root && (opt.no_trusted_cert_crl_check
+ || (!istrusted_rc && rootca_flags.relax)))
+ ;
else
rc = is_cert_still_valid (ctrl, lm, fp,
subject_cert, issuer_cert,
@@ -1054,8 +1101,10 @@
if (opt.verbose && !listmode)
log_info ("certificate is good\n");
-
+
+ /* For the next round the current issuer becomes the new subject. */
keydb_search_reset (kh);
+ ksba_cert_release (subject_cert);
subject_cert = issuer_cert;
issuer_cert = NULL;
} /* End chain traversal. */
@@ -1110,10 +1159,10 @@
if (r_exptime)
gnupg_copy_time (r_exptime, exptime);
xfree (issuer);
+ xfree (subject);
keydb_release (kh);
ksba_cert_release (issuer_cert);
- if (subject_cert != cert)
- ksba_cert_release (subject_cert);
+ ksba_cert_release (subject_cert);
return rc;
}
More information about the Gnupg-commits
mailing list