mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* verify.c (gpgsm_verify): Print STATUS_NEWSIG for each signature.
* certchain.c (gpgsm_validate_chain) <gpgsm_cert_use_cer_p>: Do not just warn if a cert is not suitable; bail out immediately. * call-dirmngr.c (isvalid_status_cb): New. (unhexify_fpr): New. Taken from ../g10/call-agent.c (gpgsm_dirmngr_isvalid): Add new arg CTRL, changed caller to pass it thru. Detect need to check the respondert cert and do that. * certchain.c (gpgsm_validate_chain): Add new arg FLAGS. Changed all callers.
This commit is contained in:
parent
d3411b3277
commit
da89d93c77
16
sm/ChangeLog
16
sm/ChangeLog
@ -1,3 +1,19 @@
|
|||||||
|
2004-04-05 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* verify.c (gpgsm_verify): Print STATUS_NEWSIG for each signature.
|
||||||
|
|
||||||
|
* certchain.c (gpgsm_validate_chain) <gpgsm_cert_use_cer_p>: Do
|
||||||
|
not just warn if a cert is not suitable; bail out immediately.
|
||||||
|
|
||||||
|
2004-04-01 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* call-dirmngr.c (isvalid_status_cb): New.
|
||||||
|
(unhexify_fpr): New. Taken from ../g10/call-agent.c
|
||||||
|
(gpgsm_dirmngr_isvalid): Add new arg CTRL, changed caller to pass
|
||||||
|
it thru. Detect need to check the respondert cert and do that.
|
||||||
|
* certchain.c (gpgsm_validate_chain): Add new arg FLAGS. Changed
|
||||||
|
all callers.
|
||||||
|
|
||||||
2004-03-24 Werner Koch <wk@gnupg.org>
|
2004-03-24 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* sign.c (gpgsm_sign): Include a short list of capabilities.
|
* sign.c (gpgsm_sign): Include a short list of capabilities.
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include <assuan.h>
|
#include <assuan.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
#include "keydb.h"
|
||||||
|
|
||||||
|
|
||||||
struct membuf {
|
struct membuf {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -52,6 +54,12 @@ struct inq_certificate_parm_s {
|
|||||||
ksba_cert_t issuer_cert;
|
ksba_cert_t issuer_cert;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct isvalid_status_parm_s {
|
||||||
|
int seen;
|
||||||
|
unsigned char fpr[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct lookup_parm_s {
|
struct lookup_parm_s {
|
||||||
CTRL ctrl;
|
CTRL ctrl;
|
||||||
ASSUAN_CONTEXT ctx;
|
ASSUAN_CONTEXT ctx;
|
||||||
@ -300,6 +308,42 @@ inq_certificate (void *opaque, const char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take a 20 byte hexencoded string and put it into the the provided
|
||||||
|
20 byte buffer FPR in binary format. */
|
||||||
|
static int
|
||||||
|
unhexify_fpr (const char *hexstr, unsigned char *fpr)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (s=hexstr, n=0; hexdigitp (s); s++, n++)
|
||||||
|
;
|
||||||
|
if (*s || (n != 40))
|
||||||
|
return 0; /* no fingerprint (invalid or wrong length). */
|
||||||
|
n /= 2;
|
||||||
|
for (s=hexstr, n=0; *s; s += 2, n++)
|
||||||
|
fpr[n] = xtoi_2 (s);
|
||||||
|
return 1; /* okay */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static assuan_error_t
|
||||||
|
isvalid_status_cb (void *opaque, const char *line)
|
||||||
|
{
|
||||||
|
struct isvalid_status_parm_s *parm = opaque;
|
||||||
|
|
||||||
|
if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
|
||||||
|
&& (line[24]==' ' || !line[24]))
|
||||||
|
{
|
||||||
|
parm->seen++;
|
||||||
|
if (!line[24] || !unhexify_fpr (line+25, parm->fpr))
|
||||||
|
parm->seen++; /* Bumb it to indicate an error. */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Call the directory manager to check whether the certificate is valid
|
/* Call the directory manager to check whether the certificate is valid
|
||||||
Returns 0 for valid or usually one of the errors:
|
Returns 0 for valid or usually one of the errors:
|
||||||
@ -312,12 +356,14 @@ inq_certificate (void *opaque, const char *line)
|
|||||||
request first.
|
request first.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
gpgsm_dirmngr_isvalid (ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
|
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
||||||
|
ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char *certid;
|
char *certid;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
struct inq_certificate_parm_s parm;
|
struct inq_certificate_parm_s parm;
|
||||||
|
struct isvalid_status_parm_s stparm;
|
||||||
|
|
||||||
rc = start_dirmngr ();
|
rc = start_dirmngr ();
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -349,6 +395,9 @@ gpgsm_dirmngr_isvalid (ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
|
|||||||
parm.cert = cert;
|
parm.cert = cert;
|
||||||
parm.issuer_cert = issuer_cert;
|
parm.issuer_cert = issuer_cert;
|
||||||
|
|
||||||
|
stparm.seen = 0;
|
||||||
|
memset (stparm.fpr, 0, 20);
|
||||||
|
|
||||||
/* FIXME: If --disable-crl-checks has been set, we should pass an
|
/* FIXME: If --disable-crl-checks has been set, we should pass an
|
||||||
option to dirmngr, so that no fallback CRL check is done after an
|
option to dirmngr, so that no fallback CRL check is done after an
|
||||||
ocsp check. */
|
ocsp check. */
|
||||||
@ -358,10 +407,66 @@ gpgsm_dirmngr_isvalid (ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
|
|||||||
xfree (certid);
|
xfree (certid);
|
||||||
|
|
||||||
rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
|
rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
|
||||||
inq_certificate, &parm, NULL, NULL);
|
inq_certificate, &parm,
|
||||||
|
isvalid_status_cb, &stparm);
|
||||||
if (opt.verbose > 1)
|
if (opt.verbose > 1)
|
||||||
log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay");
|
log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay");
|
||||||
return map_assuan_err (rc);
|
rc = map_assuan_err (rc);
|
||||||
|
|
||||||
|
if (!rc && stparm.seen)
|
||||||
|
{
|
||||||
|
/* Need to also check the certificate validity. */
|
||||||
|
if (stparm.seen != 1)
|
||||||
|
{
|
||||||
|
log_error ("communication problem with dirmngr detected\n");
|
||||||
|
rc = gpg_error (GPG_ERR_INV_CRL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KEYDB_HANDLE kh;
|
||||||
|
ksba_cert_t rspcert = NULL;
|
||||||
|
|
||||||
|
/* Fixme: First try to get the certificate from the
|
||||||
|
dirmngr's cache - it should be there. */
|
||||||
|
kh = keydb_new (0);
|
||||||
|
if (!kh)
|
||||||
|
rc = gpg_error (GPG_ERR_ENOMEM);
|
||||||
|
if (!rc)
|
||||||
|
rc = keydb_search_fpr (kh, stparm.fpr);
|
||||||
|
if (!rc)
|
||||||
|
rc = keydb_get_cert (kh, &rspcert);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("unable to find the certificate used "
|
||||||
|
"by the dirmngr: %s\n", gpg_strerror (rc));
|
||||||
|
rc = gpg_error (GPG_ERR_INV_CRL);
|
||||||
|
}
|
||||||
|
keydb_release (kh);
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
/* fixme: We should refine the check to check for
|
||||||
|
certificates allowed for CRL/OCPS. */
|
||||||
|
rc = gpgsm_cert_use_verify_p (rspcert);
|
||||||
|
if (rc)
|
||||||
|
rc = gpg_error (GPG_ERR_INV_CRL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Note, the flag = 1: This avoids checking this
|
||||||
|
certificate over and over again. */
|
||||||
|
rc = gpgsm_validate_chain (ctrl, rspcert, NULL, 0, NULL, 1);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("invalid certificate used for CRL/OCSP: %s\n",
|
||||||
|
gpg_strerror (rc));
|
||||||
|
rc = gpg_error (GPG_ERR_INV_CRL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ksba_cert_release (rspcert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -480,7 +480,8 @@ is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp,
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
|
|
||||||
err = gpgsm_dirmngr_isvalid (subject_cert, issuer_cert, ctrl->use_ocsp);
|
err = gpgsm_dirmngr_isvalid (ctrl,
|
||||||
|
subject_cert, issuer_cert, ctrl->use_ocsp);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
/* Fixme: We should change the wording because we may
|
/* Fixme: We should change the wording because we may
|
||||||
@ -522,10 +523,13 @@ is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp,
|
|||||||
/* Validate a chain and optionally return the nearest expiration time
|
/* Validate a chain and optionally return the nearest expiration time
|
||||||
in R_EXPTIME. With LISTMODE set to 1 a special listmode is
|
in R_EXPTIME. With LISTMODE set to 1 a special listmode is
|
||||||
activated where only information about the certificate is printed
|
activated where only information about the certificate is printed
|
||||||
to FP and no outputis send to the usual log stream. */
|
to FP and no output is send to the usual log stream.
|
||||||
|
|
||||||
|
Defined flag bits: 0 - do not do any dirmngr isvalid checks.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
gpgsm_validate_chain (ctrl_t 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 listmode, FILE *fp, unsigned int flags)
|
||||||
{
|
{
|
||||||
int rc = 0, depth = 0, maxdepth;
|
int rc = 0, depth = 0, maxdepth;
|
||||||
char *issuer = NULL;
|
char *issuer = NULL;
|
||||||
@ -698,10 +702,13 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for revocations etc. */
|
/* Check for revocations etc. */
|
||||||
rc = is_cert_still_valid (ctrl, lm, fp,
|
if ((flags & 1))
|
||||||
subject_cert, subject_cert,
|
rc = 0;
|
||||||
&any_revoked, &any_no_crl,
|
else
|
||||||
&any_crl_too_old);
|
rc = is_cert_still_valid (ctrl, lm, fp,
|
||||||
|
subject_cert, subject_cert,
|
||||||
|
&any_revoked, &any_no_crl,
|
||||||
|
&any_crl_too_old);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -818,14 +825,17 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
|
|||||||
sprintf (numbuf, "%d", rc);
|
sprintf (numbuf, "%d", rc);
|
||||||
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
|
gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
|
||||||
numbuf, NULL);
|
numbuf, NULL);
|
||||||
rc = 0;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for revocations etc. */
|
/* Check for revocations etc. */
|
||||||
rc = is_cert_still_valid (ctrl, lm, fp,
|
if ((flags & 1))
|
||||||
subject_cert, issuer_cert,
|
rc = 0;
|
||||||
&any_revoked, &any_no_crl, &any_crl_too_old);
|
else
|
||||||
|
rc = is_cert_still_valid (ctrl, lm, fp,
|
||||||
|
subject_cert, issuer_cert,
|
||||||
|
&any_revoked, &any_no_crl, &any_crl_too_old);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
@ -130,7 +130,8 @@ cert_usage_p (ksba_cert_t cert, int mode)
|
|||||||
{
|
{
|
||||||
if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
|
if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
|
||||||
return 0;
|
return 0;
|
||||||
log_info ( _("certificate should have not been used certification\n"));
|
log_info (_("certificate should have not "
|
||||||
|
"been used for certification\n"));
|
||||||
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
|
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +348,7 @@ gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
CERTLIST cl = xtrycalloc (1, sizeof *cl);
|
CERTLIST cl = xtrycalloc (1, sizeof *cl);
|
||||||
|
@ -222,7 +222,8 @@ 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 listmode, FILE *listfp,
|
||||||
|
unsigned int flags);
|
||||||
int gpgsm_basic_cert_check (ksba_cert_t cert);
|
int gpgsm_basic_cert_check (ksba_cert_t cert);
|
||||||
|
|
||||||
/*-- certlist.c --*/
|
/*-- certlist.c --*/
|
||||||
@ -288,7 +289,8 @@ int gpgsm_agent_learn (void);
|
|||||||
int gpgsm_agent_passwd (const char *hexkeygrip, const char *desc);
|
int gpgsm_agent_passwd (const char *hexkeygrip, const char *desc);
|
||||||
|
|
||||||
/*-- call-dirmngr.c --*/
|
/*-- call-dirmngr.c --*/
|
||||||
int gpgsm_dirmngr_isvalid (ksba_cert_t cert, ksba_cert_t issuer_cert,
|
int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
||||||
|
ksba_cert_t cert, ksba_cert_t issuer_cert,
|
||||||
int use_ocsp);
|
int use_ocsp);
|
||||||
int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names,
|
int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names,
|
||||||
void (*cb)(void*, ksba_cert_t), void *cb_value);
|
void (*cb)(void*, ksba_cert_t), void *cb_value);
|
||||||
|
@ -182,7 +182,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
|
|||||||
gpg_error_t valerr;
|
gpg_error_t valerr;
|
||||||
|
|
||||||
if (ctrl->with_validation)
|
if (ctrl->with_validation)
|
||||||
valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL);
|
valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
|
||||||
else
|
else
|
||||||
valerr = 0;
|
valerr = 0;
|
||||||
|
|
||||||
@ -483,7 +483,7 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
|
|||||||
|
|
||||||
if (with_validation)
|
if (with_validation)
|
||||||
{
|
{
|
||||||
err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp);
|
err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
|
||||||
if (!err)
|
if (!err)
|
||||||
fprintf (fp, " [certificate is good]\n");
|
fprintf (fp, " [certificate is good]\n");
|
||||||
else
|
else
|
||||||
|
@ -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, 0, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
@ -263,6 +263,9 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
|
|||||||
err = 0;
|
err = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpgsm_status (ctrl, STATUS_NEWSIG, NULL);
|
||||||
|
|
||||||
if (DBG_X509)
|
if (DBG_X509)
|
||||||
{
|
{
|
||||||
log_debug ("signer %d - issuer: `%s'\n",
|
log_debug ("signer %d - issuer: `%s'\n",
|
||||||
@ -458,7 +461,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, 0, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, keyexptime, 0, NULL, 0);
|
||||||
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