mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
* gpgsm.c: New option --with-md5-fingerprint.
* keylist.c (list_cert_std): Print MD5 fpr. * gpgsm.c: New options --with-validation. * server.c (option_handler): New option "with-validation". * keylist.c (list_cert_std, list_internal_keys): New args CTRL and WITH_VALIDATION. Changed callers to set it. (list_external_cb, list_external_keys): Pass CTRL to the callback. (list_cert_colon): Add arg CTRL. Check validation if requested. * certchain.c (unknown_criticals, allowed_ca, check_cert_policy) (gpgsm_validate_chain): New args LISTMODE and FP. (do_list): New helper for info output. (find_up): New arg FIND_NEXT. (gpgsm_validate_chain): After a bad signature try again with other CA certificates. * import.c (print_imported_status): New arg NEW_CERT. Print additional STATUS_IMPORT_OK becuase that is what gpgme expects. (check_and_store): Always call above function after import. * server.c (get_status_string): Added STATUS_IMPORT_OK.
This commit is contained in:
parent
a5fc1f40c3
commit
45a817bf4a
23
sm/ChangeLog
23
sm/ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
2004-02-17 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* gpgsm.c: New option --with-md5-fingerprint.
|
||||||
|
* keylist.c (list_cert_std): Print MD5 fpr.
|
||||||
|
|
||||||
|
* gpgsm.c: New options --with-validation.
|
||||||
|
* server.c (option_handler): New option "with-validation".
|
||||||
|
* keylist.c (list_cert_std, list_internal_keys): New args CTRL and
|
||||||
|
WITH_VALIDATION. Changed callers to set it.
|
||||||
|
(list_external_cb, list_external_keys): Pass CTRL to the callback.
|
||||||
|
(list_cert_colon): Add arg CTRL. Check validation if requested.
|
||||||
|
* certchain.c (unknown_criticals, allowed_ca, check_cert_policy)
|
||||||
|
(gpgsm_validate_chain): New args LISTMODE and FP.
|
||||||
|
(do_list): New helper for info output.
|
||||||
|
(find_up): New arg FIND_NEXT.
|
||||||
|
(gpgsm_validate_chain): After a bad signature try again with other
|
||||||
|
CA certificates.
|
||||||
|
|
||||||
|
* import.c (print_imported_status): New arg NEW_CERT. Print
|
||||||
|
additional STATUS_IMPORT_OK becuase that is what gpgme expects.
|
||||||
|
(check_and_store): Always call above function after import.
|
||||||
|
* server.c (get_status_string): Added STATUS_IMPORT_OK.
|
||||||
|
|
||||||
2004-02-13 Werner Koch <wk@gnupg.org>
|
2004-02-13 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* certcheck.c (gpgsm_create_cms_signature): Format a description
|
* certcheck.c (gpgsm_create_cms_signature): Format a description
|
||||||
|
269
sm/certchain.c
269
sm/certchain.c
@ -1,5 +1,5 @@
|
|||||||
/* certchain.c - certificate chain validation
|
/* certchain.c - certificate chain validation
|
||||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -25,8 +25,11 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define JNLIB_NEED_LOG_LOGV /* We need log_logv. */
|
||||||
|
|
||||||
#include "gpgsm.h"
|
#include "gpgsm.h"
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
@ -35,8 +38,37 @@
|
|||||||
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
|
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* If LISTMODE is true, print FORMAT in liting mode to FP. If
|
||||||
|
LISTMODE is false, use the string to print an log_info or, if
|
||||||
|
IS_ERROR is true, an log_error. */
|
||||||
|
static void
|
||||||
|
do_list (int is_error, int listmode, FILE *fp, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
|
||||||
|
va_start (arg_ptr, format) ;
|
||||||
|
if (listmode)
|
||||||
|
{
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
fputs (" [", fp);
|
||||||
|
vfprintf (fp, format, arg_ptr);
|
||||||
|
fputs ("]\n", fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_logv (is_error? JNLIB_LOG_ERROR: JNLIB_LOG_INFO, format, arg_ptr);
|
||||||
|
log_printf ("\n");
|
||||||
|
}
|
||||||
|
va_end (arg_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
unknown_criticals (ksba_cert_t cert)
|
unknown_criticals (ksba_cert_t cert, int listmode, FILE *fp)
|
||||||
{
|
{
|
||||||
static const char *known[] = {
|
static const char *known[] = {
|
||||||
"2.5.29.15", /* keyUsage */
|
"2.5.29.15", /* keyUsage */
|
||||||
@ -57,8 +89,9 @@ unknown_criticals (ksba_cert_t cert)
|
|||||||
;
|
;
|
||||||
if (!known[i])
|
if (!known[i])
|
||||||
{
|
{
|
||||||
log_error (_("critical certificate extension %s is not supported\n"),
|
do_list (1, listmode, fp,
|
||||||
oid);
|
_("critical certificate extension %s is not supported"),
|
||||||
|
oid);
|
||||||
rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT);
|
rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +102,7 @@ unknown_criticals (ksba_cert_t cert)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
allowed_ca (ksba_cert_t cert, int *chainlen)
|
allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, FILE *fp)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int flag;
|
int flag;
|
||||||
@ -79,7 +112,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen)
|
|||||||
return err;
|
return err;
|
||||||
if (!flag)
|
if (!flag)
|
||||||
{
|
{
|
||||||
log_error (_("issuer certificate is not marked as a CA\n"));
|
do_list (1, listmode, fp,_("issuer certificate is not marked as a CA"));
|
||||||
return gpg_error (GPG_ERR_BAD_CA_CERT);
|
return gpg_error (GPG_ERR_BAD_CA_CERT);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -87,7 +120,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_cert_policy (ksba_cert_t cert)
|
check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char *policies;
|
char *policies;
|
||||||
@ -105,7 +138,7 @@ check_cert_policy (ksba_cert_t cert)
|
|||||||
first field is the OID of the policy and the second field either
|
first field is the OID of the policy and the second field either
|
||||||
N or C for normal or critical extension */
|
N or C for normal or critical extension */
|
||||||
|
|
||||||
if (opt.verbose > 1)
|
if (opt.verbose > 1 && !listmode)
|
||||||
log_info ("certificate's policy list: %s\n", policies);
|
log_info ("certificate's policy list: %s\n", policies);
|
||||||
|
|
||||||
/* The check is very minimal but won't give false positives */
|
/* The check is very minimal but won't give false positives */
|
||||||
@ -116,7 +149,8 @@ check_cert_policy (ksba_cert_t cert)
|
|||||||
xfree (policies);
|
xfree (policies);
|
||||||
if (any_critical)
|
if (any_critical)
|
||||||
{
|
{
|
||||||
log_error ("critical marked policy without configured policies\n");
|
do_list (1, listmode, fplist,
|
||||||
|
_("critical marked policy without configured policies"));
|
||||||
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
|
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -131,10 +165,12 @@ check_cert_policy (ksba_cert_t cert)
|
|||||||
/* With no critical policies this is only a warning */
|
/* With no critical policies this is only a warning */
|
||||||
if (!any_critical)
|
if (!any_critical)
|
||||||
{
|
{
|
||||||
log_info (_("note: certificate policy not allowed\n"));
|
do_list (0, listmode, fplist,
|
||||||
|
_("note: non-critical certificate policy not allowed"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_error (_("certificate policy not allowed\n"));
|
do_list (1, listmode, fplist,
|
||||||
|
_("certificate policy not allowed"));
|
||||||
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
|
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,10 +194,12 @@ check_cert_policy (ksba_cert_t cert)
|
|||||||
/* With no critical policies this is only a warning */
|
/* With no critical policies this is only a warning */
|
||||||
if (!any_critical)
|
if (!any_critical)
|
||||||
{
|
{
|
||||||
log_info (_("note: certificate policy not allowed\n"));
|
do_list (0, listmode, fplist,
|
||||||
|
_("note: non-critical certificate policy not allowed"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_error (_("certificate policy not allowed\n"));
|
do_list (1, listmode, fplist,
|
||||||
|
_("certificate policy not allowed"));
|
||||||
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
|
return gpg_error (GPG_ERR_NO_POLICY_MATCH);
|
||||||
}
|
}
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
@ -222,7 +260,7 @@ find_up_store_certs_cb (void *cb_value, ksba_cert_t cert)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer)
|
find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
||||||
{
|
{
|
||||||
ksba_name_t authid;
|
ksba_name_t authid;
|
||||||
ksba_sexp_t authidno;
|
ksba_sexp_t authidno;
|
||||||
@ -236,8 +274,12 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer)
|
|||||||
rc = keydb_search_issuer_sn (kh, s, authidno);
|
rc = keydb_search_issuer_sn (kh, s, authidno);
|
||||||
if (rc)
|
if (rc)
|
||||||
keydb_search_reset (kh);
|
keydb_search_reset (kh);
|
||||||
if (rc == -1)
|
|
||||||
{ /* And try the ephemeral DB. */
|
/* In case of an error try the ephemeral DB. We can't do
|
||||||
|
that in find-netx mode because we can't keep the search
|
||||||
|
state then. */
|
||||||
|
if (rc == -1 && !find_next)
|
||||||
|
{
|
||||||
int old = keydb_set_ephemeral (kh, 1);
|
int old = keydb_set_ephemeral (kh, 1);
|
||||||
if (!old)
|
if (!old)
|
||||||
{
|
{
|
||||||
@ -248,9 +290,9 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer)
|
|||||||
keydb_set_ephemeral (kh, old);
|
keydb_set_ephemeral (kh, old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* print a note so that the user does not feel too helpless when
|
/* Print a note so that the user does not feel too helpless when
|
||||||
an issuer certificate was found and gpgsm prints BAD
|
an issuer certificate was found and gpgsm prints BAD
|
||||||
signature becuase it is not the correct one. */
|
signature because it is not the correct one. */
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
{
|
{
|
||||||
log_info ("issuer certificate (#");
|
log_info ("issuer certificate (#");
|
||||||
@ -267,8 +309,8 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */
|
if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */
|
||||||
rc = keydb_search_subject (kh, issuer);
|
rc = keydb_search_subject (kh, issuer);
|
||||||
if (rc == -1)
|
if (rc == -1 && !find_next)
|
||||||
{
|
{
|
||||||
/* Not found, lets see whether we have one in the ephemeral key DB. */
|
/* Not found, lets see whether we have one in the ephemeral key DB. */
|
||||||
int old = keydb_set_ephemeral (kh, 1);
|
int old = keydb_set_ephemeral (kh, 1);
|
||||||
@ -280,7 +322,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer)
|
|||||||
keydb_set_ephemeral (kh, old);
|
keydb_set_ephemeral (kh, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == -1 && opt.auto_issuer_key_retrieve)
|
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
|
||||||
{
|
{
|
||||||
STRLIST names = NULL;
|
STRLIST names = NULL;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -368,7 +410,7 @@ gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = find_up (kh, start, issuer);
|
rc = find_up (kh, start, issuer, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
/* it is quite common not to have a certificate, so better don't
|
/* it is quite common not to have a certificate, so better don't
|
||||||
@ -413,9 +455,12 @@ gpgsm_is_root_cert (ksba_cert_t cert)
|
|||||||
|
|
||||||
|
|
||||||
/* Validate a chain and optionally return the nearest expiration time
|
/* Validate a chain and optionally return the nearest expiration time
|
||||||
in R_EXPTIME */
|
in R_EXPTIME. With LISTMODE set to 1 a special listmode is
|
||||||
|
activated where only information about the certificate is printed
|
||||||
|
to FP and no outputis send to the usual log stream. */
|
||||||
int
|
int
|
||||||
gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
|
||||||
|
int listmode, FILE *fp)
|
||||||
{
|
{
|
||||||
int rc = 0, depth = 0, maxdepth;
|
int rc = 0, depth = 0, maxdepth;
|
||||||
char *issuer = NULL;
|
char *issuer = NULL;
|
||||||
@ -429,14 +474,14 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
int any_no_crl = 0;
|
int any_no_crl = 0;
|
||||||
int any_crl_too_old = 0;
|
int any_crl_too_old = 0;
|
||||||
int any_no_policy_match = 0;
|
int any_no_policy_match = 0;
|
||||||
|
int lm = listmode;
|
||||||
|
|
||||||
gnupg_get_isotime (current_time);
|
gnupg_get_isotime (current_time);
|
||||||
if (r_exptime)
|
if (r_exptime)
|
||||||
*r_exptime = 0;
|
*r_exptime = 0;
|
||||||
*exptime = 0;
|
*exptime = 0;
|
||||||
|
|
||||||
if (opt.no_chain_validation)
|
if (opt.no_chain_validation && !listmode)
|
||||||
{
|
{
|
||||||
log_info ("WARNING: bypassing certificate chain validation\n");
|
log_info ("WARNING: bypassing certificate chain validation\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -449,7 +494,7 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBG_X509)
|
if (DBG_X509 && !listmode)
|
||||||
gpgsm_dump_cert ("subject", cert);
|
gpgsm_dump_cert ("subject", cert);
|
||||||
|
|
||||||
subject_cert = cert;
|
subject_cert = cert;
|
||||||
@ -464,7 +509,7 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
|
|
||||||
if (!issuer)
|
if (!issuer)
|
||||||
{
|
{
|
||||||
log_error ("no issuer found in certificate\n");
|
do_list (1, lm, fp, _("no issuer found in certificate"));
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT);
|
rc = gpg_error (GPG_ERR_BAD_CERT);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -477,8 +522,8 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
rc = ksba_cert_get_validity (subject_cert, 1, not_after);
|
rc = ksba_cert_get_validity (subject_cert, 1, not_after);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error (_("certificate with invalid validity: %s\n"),
|
do_list (1, lm, fp, _("certificate with invalid validity: %s"),
|
||||||
gpg_strerror (rc));
|
gpg_strerror (rc));
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT);
|
rc = gpg_error (GPG_ERR_BAD_CERT);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -493,28 +538,36 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
|
|
||||||
if (*not_before && strcmp (current_time, not_before) < 0 )
|
if (*not_before && strcmp (current_time, not_before) < 0 )
|
||||||
{
|
{
|
||||||
log_error ("certificate too young; valid from ");
|
do_list (1, lm, fp, _("certificate not yet valid"));
|
||||||
gpgsm_dump_time (not_before);
|
if (!lm)
|
||||||
log_printf ("\n");
|
{
|
||||||
|
log_info ("(valid from ");
|
||||||
|
gpgsm_dump_time (not_before);
|
||||||
|
log_printf (")\n");
|
||||||
|
}
|
||||||
rc = gpg_error (GPG_ERR_CERT_TOO_YOUNG);
|
rc = gpg_error (GPG_ERR_CERT_TOO_YOUNG);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if (not_after && strcmp (current_time, not_after) > 0 )
|
if (not_after && strcmp (current_time, not_after) > 0 )
|
||||||
{
|
{
|
||||||
log_error ("certificate has expired at ");
|
do_list (1, lm, fp, _("certificate has expired"));
|
||||||
gpgsm_dump_time (not_after);
|
if (!lm)
|
||||||
log_printf ("\n");
|
{
|
||||||
|
log_error ("(expired at ");
|
||||||
|
gpgsm_dump_time (not_after);
|
||||||
|
log_printf (")\n");
|
||||||
|
}
|
||||||
any_expired = 1;
|
any_expired = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = unknown_criticals (subject_cert);
|
rc = unknown_criticals (subject_cert, listmode, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (!opt.no_policy_check)
|
if (!opt.no_policy_check)
|
||||||
{
|
{
|
||||||
rc = check_cert_policy (subject_cert);
|
rc = check_cert_policy (subject_cert, listmode, fp);
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH)
|
if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH)
|
||||||
{
|
{
|
||||||
any_no_policy_match = 1;
|
any_no_policy_match = 1;
|
||||||
@ -534,7 +587,7 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
switch (gpg_err_code (rc))
|
switch (gpg_err_code (rc))
|
||||||
{
|
{
|
||||||
case GPG_ERR_CERT_REVOKED:
|
case GPG_ERR_CERT_REVOKED:
|
||||||
log_error (_("the certificate has been revoked\n"));
|
do_list (1, lm, fp, _("certificate has been revoked"));
|
||||||
any_revoked = 1;
|
any_revoked = 1;
|
||||||
/* Store that in the keybox so that key listings are
|
/* Store that in the keybox so that key listings are
|
||||||
able to return the revoked flag. We don't care
|
able to return the revoked flag. We don't care
|
||||||
@ -543,18 +596,19 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
VALIDITY_REVOKED);
|
VALIDITY_REVOKED);
|
||||||
break;
|
break;
|
||||||
case GPG_ERR_NO_CRL_KNOWN:
|
case GPG_ERR_NO_CRL_KNOWN:
|
||||||
log_error (_("no CRL found for certificate\n"));
|
do_list (1, lm, fp, _("no CRL found for certificate"));
|
||||||
any_no_crl = 1;
|
any_no_crl = 1;
|
||||||
break;
|
break;
|
||||||
case GPG_ERR_CRL_TOO_OLD:
|
case GPG_ERR_CRL_TOO_OLD:
|
||||||
log_error (_("the available CRL is too old\n"));
|
do_list (1, lm, fp, _("the available CRL is too old"));
|
||||||
log_info (_("please make sure that the "
|
if (!lm)
|
||||||
"\"dirmngr\" is properly installed\n"));
|
log_info (_("please make sure that the "
|
||||||
|
"\"dirmngr\" is properly installed\n"));
|
||||||
any_crl_too_old = 1;
|
any_crl_too_old = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_error (_("checking the CRL failed: %s\n"),
|
do_list (1, lm, fp, _("checking the CRL failed: %s"),
|
||||||
gpg_strerror (rc));
|
gpg_strerror (rc));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@ -565,12 +619,13 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
{
|
{
|
||||||
if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
|
if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
|
||||||
{
|
{
|
||||||
log_error ("selfsigned certificate has a BAD signatures\n");
|
do_list (1, lm, fp,
|
||||||
|
_("selfsigned certificate has a BAD signature"));
|
||||||
rc = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN
|
rc = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN
|
||||||
: GPG_ERR_BAD_CERT);
|
: GPG_ERR_BAD_CERT);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
rc = allowed_ca (subject_cert, NULL);
|
rc = allowed_ca (subject_cert, NULL, listmode, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -579,26 +634,28 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
;
|
;
|
||||||
else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
|
else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
|
||||||
{
|
{
|
||||||
int rc2;
|
do_list (0, lm, fp, _("root certificate is not marked trusted"));
|
||||||
|
if (!lm)
|
||||||
char *fpr = gpgsm_get_fingerprint_string (subject_cert,
|
|
||||||
GCRY_MD_SHA1);
|
|
||||||
log_info (_("root certificate is not marked trusted\n"));
|
|
||||||
log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
|
|
||||||
xfree (fpr);
|
|
||||||
rc2 = gpgsm_agent_marktrusted (subject_cert);
|
|
||||||
if (!rc2)
|
|
||||||
{
|
{
|
||||||
log_info (_("root certificate has now"
|
int rc2;
|
||||||
" been marked as trusted\n"));
|
char *fpr = gpgsm_get_fingerprint_string (subject_cert,
|
||||||
rc = 0;
|
GCRY_MD_SHA1);
|
||||||
}
|
log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
|
||||||
else
|
xfree (fpr);
|
||||||
{
|
rc2 = gpgsm_agent_marktrusted (subject_cert);
|
||||||
gpgsm_dump_cert ("issuer", subject_cert);
|
if (!rc2)
|
||||||
log_info ("after checking the fingerprint, you may want "
|
{
|
||||||
"to add it manually to the list of trusted "
|
log_info (_("root certificate has now"
|
||||||
"certificates.\n");
|
" been marked as trusted\n"));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpgsm_dump_cert ("issuer", subject_cert);
|
||||||
|
log_info ("after checking the fingerprint, you may want "
|
||||||
|
"to add it manually to the list of trusted "
|
||||||
|
"certificates.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -613,21 +670,25 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
depth++;
|
depth++;
|
||||||
if (depth > maxdepth)
|
if (depth > maxdepth)
|
||||||
{
|
{
|
||||||
log_error (_("certificate chain too long\n"));
|
do_list (1, lm, fp, _("certificate chain too long\n"));
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
|
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the next cert up the tree */
|
/* find the next cert up the tree */
|
||||||
keydb_search_reset (kh);
|
keydb_search_reset (kh);
|
||||||
rc = find_up (kh, subject_cert, issuer);
|
rc = find_up (kh, subject_cert, issuer, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
{
|
{
|
||||||
log_info ("issuer certificate (#/");
|
do_list (0, lm, fp, _("issuer certificate not found"));
|
||||||
gpgsm_dump_string (issuer);
|
if (!lm)
|
||||||
log_printf (") not found\n");
|
{
|
||||||
|
log_info ("issuer certificate: #/");
|
||||||
|
gpgsm_dump_string (issuer);
|
||||||
|
log_printf ("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
||||||
@ -635,6 +696,7 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try_another_cert:
|
||||||
ksba_cert_release (issuer_cert); issuer_cert = NULL;
|
ksba_cert_release (issuer_cert); issuer_cert = NULL;
|
||||||
rc = keydb_get_cert (kh, &issuer_cert);
|
rc = keydb_get_cert (kh, &issuer_cert);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -650,38 +712,56 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
gpgsm_dump_cert ("issuer", issuer_cert);
|
gpgsm_dump_cert ("issuer", issuer_cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
|
rc = gpgsm_check_cert_sig (issuer_cert, subject_cert);
|
||||||
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("certificate has a BAD signatures\n");
|
do_list (0, lm, fp, _("certificate has a BAD signature"));
|
||||||
|
if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE)
|
||||||
|
{
|
||||||
|
rc = find_up (kh, subject_cert, issuer, 1);
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
do_list (0, lm, fp, _("found another possible matching "
|
||||||
|
"CA certificate - trying again"));
|
||||||
|
goto try_another_cert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We give a more descriptive error code than the one
|
||||||
|
returned from the signature checking. */
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
|
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int chainlen;
|
int chainlen;
|
||||||
rc = allowed_ca (issuer_cert, &chainlen);
|
rc = allowed_ca (issuer_cert, &chainlen, listmode, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
if (chainlen >= 0 && (depth - 1) > chainlen)
|
if (chainlen >= 0 && (depth - 1) > chainlen)
|
||||||
{
|
{
|
||||||
log_error (_("certificate chain longer than allowed by CA (%d)\n"),
|
do_list (1, lm, fp,
|
||||||
chainlen);
|
_("certificate chain longer than allowed by CA (%d)"),
|
||||||
|
chainlen);
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
|
rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = gpgsm_cert_use_cert_p (issuer_cert);
|
if (!listmode)
|
||||||
if (rc)
|
|
||||||
{
|
{
|
||||||
char numbuf[50];
|
rc = gpgsm_cert_use_cert_p (issuer_cert);
|
||||||
sprintf (numbuf, "%d", rc);
|
if (rc)
|
||||||
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
|
{
|
||||||
numbuf, NULL);
|
char numbuf[50];
|
||||||
rc = 0;
|
sprintf (numbuf, "%d", rc);
|
||||||
|
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
|
||||||
|
numbuf, NULL);
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose && !listmode)
|
||||||
log_info ("certificate is good\n");
|
log_info ("certificate is good\n");
|
||||||
|
|
||||||
keydb_search_reset (kh);
|
keydb_search_reset (kh);
|
||||||
@ -689,10 +769,15 @@ gpgsm_validate_chain (CTRL ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime)
|
|||||||
issuer_cert = NULL;
|
issuer_cert = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.no_policy_check)
|
if (!listmode)
|
||||||
log_info ("policies not checked due to --disable-policy-checks option\n");
|
{
|
||||||
if (opt.no_crl_check && !ctrl->use_ocsp)
|
if (opt.no_policy_check)
|
||||||
log_info ("CRLs not checked due to --disable-crl-checks option\n");
|
log_info ("policies not checked due to %s option\n",
|
||||||
|
"--disable-policy-checks");
|
||||||
|
if (opt.no_crl_check && !ctrl->use_ocsp)
|
||||||
|
log_info ("CRLs not checked due to %s option\n",
|
||||||
|
"--disable-crl-checks");
|
||||||
|
}
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{ /* If we encountered an error somewhere during the checks, set
|
{ /* If we encountered an error somewhere during the checks, set
|
||||||
@ -733,7 +818,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert)
|
|||||||
char *subject = NULL;
|
char *subject = NULL;
|
||||||
KEYDB_HANDLE kh = keydb_new (0);
|
KEYDB_HANDLE kh = keydb_new (0);
|
||||||
ksba_cert_t issuer_cert = NULL;
|
ksba_cert_t issuer_cert = NULL;
|
||||||
|
|
||||||
if (opt.no_chain_validation)
|
if (opt.no_chain_validation)
|
||||||
{
|
{
|
||||||
log_info ("WARNING: bypassing basic certificate checks\n");
|
log_info ("WARNING: bypassing basic certificate checks\n");
|
||||||
@ -760,7 +845,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert)
|
|||||||
{
|
{
|
||||||
if (gpgsm_check_cert_sig (cert, cert) )
|
if (gpgsm_check_cert_sig (cert, cert) )
|
||||||
{
|
{
|
||||||
log_error ("selfsigned certificate has a BAD signatures\n");
|
log_error ("selfsigned certificate has a BAD signature\n");
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT);
|
rc = gpg_error (GPG_ERR_BAD_CERT);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -769,7 +854,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert)
|
|||||||
{
|
{
|
||||||
/* find the next cert up the tree */
|
/* find the next cert up the tree */
|
||||||
keydb_search_reset (kh);
|
keydb_search_reset (kh);
|
||||||
rc = find_up (kh, cert, issuer);
|
rc = find_up (kh, cert, issuer, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
@ -795,7 +880,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert)
|
|||||||
|
|
||||||
if (gpgsm_check_cert_sig (issuer_cert, cert) )
|
if (gpgsm_check_cert_sig (issuer_cert, cert) )
|
||||||
{
|
{
|
||||||
log_error ("certificate has a BAD signatures\n");
|
log_error ("certificate has a BAD signature\n");
|
||||||
rc = gpg_error (GPG_ERR_BAD_CERT);
|
rc = gpg_error (GPG_ERR_BAD_CERT);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ do_encode_md (gcry_md_hd_t md, int algo, unsigned int nbits,
|
|||||||
asnlen = DIM(asn);
|
asnlen = DIM(asn);
|
||||||
if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
|
if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
|
||||||
{
|
{
|
||||||
log_error ("No object identifier for algo %d\n", algo);
|
log_error ("no object identifier for algo %d\n", algo);
|
||||||
return gpg_error (GPG_ERR_INTERNAL);
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = gpgsm_validate_chain (ctrl, cert, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
CERTLIST cl = xtrycalloc (1, sizeof *cl);
|
CERTLIST cl = xtrycalloc (1, sizeof *cl);
|
||||||
|
12
sm/gpgsm.c
12
sm/gpgsm.c
@ -1,5 +1,5 @@
|
|||||||
/* gpgsm.c - GnuPG for S/MIME
|
/* gpgsm.c - GnuPG for S/MIME
|
||||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -125,6 +125,7 @@ enum cmd_and_opt_values {
|
|||||||
oTextmode,
|
oTextmode,
|
||||||
oFingerprint,
|
oFingerprint,
|
||||||
oWithFingerprint,
|
oWithFingerprint,
|
||||||
|
oWithMD5Fingerprint,
|
||||||
oAnswerYes,
|
oAnswerYes,
|
||||||
oAnswerNo,
|
oAnswerNo,
|
||||||
oKeyring,
|
oKeyring,
|
||||||
@ -158,6 +159,7 @@ enum cmd_and_opt_values {
|
|||||||
oHomedir,
|
oHomedir,
|
||||||
oWithColons,
|
oWithColons,
|
||||||
oWithKeyData,
|
oWithKeyData,
|
||||||
|
oWithValidation,
|
||||||
oSkipVerify,
|
oSkipVerify,
|
||||||
oCompressKeys,
|
oCompressKeys,
|
||||||
oCompressSigs,
|
oCompressSigs,
|
||||||
@ -378,6 +380,8 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oNoBatch, "no-batch", 0, "@" },
|
{ oNoBatch, "no-batch", 0, "@" },
|
||||||
{ oWithColons, "with-colons", 0, "@"},
|
{ oWithColons, "with-colons", 0, "@"},
|
||||||
{ oWithKeyData,"with-key-data", 0, "@"},
|
{ oWithKeyData,"with-key-data", 0, "@"},
|
||||||
|
{ oWithValidation, "with-validation", 0, "@"},
|
||||||
|
{ oWithMD5Fingerprint, "with-md5-fingerprint", 0, "@"},
|
||||||
{ aListKeys, "list-key", 0, "@" }, /* alias */
|
{ aListKeys, "list-key", 0, "@" }, /* alias */
|
||||||
{ aListSigs, "list-sig", 0, "@" }, /* alias */
|
{ aListSigs, "list-sig", 0, "@" }, /* alias */
|
||||||
{ aListSigs, "check-sig",0, "@" }, /* alias */
|
{ aListSigs, "check-sig",0, "@" }, /* alias */
|
||||||
@ -925,6 +929,8 @@ main ( int argc, char **argv)
|
|||||||
|
|
||||||
case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
|
case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
|
||||||
case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
|
case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
|
||||||
|
case oWithMD5Fingerprint:
|
||||||
|
opt.with_md5_fingerprint=1; /*fall thru*/
|
||||||
case oWithFingerprint:
|
case oWithFingerprint:
|
||||||
with_fpr=1; /*fall thru*/
|
with_fpr=1; /*fall thru*/
|
||||||
case oFingerprint:
|
case oFingerprint:
|
||||||
@ -980,6 +986,7 @@ main ( int argc, char **argv)
|
|||||||
|
|
||||||
case oWithKeyData: opt.with_key_data=1; /* fall thru */
|
case oWithKeyData: opt.with_key_data=1; /* fall thru */
|
||||||
case oWithColons: ctrl.with_colons = 1; break;
|
case oWithColons: ctrl.with_colons = 1; break;
|
||||||
|
case oWithValidation: ctrl.with_validation=1; break;
|
||||||
|
|
||||||
case oSkipVerify: opt.skip_verify=1; break;
|
case oSkipVerify: opt.skip_verify=1; break;
|
||||||
|
|
||||||
@ -1291,7 +1298,8 @@ main ( int argc, char **argv)
|
|||||||
case aListExternalKeys:
|
case aListExternalKeys:
|
||||||
for (sl=NULL; argc; argc--, argv++)
|
for (sl=NULL; argc; argc--, argv++)
|
||||||
add_to_strlist (&sl, *argv);
|
add_to_strlist (&sl, *argv);
|
||||||
gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7)));
|
gpgsm_list_keys (&ctrl, sl, stdout,
|
||||||
|
(0 | (1<<7)));
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
19
sm/gpgsm.h
19
sm/gpgsm.h
@ -58,9 +58,12 @@ struct {
|
|||||||
char *outfile; /* name of output file */
|
char *outfile; /* name of output file */
|
||||||
|
|
||||||
int with_key_data;/* include raw key in the column delimted output */
|
int with_key_data;/* include raw key in the column delimted output */
|
||||||
|
|
||||||
int fingerprint; /* list fingerprints in all key listings */
|
int fingerprint; /* list fingerprints in all key listings */
|
||||||
|
|
||||||
|
int with_md5_fingerprint; /* Also print an MD5 fingerprint for
|
||||||
|
standard key listings. */
|
||||||
|
|
||||||
int armor; /* force base64 armoring (see also ctrl.with_base64) */
|
int armor; /* force base64 armoring (see also ctrl.with_base64) */
|
||||||
int no_armor; /* don't try to figure out whether data is base64 armored*/
|
int no_armor; /* don't try to figure out whether data is base64 armored*/
|
||||||
|
|
||||||
@ -117,13 +120,14 @@ struct server_local_s;
|
|||||||
/* Note that the default values for this are set by
|
/* Note that the default values for this are set by
|
||||||
gpgsm_init_default_ctrl() */
|
gpgsm_init_default_ctrl() */
|
||||||
struct server_control_s {
|
struct server_control_s {
|
||||||
int no_server; /* we are not running under server control */
|
int no_server; /* We are not running under server control */
|
||||||
int status_fd; /* only for non-server mode */
|
int status_fd; /* Only for non-server mode */
|
||||||
struct server_local_s *server_local;
|
struct server_local_s *server_local;
|
||||||
int with_colons; /* use column delimited output format */
|
int with_colons; /* Use column delimited output format */
|
||||||
int with_chain; /* include the certifying certs in a listing */
|
int with_chain; /* Include the certifying certs in a listing */
|
||||||
|
int with_validation;/* Validate each key while listing. */
|
||||||
|
|
||||||
int autodetect_encoding; /* try to detect the input encoding */
|
int autodetect_encoding; /* Try to detect the input encoding */
|
||||||
int is_pem; /* Is in PEM format */
|
int is_pem; /* Is in PEM format */
|
||||||
int is_base64; /* is in plain base-64 format */
|
int is_base64; /* is in plain base-64 format */
|
||||||
|
|
||||||
@ -216,7 +220,8 @@ int gpgsm_create_cms_signature (ksba_cert_t cert, gcry_md_hd_t md, int mdalgo,
|
|||||||
int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next);
|
int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next);
|
||||||
int gpgsm_is_root_cert (ksba_cert_t cert);
|
int gpgsm_is_root_cert (ksba_cert_t cert);
|
||||||
int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert,
|
int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert,
|
||||||
ksba_isotime_t r_exptime);
|
ksba_isotime_t r_exptime,
|
||||||
|
int listmode, FILE *listfp);
|
||||||
int gpgsm_basic_cert_check (ksba_cert_t cert);
|
int gpgsm_basic_cert_check (ksba_cert_t cert);
|
||||||
|
|
||||||
/*-- certlist.c --*/
|
/*-- certlist.c --*/
|
||||||
|
20
sm/import.c
20
sm/import.c
@ -57,12 +57,17 @@ static gpg_error_t parse_p12 (ksba_reader_t reader, FILE **retfp);
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_imported_status (CTRL ctrl, ksba_cert_t cert)
|
print_imported_status (CTRL ctrl, ksba_cert_t cert, int new_cert)
|
||||||
{
|
{
|
||||||
char *fpr;
|
char *fpr;
|
||||||
|
|
||||||
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
||||||
gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL);
|
if (new_cert)
|
||||||
|
gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL);
|
||||||
|
|
||||||
|
gpgsm_status2 (ctrl, STATUS_IMPORT_OK,
|
||||||
|
new_cert? "1":"0", fpr, NULL);
|
||||||
|
|
||||||
xfree (fpr);
|
xfree (fpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +151,7 @@ check_and_store (CTRL ctrl, struct stats_s *stats, ksba_cert_t cert, int depth)
|
|||||||
/* Some basic checks, but don't care about missing certificates;
|
/* Some basic checks, but don't care about missing certificates;
|
||||||
this is so that we are able to import entire certificate chains
|
this is so that we are able to import entire certificate chains
|
||||||
w/o requirening a special order (i.e. root-CA first). This used
|
w/o requirening a special order (i.e. root-CA first). This used
|
||||||
to be different but becuase gpgsm_verify even imports
|
to be different but because gpgsm_verify even imports
|
||||||
certificates without any checks, it doesn't matter much and the
|
certificates without any checks, it doesn't matter much and the
|
||||||
code gets much cleaner. A housekeeping function to remove
|
code gets much cleaner. A housekeeping function to remove
|
||||||
certificates w/o an anchor would be nice, though. */
|
certificates w/o an anchor would be nice, though. */
|
||||||
@ -161,11 +166,14 @@ check_and_store (CTRL ctrl, struct stats_s *stats, ksba_cert_t cert, int depth)
|
|||||||
|
|
||||||
if (!existed)
|
if (!existed)
|
||||||
{
|
{
|
||||||
print_imported_status (ctrl, cert);
|
print_imported_status (ctrl, cert, 1);
|
||||||
stats->imported++;
|
stats->imported++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
stats->unchanged++;
|
{
|
||||||
|
print_imported_status (ctrl, cert, 0);
|
||||||
|
stats->unchanged++;
|
||||||
|
}
|
||||||
|
|
||||||
if (opt.verbose > 1 && existed)
|
if (opt.verbose > 1 && existed)
|
||||||
{
|
{
|
||||||
|
112
sm/keylist.c
112
sm/keylist.c
@ -1,5 +1,6 @@
|
|||||||
/* keylist.c
|
/* keylist.c
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
|
||||||
|
* 2004 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -37,6 +38,7 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
struct list_external_parm_s {
|
struct list_external_parm_s {
|
||||||
|
ctrl_t ctrl;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int print_header;
|
int print_header;
|
||||||
int with_colons;
|
int with_colons;
|
||||||
@ -146,28 +148,35 @@ email_kludge (const char *name)
|
|||||||
|
|
||||||
/* List one certificate in colon mode */
|
/* List one certificate in colon mode */
|
||||||
static void
|
static void
|
||||||
list_cert_colon (ksba_cert_t cert, unsigned int validity,
|
list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
|
||||||
FILE *fp, int have_secret)
|
FILE *fp, int have_secret)
|
||||||
{
|
{
|
||||||
int idx, trustletter = 0;
|
int idx;
|
||||||
|
char truststring[2];
|
||||||
char *p;
|
char *p;
|
||||||
ksba_sexp_t sexp;
|
ksba_sexp_t sexp;
|
||||||
char *fpr;
|
char *fpr;
|
||||||
ksba_isotime_t t;
|
ksba_isotime_t t;
|
||||||
|
gpg_error_t valerr;
|
||||||
|
|
||||||
|
if (ctrl->with_validation)
|
||||||
|
valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL);
|
||||||
|
else
|
||||||
|
valerr = 0;
|
||||||
|
|
||||||
fputs (have_secret? "crs:":"crt:", fp);
|
fputs (have_secret? "crs:":"crt:", fp);
|
||||||
trustletter = 0;
|
truststring[0] = 0;
|
||||||
if ((validity & VALIDITY_REVOKED))
|
truststring[1] = 0;
|
||||||
trustletter = 'r';
|
if ((validity & VALIDITY_REVOKED)
|
||||||
#if 0
|
|| gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
|
||||||
else if (is_not_valid (cert))
|
*truststring = 'r';
|
||||||
putc ('i', fp);
|
else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
|
||||||
else if ( has_expired (cert))
|
*truststring = 'e';
|
||||||
putcr ('e', fp);
|
else if (valerr)
|
||||||
#endif
|
*truststring = 'i';
|
||||||
else
|
|
||||||
trustletter = '?';
|
if (*truststring)
|
||||||
putc (trustletter, fp);
|
fputs (truststring, fp);
|
||||||
|
|
||||||
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
||||||
fprintf (fp, ":%u:%d:%s:",
|
fprintf (fp, ":%u:%d:%s:",
|
||||||
@ -247,7 +256,7 @@ list_cert_colon (ksba_cert_t cert, unsigned int validity,
|
|||||||
|
|
||||||
for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
|
for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
|
||||||
{
|
{
|
||||||
fprintf (fp, "uid:%c::::::::", trustletter);
|
fprintf (fp, "uid:%s::::::::", truststring);
|
||||||
print_sanitized_string (fp, p, ':');
|
print_sanitized_string (fp, p, ':');
|
||||||
putc (':', fp);
|
putc (':', fp);
|
||||||
putc (':', fp);
|
putc (':', fp);
|
||||||
@ -261,7 +270,7 @@ list_cert_colon (ksba_cert_t cert, unsigned int validity,
|
|||||||
char *pp = email_kludge (p);
|
char *pp = email_kludge (p);
|
||||||
if (pp)
|
if (pp)
|
||||||
{
|
{
|
||||||
fprintf (fp, "uid:%c::::::::", trustletter);
|
fprintf (fp, "uid:%s::::::::", truststring);
|
||||||
print_sanitized_string (fp, pp, ':');
|
print_sanitized_string (fp, pp, ':');
|
||||||
putc (':', fp);
|
putc (':', fp);
|
||||||
putc (':', fp);
|
putc (':', fp);
|
||||||
@ -276,9 +285,10 @@ list_cert_colon (ksba_cert_t cert, unsigned int validity,
|
|||||||
|
|
||||||
/* List one certificate in standard mode */
|
/* List one certificate in standard mode */
|
||||||
static void
|
static void
|
||||||
list_cert_std (ksba_cert_t cert, FILE *fp, int have_secret)
|
list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
|
||||||
|
int with_validation)
|
||||||
{
|
{
|
||||||
gpg_error_t kerr;
|
gpg_error_t err;
|
||||||
ksba_sexp_t sexp;
|
ksba_sexp_t sexp;
|
||||||
char *dn;
|
char *dn;
|
||||||
ksba_isotime_t t;
|
ksba_isotime_t t;
|
||||||
@ -327,12 +337,12 @@ list_cert_std (ksba_cert_t cert, FILE *fp, int have_secret)
|
|||||||
gpgsm_print_time (fp, t);
|
gpgsm_print_time (fp, t);
|
||||||
putc ('\n', fp);
|
putc ('\n', fp);
|
||||||
|
|
||||||
kerr = ksba_cert_get_key_usage (cert, &kusage);
|
err = ksba_cert_get_key_usage (cert, &kusage);
|
||||||
if (gpg_err_code (kerr) != GPG_ERR_NO_DATA)
|
if (gpg_err_code (err) != GPG_ERR_NO_DATA)
|
||||||
{
|
{
|
||||||
fputs (" key usage:", fp);
|
fputs (" key usage:", fp);
|
||||||
if (kerr)
|
if (err)
|
||||||
fprintf (fp, " [error: %s]", gpg_strerror (kerr));
|
fprintf (fp, " [error: %s]", gpg_strerror (err));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
|
if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
|
||||||
@ -357,12 +367,12 @@ list_cert_std (ksba_cert_t cert, FILE *fp, int have_secret)
|
|||||||
putc ('\n', fp);
|
putc ('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ksba_cert_get_cert_policies (cert, &string);
|
err = ksba_cert_get_cert_policies (cert, &string);
|
||||||
if (gpg_err_code (kerr) != GPG_ERR_NO_DATA)
|
if (gpg_err_code (err) != GPG_ERR_NO_DATA)
|
||||||
{
|
{
|
||||||
fputs (" policies: ", fp);
|
fputs (" policies: ", fp);
|
||||||
if (kerr)
|
if (err)
|
||||||
fprintf (fp, "[error: %s]", gpg_strerror (kerr));
|
fprintf (fp, "[error: %s]", gpg_strerror (err));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (p=string; *p; p++)
|
for (p=string; *p; p++)
|
||||||
@ -376,12 +386,12 @@ list_cert_std (ksba_cert_t cert, FILE *fp, int have_secret)
|
|||||||
putc ('\n', fp);
|
putc ('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ksba_cert_is_ca (cert, &is_ca, &chainlen);
|
err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
|
||||||
if (kerr || is_ca)
|
if (err || is_ca)
|
||||||
{
|
{
|
||||||
fputs (" chain length: ", fp);
|
fputs (" chain length: ", fp);
|
||||||
if (kerr)
|
if (err)
|
||||||
fprintf (fp, "[error: %s]", gpg_strerror (kerr));
|
fprintf (fp, "[error: %s]", gpg_strerror (err));
|
||||||
else if (chainlen == -1)
|
else if (chainlen == -1)
|
||||||
fputs ("unlimited", fp);
|
fputs ("unlimited", fp);
|
||||||
else
|
else
|
||||||
@ -389,25 +399,41 @@ list_cert_std (ksba_cert_t cert, FILE *fp, int have_secret)
|
|||||||
putc ('\n', fp);
|
putc ('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.with_md5_fingerprint)
|
||||||
|
{
|
||||||
|
dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
|
||||||
|
fprintf (fp, " md5 fpr: %s\n", dn?dn:"error");
|
||||||
|
xfree (dn);
|
||||||
|
}
|
||||||
|
|
||||||
dn = gpgsm_get_fingerprint_string (cert, 0);
|
dn = gpgsm_get_fingerprint_string (cert, 0);
|
||||||
fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
|
fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
|
||||||
xfree (dn);
|
xfree (dn);
|
||||||
|
|
||||||
|
if (with_validation)
|
||||||
|
{
|
||||||
|
err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp);
|
||||||
|
if (!err)
|
||||||
|
fprintf (fp, " [certificate is good]\n");
|
||||||
|
else
|
||||||
|
fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as standard mode mode list all certifying certts too */
|
|
||||||
|
/* Same as standard mode mode list all certifying certs too. */
|
||||||
static void
|
static void
|
||||||
list_cert_chain (ksba_cert_t cert, FILE *fp)
|
list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int with_validation)
|
||||||
{
|
{
|
||||||
ksba_cert_t next = NULL;
|
ksba_cert_t next = NULL;
|
||||||
|
|
||||||
list_cert_std (cert, fp, 0);
|
list_cert_std (ctrl, cert, fp, 0, with_validation);
|
||||||
ksba_cert_ref (cert);
|
ksba_cert_ref (cert);
|
||||||
while (!gpgsm_walk_cert_chain (cert, &next))
|
while (!gpgsm_walk_cert_chain (cert, &next))
|
||||||
{
|
{
|
||||||
ksba_cert_release (cert);
|
ksba_cert_release (cert);
|
||||||
fputs ("Certified by\n", fp);
|
fputs ("Certified by\n", fp);
|
||||||
list_cert_std (next, fp, 0);
|
list_cert_std (ctrl, next, fp, 0, with_validation);
|
||||||
cert = next;
|
cert = next;
|
||||||
}
|
}
|
||||||
ksba_cert_release (cert);
|
ksba_cert_release (cert);
|
||||||
@ -471,7 +497,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* it would be nice to see which of the given users did actually
|
/* It would be nice to see which of the given users did actually
|
||||||
match one in the keyring. To implement this we need to have a
|
match one in the keyring. To implement this we need to have a
|
||||||
found flag for each entry in desc and to set this we must check
|
found flag for each entry in desc and to set this we must check
|
||||||
all those entries after a match to mark all matched one -
|
all those entries after a match to mark all matched one -
|
||||||
@ -532,12 +558,13 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
|
|||||||
|| ((mode & 2) && have_secret) )
|
|| ((mode & 2) && have_secret) )
|
||||||
{
|
{
|
||||||
if (ctrl->with_colons)
|
if (ctrl->with_colons)
|
||||||
list_cert_colon (cert, validity, fp, have_secret);
|
list_cert_colon (ctrl, cert, validity, fp, have_secret);
|
||||||
else if (ctrl->with_chain)
|
else if (ctrl->with_chain)
|
||||||
list_cert_chain (cert, fp);
|
list_cert_chain (ctrl, cert, fp, ctrl->with_validation);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
list_cert_std (cert, fp, have_secret);
|
list_cert_std (ctrl, cert, fp, have_secret,
|
||||||
|
ctrl->with_validation);
|
||||||
putc ('\n', fp);
|
putc ('\n', fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -576,12 +603,12 @@ list_external_cb (void *cb_value, ksba_cert_t cert)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parm->with_colons)
|
if (parm->with_colons)
|
||||||
list_cert_colon (cert, 0, parm->fp, 0);
|
list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
|
||||||
else if (parm->with_chain)
|
else if (parm->with_chain)
|
||||||
list_cert_chain (cert, parm->fp);
|
list_cert_chain (parm->ctrl, cert, parm->fp, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
list_cert_std (cert, parm->fp, 0);
|
list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
|
||||||
putc ('\n', parm->fp);
|
putc ('\n', parm->fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -597,6 +624,7 @@ list_external_keys (CTRL ctrl, STRLIST names, FILE *fp)
|
|||||||
struct list_external_parm_s parm;
|
struct list_external_parm_s parm;
|
||||||
|
|
||||||
parm.fp = fp;
|
parm.fp = fp;
|
||||||
|
parm.ctrl = ctrl,
|
||||||
parm.print_header = ctrl->no_server;
|
parm.print_header = ctrl->no_server;
|
||||||
parm.with_colons = ctrl->with_colons;
|
parm.with_colons = ctrl->with_colons;
|
||||||
parm.with_chain = ctrl->with_chain;
|
parm.with_chain = ctrl->with_chain;
|
||||||
|
@ -170,6 +170,10 @@ option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
|
|||||||
else
|
else
|
||||||
return ASSUAN_Parameter_Error;
|
return ASSUAN_Parameter_Error;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (key, "with-validation"))
|
||||||
|
{
|
||||||
|
ctrl->with_validation = !!*value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return ASSUAN_Invalid_Option;
|
return ASSUAN_Invalid_Option;
|
||||||
|
|
||||||
@ -898,6 +902,7 @@ get_status_string ( int no )
|
|||||||
case STATUS_BADMDC : s = "BADMDC"; break;
|
case STATUS_BADMDC : s = "BADMDC"; break;
|
||||||
case STATUS_ERRMDC : s = "ERRMDC"; break;
|
case STATUS_ERRMDC : s = "ERRMDC"; break;
|
||||||
case STATUS_IMPORTED : s = "IMPORTED"; break;
|
case STATUS_IMPORTED : s = "IMPORTED"; break;
|
||||||
|
case STATUS_IMPORT_OK : s = "IMPORT_OK"; break;
|
||||||
case STATUS_IMPORT_RES : s = "IMPORT_RES"; break;
|
case STATUS_IMPORT_RES : s = "IMPORT_RES"; break;
|
||||||
case STATUS_FILE_START : s = "FILE_START"; break;
|
case STATUS_FILE_START : s = "FILE_START"; break;
|
||||||
case STATUS_FILE_DONE : s = "FILE_DONE"; break;
|
case STATUS_FILE_DONE : s = "FILE_DONE"; break;
|
||||||
|
@ -378,7 +378,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
|
|||||||
valid. */
|
valid. */
|
||||||
rc = gpgsm_cert_use_sign_p (cert);
|
rc = gpgsm_cert_use_sign_p (cert);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = gpgsm_validate_chain (ctrl, cert, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
|
|||||||
|
|
||||||
if (DBG_X509)
|
if (DBG_X509)
|
||||||
log_debug ("signature okay - checking certs\n");
|
log_debug ("signature okay - checking certs\n");
|
||||||
rc = gpgsm_validate_chain (ctrl, cert, keyexptime);
|
rc = gpgsm_validate_chain (ctrl, cert, keyexptime, 0, NULL);
|
||||||
if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
|
if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
|
||||||
{
|
{
|
||||||
gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL);
|
gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user