mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
* certlist.c (gpgsm_add_to_certlist): Fixed locating of a
certificate with the required key usage. * gpgsm.c (main): Fixed a segv when using --outfile without an argument. * keylist.c (print_capabilities): Also check for non-repudiation and data encipherment. * certlist.c (cert_usage_p): Test for signing and encryption was swapped. Add a case for certification usage, handle non-repudiation and data encipherment. (gpgsm_cert_use_cert_p): New. (gpgsm_add_to_certlist): Added a CTRL argument and changed all callers to pass it. * certpath.c (gpgsm_validate_path): Use it here to print a status message. Added a CTRL argument and changed all callers to pass it. * decrypt.c (gpgsm_decrypt): Print a status message for wrong key usage. * verify.c (gpgsm_verify): Ditto. * keydb.c (classify_user_id): Allow a colon delimited fingerprint.
This commit is contained in:
parent
52146943d1
commit
42cf865350
23
sm/ChangeLog
23
sm/ChangeLog
@ -1,3 +1,26 @@
|
||||
2002-06-20 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* certlist.c (gpgsm_add_to_certlist): Fixed locating of a
|
||||
certificate with the required key usage.
|
||||
|
||||
* gpgsm.c (main): Fixed a segv when using --outfile without an
|
||||
argument.
|
||||
|
||||
* keylist.c (print_capabilities): Also check for non-repudiation
|
||||
and data encipherment.
|
||||
* certlist.c (cert_usage_p): Test for signing and encryption was
|
||||
swapped. Add a case for certification usage, handle
|
||||
non-repudiation and data encipherment.
|
||||
(gpgsm_cert_use_cert_p): New.
|
||||
(gpgsm_add_to_certlist): Added a CTRL argument and changed all
|
||||
callers to pass it.
|
||||
* certpath.c (gpgsm_validate_path): Use it here to print a status
|
||||
message. Added a CTRL argument and changed all callers to pass it.
|
||||
* decrypt.c (gpgsm_decrypt): Print a status message for wrong key
|
||||
usage.
|
||||
* verify.c (gpgsm_verify): Ditto.
|
||||
* keydb.c (classify_user_id): Allow a colon delimited fingerprint.
|
||||
|
||||
2002-06-19 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* call-agent.c (learn_cb): Use log_info instead of log_error on
|
||||
|
@ -420,7 +420,6 @@ static AssuanError
|
||||
lookup_status_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct lookup_parm_s *parm = opaque;
|
||||
int i;
|
||||
|
||||
if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
|
||||
{
|
||||
|
@ -308,7 +308,7 @@ gpgsm_is_root_cert (KsbaCert cert)
|
||||
/* Validate a path and optionally return the nearest expiration time
|
||||
in R_EXPTIME */
|
||||
int
|
||||
gpgsm_validate_path (KsbaCert cert, time_t *r_exptime)
|
||||
gpgsm_validate_path (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
|
||||
{
|
||||
int rc = 0, depth = 0, maxdepth;
|
||||
char *issuer = NULL;
|
||||
@ -551,6 +551,14 @@ gpgsm_validate_path (KsbaCert cert, time_t *r_exptime)
|
||||
}
|
||||
}
|
||||
|
||||
rc = gpgsm_cert_use_cert_p (issuer_cert);
|
||||
if (rc)
|
||||
{
|
||||
gpgsm_status2 (ctrl, STATUS_ERROR, "certpath.issuer.keyusage",
|
||||
gnupg_error_token (rc), NULL);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("certificate is good\n");
|
||||
|
||||
|
101
sm/certlist.c
101
sm/certlist.c
@ -60,8 +60,18 @@ cert_usage_p (KsbaCert cert, int mode)
|
||||
return map_ksba_err (err);
|
||||
}
|
||||
|
||||
if ((use & ((mode&1)? KSBA_KEYUSAGE_DIGITAL_SIGNATURE
|
||||
: KSBA_KEYUSAGE_KEY_ENCIPHERMENT)))
|
||||
if (mode == 4)
|
||||
{
|
||||
if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN)))
|
||||
return 0;
|
||||
log_info ( _("certificate should have not been used certification\n"));
|
||||
return GNUPG_Wrong_Key_Usage;
|
||||
}
|
||||
|
||||
if ((use & ((mode&1)?
|
||||
(KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT):
|
||||
(KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
|
||||
)
|
||||
return 0;
|
||||
log_info (mode==3? _("certificate should have not been used for encryption\n"):
|
||||
mode==2? _("certificate should have not been used for signing\n"):
|
||||
@ -98,10 +108,35 @@ gpgsm_cert_use_decrypt_p (KsbaCert cert)
|
||||
return cert_usage_p (cert, 3);
|
||||
}
|
||||
|
||||
int
|
||||
gpgsm_cert_use_cert_p (KsbaCert cert)
|
||||
{
|
||||
return cert_usage_p (cert, 4);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
same_subject_issuer (const char *subject, const char *issuer, KsbaCert cert)
|
||||
{
|
||||
char *subject2 = ksba_cert_get_subject (cert, 0);
|
||||
char *issuer2 = ksba_cert_get_subject (cert, 0);
|
||||
int tmp;
|
||||
|
||||
tmp = (subject && subject2
|
||||
&& !strcmp (subject, subject2)
|
||||
&& issuer && issuer2
|
||||
&& !strcmp (issuer, issuer2));
|
||||
xfree (subject2);
|
||||
xfree (issuer2);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* add a certificate to a list of certificate and make sure that it is
|
||||
a valid certificate */
|
||||
int
|
||||
gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr)
|
||||
gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr)
|
||||
{
|
||||
int rc;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
@ -117,6 +152,9 @@ gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr)
|
||||
else
|
||||
{
|
||||
int wrong_usage = 0;
|
||||
char *subject = NULL;
|
||||
char *issuer = NULL;
|
||||
|
||||
get_next:
|
||||
rc = keydb_search (kh, &desc, 1);
|
||||
if (!rc)
|
||||
@ -127,32 +165,61 @@ gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr)
|
||||
if (rc == GNUPG_Wrong_Key_Usage)
|
||||
{
|
||||
/* There might be another certificate with the
|
||||
correct usage, so we better try again */
|
||||
wrong_usage = rc;
|
||||
ksba_cert_release (cert);
|
||||
cert = NULL;
|
||||
goto get_next;
|
||||
correct usage, so we try again */
|
||||
if (!wrong_usage)
|
||||
{ /* save the first match */
|
||||
wrong_usage = rc;
|
||||
subject = ksba_cert_get_subject (cert, 0);
|
||||
issuer = ksba_cert_get_subject (cert, 0);
|
||||
ksba_cert_release (cert);
|
||||
cert = NULL;
|
||||
goto get_next;
|
||||
}
|
||||
else if (same_subject_issuer (subject, issuer, cert))
|
||||
{
|
||||
wrong_usage = rc;
|
||||
ksba_cert_release (cert);
|
||||
cert = NULL;
|
||||
goto get_next;
|
||||
}
|
||||
else
|
||||
wrong_usage = rc;
|
||||
|
||||
}
|
||||
}
|
||||
/* we want the error code from the first match in this case */
|
||||
if (wrong_usage)
|
||||
if (rc && wrong_usage)
|
||||
rc = wrong_usage;
|
||||
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
/* Fixme: If we ever have two certifciates differing
|
||||
only in the key usage, we should only bail out here
|
||||
if the certificate differes just in the key usage.
|
||||
However we need to find some criteria to match the
|
||||
identities */
|
||||
next_ambigious:
|
||||
rc = keydb_search (kh, &desc, 1);
|
||||
if (rc == -1)
|
||||
rc = 0;
|
||||
else if (!rc)
|
||||
rc = GNUPG_Ambiguous_Name;
|
||||
{
|
||||
KsbaCert cert2 = NULL;
|
||||
|
||||
/* We have to ignore ambigious names as long as
|
||||
there only fault is a bad key usage */
|
||||
if (!keydb_get_cert (kh, &cert2))
|
||||
{
|
||||
int tmp = (same_subject_issuer (subject, issuer, cert2)
|
||||
&& (gpgsm_cert_use_encrypt_p (cert2)
|
||||
== GNUPG_Wrong_Key_Usage));
|
||||
ksba_cert_release (cert2);
|
||||
if (tmp)
|
||||
goto next_ambigious;
|
||||
}
|
||||
rc = GNUPG_Ambiguous_Name;
|
||||
}
|
||||
}
|
||||
xfree (subject);
|
||||
xfree (issuer);
|
||||
|
||||
if (!rc)
|
||||
rc = gpgsm_validate_path (cert, NULL);
|
||||
rc = gpgsm_validate_path (ctrl, cert, NULL);
|
||||
if (!rc)
|
||||
{
|
||||
CERTLIST cl = xtrycalloc (1, sizeof *cl);
|
||||
|
@ -308,7 +308,7 @@ gpgsm_is_root_cert (KsbaCert cert)
|
||||
/* Validate a path and optionally return the nearest expiration time
|
||||
in R_EXPTIME */
|
||||
int
|
||||
gpgsm_validate_path (KsbaCert cert, time_t *r_exptime)
|
||||
gpgsm_validate_path (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
|
||||
{
|
||||
int rc = 0, depth = 0, maxdepth;
|
||||
char *issuer = NULL;
|
||||
@ -551,6 +551,14 @@ gpgsm_validate_path (KsbaCert cert, time_t *r_exptime)
|
||||
}
|
||||
}
|
||||
|
||||
rc = gpgsm_cert_use_cert_p (issuer_cert);
|
||||
if (rc)
|
||||
{
|
||||
gpgsm_status2 (ctrl, STATUS_ERROR, "certpath.issuer.keyusage",
|
||||
gnupg_error_token (rc), NULL);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("certificate is good\n");
|
||||
|
||||
|
@ -381,7 +381,13 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
|
||||
/* Just in case there is a problem with the own
|
||||
certificate we print this message - should never
|
||||
happen of course */
|
||||
gpgsm_cert_use_decrypt_p (cert);
|
||||
rc = gpgsm_cert_use_decrypt_p (cert);
|
||||
if (rc)
|
||||
{
|
||||
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
|
||||
gnupg_error_token (rc), NULL);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
|
||||
|
||||
|
@ -1054,7 +1054,7 @@ main ( int argc, char **argv)
|
||||
|
||||
for (sl = remusr; sl; sl = sl->next)
|
||||
{
|
||||
int rc = gpgsm_add_to_certlist (sl->d, &recplist);
|
||||
int rc = gpgsm_add_to_certlist (&ctrl, sl->d, &recplist);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("can't encrypt to `%s': %s\n"),
|
||||
@ -1164,7 +1164,7 @@ main ( int argc, char **argv)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
|
||||
if (argc == 2 && *opt.outfile)
|
||||
if (argc == 2 && opt.outfile)
|
||||
log_info ("option --output ignored for a detached signature\n");
|
||||
else if (opt.outfile)
|
||||
fp = open_fwrite (opt.outfile);
|
||||
|
@ -186,7 +186,7 @@ int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo,
|
||||
/*-- certpath.c --*/
|
||||
int gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next);
|
||||
int gpgsm_is_root_cert (KsbaCert cert);
|
||||
int gpgsm_validate_path (KsbaCert cert, time_t *r_exptime);
|
||||
int gpgsm_validate_path (CTRL ctrl, KsbaCert cert, time_t *r_exptime);
|
||||
int gpgsm_basic_cert_check (KsbaCert cert);
|
||||
|
||||
/*-- certlist.c --*/
|
||||
@ -194,7 +194,8 @@ int gpgsm_cert_use_sign_p (KsbaCert cert);
|
||||
int gpgsm_cert_use_encrypt_p (KsbaCert cert);
|
||||
int gpgsm_cert_use_verify_p (KsbaCert cert);
|
||||
int gpgsm_cert_use_decrypt_p (KsbaCert cert);
|
||||
int gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr);
|
||||
int gpgsm_cert_use_cert_p (KsbaCert cert);
|
||||
int gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr);
|
||||
void gpgsm_release_certlist (CERTLIST list);
|
||||
int gpgsm_find_cert (const char *name, KsbaCert *r_cert);
|
||||
|
||||
|
29
sm/keydb.c
29
sm/keydb.c
@ -1137,10 +1137,31 @@ classify_user_id (const char *name,
|
||||
mode = KEYDB_SEARCH_MODE_FPR20;
|
||||
}
|
||||
else if (!hexprefix)
|
||||
{ /* default is substring search */
|
||||
*force_exact = 0;
|
||||
desc->u.name = s;
|
||||
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
||||
{
|
||||
/* The fingerprint in an X.509 listing is often delimited by
|
||||
colons, so we try to single this case out. */
|
||||
mode = 0;
|
||||
hexlength = strspn (s, ":0123456789abcdefABCDEF");
|
||||
if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < 20; i++, s += 3)
|
||||
{
|
||||
int c = hextobyte(s);
|
||||
if (c == -1 || (i < 19 && s[2] != ':'))
|
||||
break;
|
||||
desc->u.fpr[i] = c;
|
||||
}
|
||||
if (i == 20)
|
||||
mode = KEYDB_SEARCH_MODE_FPR20;
|
||||
}
|
||||
if (!mode) /* default is substring search */
|
||||
{
|
||||
*force_exact = 0;
|
||||
desc->u.name = s;
|
||||
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* hex number with a prefix but a wrong length */
|
||||
|
@ -84,15 +84,15 @@ print_capabilities (KsbaCert cert, FILE *fp)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((use & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
|
||||
if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
|
||||
putc ('e', fp);
|
||||
if ((use & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
|
||||
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
|
||||
putc ('s', fp);
|
||||
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
|
||||
putc ('c', fp);
|
||||
if ((use & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
|
||||
if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
|
||||
putc ('E', fp);
|
||||
if ((use & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
|
||||
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
|
||||
putc ('S', fp);
|
||||
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
|
||||
putc ('C', fp);
|
||||
|
@ -239,7 +239,7 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
|
||||
CTRL ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
|
||||
rc = gpgsm_add_to_certlist (line, &ctrl->server_local->recplist);
|
||||
rc = gpgsm_add_to_certlist (ctrl, line, &ctrl->server_local->recplist);
|
||||
if (rc)
|
||||
gpgsm_status2 (ctrl, STATUS_INV_RECP,
|
||||
rc == -1? "1":
|
||||
|
11
sm/verify.c
11
sm/verify.c
@ -389,10 +389,17 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
|
||||
gpgsm_status (ctrl, STATUS_BADSIG, NULL);
|
||||
goto next_signer;
|
||||
}
|
||||
gpgsm_cert_use_verify_p (cert); /* this displays an info message */
|
||||
rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
|
||||
if (rc)
|
||||
{
|
||||
gpgsm_status2 (ctrl, STATUS_ERROR, "verify.keyusage",
|
||||
gnupg_error_token (rc), NULL);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (DBG_X509)
|
||||
log_debug ("signature okay - checking certs\n");
|
||||
rc = gpgsm_validate_path (cert, &keyexptime);
|
||||
rc = gpgsm_validate_path (ctrl, cert, &keyexptime);
|
||||
if (rc == GNUPG_Certificate_Expired)
|
||||
{
|
||||
gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user