mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
gpgsm: Add new validation model "steed".
* sm/gpgsm.h (VALIDATE_FLAG_STEED): New. * sm/gpgsm.c (gpgsm_parse_validation_model): Add model "steed". * sm/server.c (option_handler): Allow validation model "steed". * sm/certlist.c (gpgsm_cert_has_well_known_private_key): New. * sm/certchain.c (do_validate_chain): Handle the well-known-private-key attribute. Support the "steed" model. (gpgsm_validate_chain): Ditto. * sm/verify.c (gpgsm_verify): Return "steed" in the trust status line. * sm/keylist.c (list_cert_colon): Print the new 'w' flag. -- This is the first part of changes to implement the STEED proposal as described at http://g10code.com/steed.html . The idea for X.509 is not to use plain self-signed certificates but certificates signed by a dummy CA (i.e. one for which the private key is known). Having a single CA as an indication for the use of STEED might help other X.509 implementations to implement STEED.
This commit is contained in:
parent
14e4fdc9f9
commit
8a12a2000d
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
28
sm/keylist.c
28
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)
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user