aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/DETAILS5
-rw-r--r--doc/gpgsm.texi9
-rw-r--r--sm/certchain.c61
-rw-r--r--sm/certlist.c17
-rw-r--r--sm/gpgsm.c2
-rw-r--r--sm/gpgsm.h7
-rw-r--r--sm/keylist.c28
-rw-r--r--sm/server.c2
-rw-r--r--sm/verify.c2
9 files changed, 104 insertions, 29 deletions
diff --git a/doc/DETAILS b/doc/DETAILS
index 2e6874e9a..ddf7438f5 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -58,6 +58,10 @@ record; gpg2 does this by default and the option is a dummy.
u = The key is ultimately valid. This often means
that the secret key is available, but any key may
be marked as ultimately valid.
+ w = The key has a well known private part.
+ s = The key has special validity. This means that it
+ might be self-signed and expected to be used in
+ the STEED sytem.
If the validity information is given for a UID or UAT
record, it describes the validity calculated based on this
@@ -347,6 +351,7 @@ more arguments in future versions.
"pgp" for the standard PGP WoT.
"shell" for the standard X.509 model.
"chain" for the chain model.
+ "steed" for the STEED model.
Note that we use the term "TRUST_" in the status names for
historic reasons; we now speak of validity.
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index 8e25baf62..bdb03783e 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -451,10 +451,11 @@ address and the time when you verified the signature.
@item --validation-model @var{name}
@opindex validation-model
This option changes the default validation model. The only possible
-values are "shell" (which is the default) and "chain" which forces the
-use of the chain model. The chain model is also used if an option in
-the @file{trustlist.txt} or an attribute of the certificate requests it.
-However the standard model (shell) is in that case always tried first.
+values are "shell" (which is the default), "chain" which forces the
+use of the chain model and "steed" for a new simplified model. The
+chain model is also used if an option in the @file{trustlist.txt} or
+an attribute of the certificate requests it. However the standard
+model (shell) is in that case always tried first.
@item --ignore-cert-extension @var{oid}
@opindex ignore-cert-extension
diff --git a/sm/certchain.c b/sm/certchain.c
index 1a2632504..54c7a5772 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -1,6 +1,6 @@
/* certchain.c - certificate chain validation
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
- * 2006, 2007, 2008 Free Software Foundation, Inc.
+ * 2006, 2007, 2008, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -1193,6 +1193,7 @@ ask_marktrusted (ctrl_t ctrl, ksba_cert_t cert, int listmode)
VALIDATE_FLAG_NO_DIRMNGR - Do not do any dirmngr isvalid checks.
VALIDATE_FLAG_CHAIN_MODEL - Check according to chain model.
+ VALIDATE_FLAG_STEED - Check according to the STEED model.
*/
static int
do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
@@ -1305,13 +1306,21 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
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, NULL,
- rootca_flags);
+ if (gpgsm_cert_has_well_known_private_key (subject_cert))
+ {
+ memset (rootca_flags, 0, sizeof *rootca_flags);
+ istrusted_rc = ((flags & VALIDATE_FLAG_STEED)
+ ? 0 : gpg_error (GPG_ERR_NOT_TRUSTED));
+ }
+ else
+ istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, NULL,
+ rootca_flags);
audit_log_cert (ctrl->audit, AUDIT_ROOT_TRUSTED,
subject_cert, istrusted_rc);
/* If the chain model extended attribute is used, make sure
that our chain model flag is set. */
- if (has_validation_model_chain (subject_cert, listmode, listfp))
+ if (!(flags & VALIDATE_FLAG_STEED)
+ && has_validation_model_chain (subject_cert, listmode, listfp))
rootca_flags->chain_model = 1;
}
@@ -1383,7 +1392,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
/* Set the flag for qualified signatures. This flag is
deduced from a list of root certificates allowed for
qualified signatures. */
- if (is_qualified == -1)
+ if (is_qualified == -1 && !(flags & VALIDATE_FLAG_STEED))
{
gpg_error_t err;
size_t buflen;
@@ -1437,8 +1446,11 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
expired it does not make much sense to ask the user
whether we wants to trust the root certificate. We
should do this only if the certificate under question
- will then be usable. */
+ will then be usable. If the certificate has a well
+ known private key asking the user does not make any
+ sense. */
if ( !any_expired
+ && !gpgsm_cert_has_well_known_private_key (subject_cert)
&& (!listmode || !already_asked_marktrusted (subject_cert))
&& ask_marktrusted (ctrl, subject_cert, listmode) )
rc = 0;
@@ -1455,6 +1467,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
/* Check for revocations etc. */
if ((flags & VALIDATE_FLAG_NO_DIRMNGR))
;
+ else if ((flags & VALIDATE_FLAG_STEED))
+ ; /* Fixme: check revocations via DNS. */
else if (opt.no_trusted_cert_crl_check || rootca_flags->relax)
;
else
@@ -1586,8 +1600,16 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
performance reasons. */
if (is_root)
{
- istrusted_rc = gpgsm_agent_istrusted (ctrl, issuer_cert, NULL,
- rootca_flags);
+ if (gpgsm_cert_has_well_known_private_key (issuer_cert))
+ {
+ memset (rootca_flags, 0, sizeof *rootca_flags);
+ istrusted_rc = ((flags & VALIDATE_FLAG_STEED)
+ ? 0 : gpg_error (GPG_ERR_NOT_TRUSTED));
+ }
+ else
+ istrusted_rc = gpgsm_agent_istrusted
+ (ctrl, issuer_cert, NULL, rootca_flags);
+
if (!istrusted_rc && rootca_flags->relax)
{
/* Ignore the error due to the relax flag. */
@@ -1627,6 +1649,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
be fixed. */
if ((flags & VALIDATE_FLAG_NO_DIRMNGR))
rc = 0;
+ else if ((flags & VALIDATE_FLAG_STEED))
+ rc = 0; /* Fixme: XXX */
else if (is_root && (opt.no_trusted_cert_crl_check
|| (!istrusted_rc && rootca_flags->relax)))
rc = 0;
@@ -1722,7 +1746,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
capability of the certificate under question, store the result as
user data in all certificates of the chain. We do this even if the
validation itself failed. */
- if (is_qualified != -1)
+ if (is_qualified != -1 && !(flags & VALIDATE_FLAG_STEED))
{
gpg_error_t err;
chain_item_t ci;
@@ -1780,8 +1804,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
do_validate_chain. This function is a wrapper to handle a root
certificate with the chain_model flag set. If RETFLAGS is not
NULL, flags indicating now the verification was done are stored
- there. The only defined flag for RETFLAGS is
- VALIDATE_FLAG_CHAIN_MODEL.
+ there. The only defined vits for RETFLAGS are
+ VALIDATE_FLAG_CHAIN_MODEL and VALIDATE_FLAG_STEED.
If you are verifying a signature you should set CHECKTIME to the
creation time of the signature. If your are verifying a
@@ -1801,16 +1825,27 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
if (!retflags)
retflags = &dummy_retflags;
+ /* If the session requested a certain validation mode make sure the
+ corresponding flags are set. */
if (ctrl->validation_model == 1)
flags |= VALIDATE_FLAG_CHAIN_MODEL;
+ else if (ctrl->validation_model == 2)
+ flags |= VALIDATE_FLAG_STEED;
+ /* If the chain model was forced, set this immediately into
+ RETFLAGS. */
*retflags = (flags & VALIDATE_FLAG_CHAIN_MODEL);
+
memset (&rootca_flags, 0, sizeof rootca_flags);
rc = do_validate_chain (ctrl, cert, checktime,
r_exptime, listmode, listfp, flags,
&rootca_flags);
- if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED
+ if (!rc && (flags & VALIDATE_FLAG_STEED))
+ {
+ *retflags |= VALIDATE_FLAG_STEED;
+ }
+ else if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED
&& !(flags & VALIDATE_FLAG_CHAIN_MODEL)
&& (rootca_flags.valid && rootca_flags.chain_model))
{
@@ -1824,6 +1859,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
if (opt.verbose)
do_list (0, listmode, listfp, _("validation model used: %s"),
+ (*retflags & VALIDATE_FLAG_STEED)?
+ "steed" :
(*retflags & VALIDATE_FLAG_CHAIN_MODEL)?
_("chain"):_("shell"));
diff --git a/sm/certlist.c b/sm/certlist.c
index 0e9031953..241364a3a 100644
--- a/sm/certlist.c
+++ b/sm/certlist.c
@@ -1,6 +1,6 @@
/* certlist.c - build list of certificates
* Copyright (C) 2001, 2003, 2004, 2005, 2007,
- * 2008 Free Software Foundation, Inc.
+ * 2008, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -210,6 +210,21 @@ gpgsm_cert_use_ocsp_p (ksba_cert_t cert)
}
+/* Return true if CERT has the well known private key extension. */
+int
+gpgsm_cert_has_well_known_private_key (ksba_cert_t cert)
+{
+ int idx;
+ const char *oid;
+
+ for (idx=0; !ksba_cert_get_extension (cert, idx,
+ &oid, NULL, NULL, NULL);idx++)
+ if (!strcmp (oid, "1.3.6.1.4.1.11591.2.2.2") )
+ return 1; /* Yes. */
+ return 0; /* No. */
+}
+
+
static int
same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert)
{
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index dc9f2e032..7164f4274 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -2004,6 +2004,8 @@ gpgsm_parse_validation_model (const char *model)
return 0;
else if ( !ascii_strcasecmp (model, "chain") )
return 1;
+ else if ( !ascii_strcasecmp (model, "steed") )
+ return 2;
else
return -1;
}
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 31cd95150..6c68af746 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -195,7 +195,9 @@ struct server_control_s
certificates up the chain (0 = none, 1 = only
signer) */
int use_ocsp; /* Set to true if OCSP should be used. */
- int validation_model; /* Set to 1 for the chain model. */
+ int validation_model; /* 0 := standard model (shell),
+ 1 := chain model,
+ 2 := STEED model. */
};
@@ -307,7 +309,7 @@ int gpgsm_create_cms_signature (ctrl_t ctrl,
/* Flags used with gpgsm_validate_chain. */
#define VALIDATE_FLAG_NO_DIRMNGR 1
#define VALIDATE_FLAG_CHAIN_MODEL 2
-
+#define VALIDATE_FLAG_STEED 4
int gpgsm_walk_cert_chain (ctrl_t ctrl,
ksba_cert_t start, ksba_cert_t *r_next);
@@ -326,6 +328,7 @@ int gpgsm_cert_use_verify_p (ksba_cert_t cert);
int gpgsm_cert_use_decrypt_p (ksba_cert_t cert);
int gpgsm_cert_use_cert_p (ksba_cert_t cert);
int gpgsm_cert_use_ocsp_p (ksba_cert_t cert);
+int gpgsm_cert_has_well_known_private_key (ksba_cert_t cert);
int gpgsm_certs_identical_p (ksba_cert_t cert_a, ksba_cert_t cert_b);
int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
certlist_t *listaddr, int is_encrypt_to);
diff --git a/sm/keylist.c b/sm/keylist.c
index a5023601f..42c533a6d 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -1,6 +1,6 @@
/* keylist.c - Print certificates in various formats.
- * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- * 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2008, 2009,
+ * 2010, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -421,7 +421,12 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
&& *not_after && strcmp (current_time, not_after) > 0 )
*truststring = 'e';
else if (valerr)
- *truststring = 'i';
+ {
+ if (gpgsm_cert_has_well_known_private_key (cert))
+ *truststring = 'w'; /* Well, this is dummy CA. */
+ else
+ *truststring = 'i';
+ }
else if (ctrl->with_validation && !is_root)
*truststring = 'f';
}
@@ -433,12 +438,17 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
{
struct rootca_flags_s dummy_flags;
- rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
- if (!rc)
- *truststring = 'u'; /* Yes, we trust this one (ultimately). */
- else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
- *truststring = 'n'; /* No, we do not trust this one. */
- /* (in case of an error we can't tell anything.) */
+ if (gpgsm_cert_has_well_known_private_key (cert))
+ *truststring = 'w'; /* Well, this is dummy CA. */
+ else
+ {
+ rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
+ if (!rc)
+ *truststring = 'u'; /* Yes, we trust this one (ultimately). */
+ else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
+ *truststring = 'n'; /* No, we do not trust this one. */
+ /* (in case of an error we can't tell anything.) */
+ }
}
if (*truststring)
diff --git a/sm/server.c b/sm/server.c
index 19c4a1678..385eb538a 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -277,7 +277,7 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
else if (!strcmp (key, "validation-model"))
{
int i = gpgsm_parse_validation_model (value);
- if ( i >= 0 && i <= 1 )
+ if ( i >= 0 && i <= 2 )
ctrl->validation_model = i;
else
err = gpg_error (GPG_ERR_ASS_PARAMETER);
diff --git a/sm/verify.c b/sm/verify.c
index c77eb5744..1173f66d1 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -624,6 +624,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
}
gpgsm_status (ctrl, STATUS_TRUST_FULLY,
+ (verifyflags & VALIDATE_FLAG_STEED)?
+ "0 steed":
(verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
"0 chain": "0 shell");