1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

* configure.ac: Require libksba 0.9.11.

sm/
* call-dirmngr.c (inq_certificate): Add new inquire SENDCERT_SKI.
* certlist.c (gpgsm_find_cert): Add new arg KEYID and implement
this filter.  Changed all callers.

* certchain.c (find_up_search_by_keyid): New helper.
(find_up): Also try using the AKI.keyIdentifier.
(find_up_external): Ditto.
This commit is contained in:
Werner Koch 2005-04-18 10:44:46 +00:00
parent 00853b8a1a
commit eff62d82bf
17 changed files with 302 additions and 41 deletions

View file

@ -1,3 +1,18 @@
2005-04-17 Werner Koch <wk@g10code.com>
* call-dirmngr.c (inq_certificate): Add new inquire SENDCERT_SKI.
* certlist.c (gpgsm_find_cert): Add new arg KEYID and implement
this filter. Changed all callers.
* certchain.c (find_up_search_by_keyid): New helper.
(find_up): Also try using the AKI.keyIdentifier.
(find_up_external): Ditto.
2005-04-15 Werner Koch <wk@g10code.com>
* keylist.c (list_cert_raw): Print the subjectKeyIdentifier as
well as the keyIdentifier part of the authorityKeyIdentifier.
2005-03-31 Werner Koch <wk@g10code.com>
* call-dirmngr.c (start_dirmngr): Use PATHSEP_C instead of ':'.

View file

@ -1,5 +1,5 @@
/* call-dirmngr.c - communication with the dromngr
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -266,11 +266,25 @@ inq_certificate (void *opaque, const char *line)
const unsigned char *der;
size_t derlen;
int issuer_mode = 0;
ksba_sexp_t ski = NULL;
if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
{
line += 8;
}
else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
{
size_t n;
/* Send a certificate where a sourceKeyidentifier is included. */
line += 12;
while (*line == ' ')
line++;
ski = make_simple_sexp_from_hexstr (line, &n);
line += n;
while (*line == ' ')
line++;
}
else if (!strncmp (line, "SENDISSUERCERT", 14)
&& (line[14] == ' ' || !line[14]))
{
@ -304,7 +318,7 @@ inq_certificate (void *opaque, const char *line)
ksba_cert_t cert;
err = gpgsm_find_cert (line, &cert);
err = gpgsm_find_cert (line, ski, &cert);
if (err)
{
log_error ("certificate not found: %s\n", gpg_strerror (err));
@ -321,6 +335,7 @@ inq_certificate (void *opaque, const char *line)
}
}
xfree (ski);
return rc;
}
@ -717,7 +732,7 @@ run_command_inq_cb (void *opaque, const char *line)
if (!*line)
return ASSUAN_Inquire_Error;
err = gpgsm_find_cert (line, &cert);
err = gpgsm_find_cert (line, NULL, &cert);
if (err)
{
log_error ("certificate not found: %s\n", gpg_strerror (err));

View file

@ -266,6 +266,42 @@ check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist)
}
/* Helper fucntion for find_up. This resets the key handle and search
for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns
0 obn success or -1 when not found. */
static int
find_up_search_by_keyid (KEYDB_HANDLE kh,
const char *issuer, ksba_sexp_t keyid)
{
int rc;
ksba_cert_t cert = NULL;
ksba_sexp_t subj = NULL;
keydb_search_reset (kh);
while (!(rc = keydb_search_subject (kh, issuer)))
{
ksba_cert_release (cert); cert = NULL;
rc = keydb_get_cert (kh, &cert);
if (rc)
{
log_error ("keydb_get_cert() failed: rc=%d\n", rc);
rc = -1;
break;
}
xfree (subj);
if (!ksba_cert_get_subj_key_id (cert, NULL, &subj))
{
if (!cmp_simple_canon_sexp (keyid, subj))
break; /* Found matching cert. */
}
}
ksba_cert_release (cert);
xfree (subj);
return rc? -1:0;
}
static void
find_up_store_certs_cb (void *cb_value, ksba_cert_t cert)
{
@ -275,13 +311,13 @@ find_up_store_certs_cb (void *cb_value, ksba_cert_t cert)
}
/* Helper for find_up(). Locate the certificate for ISSUER using an
external lookup. KH is the keydb context we are currently using.
On success 0 is returned and the certificate may be retrieved from
the keydb using keydb_get_cert().*/
the keydb using keydb_get_cert(). KEYID is the keyIdentifier from
the AKI or NULL. */
static int
find_up_external (KEYDB_HANDLE kh, const char *issuer)
find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid)
{
int rc;
strlist_t names = NULL;
@ -324,8 +360,13 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer)
/* The issuers are currently stored in the ephemeral key DB, so
we temporary switch to ephemeral mode. */
old = keydb_set_ephemeral (kh, 1);
keydb_search_reset (kh);
rc = keydb_search_subject (kh, issuer);
if (keyid)
rc = find_up_search_by_keyid (kh, issuer, keyid);
else
{
keydb_search_reset (kh);
rc = keydb_search_subject (kh, issuer);
}
keydb_set_ephemeral (kh, old);
}
return rc;
@ -343,9 +384,10 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
{
ksba_name_t authid;
ksba_sexp_t authidno;
ksba_sexp_t keyid;
int rc = -1;
if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno))
if (!ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno))
{
const char *s = ksba_name_enum (authid, 0);
if (s && *authidno)
@ -369,28 +411,57 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
keydb_set_ephemeral (kh, old);
}
/* If we didn't found it, try an external lookup. */
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
rc = find_up_external (kh, issuer);
}
if (rc == -1 && keyid && !find_next)
{
/* Not found by AIK.issuer_sn. Lets try the AIY.ki
instead. Loop over all certificates with that issuer as
subject and stop for the one with a matching
subjectKeyIdentifier. */
rc = find_up_search_by_keyid (kh, issuer, keyid);
if (rc)
{
int old = keydb_set_ephemeral (kh, 1);
if (!old)
rc = find_up_search_by_keyid (kh, issuer, keyid);
keydb_set_ephemeral (kh, old);
}
if (rc)
rc = -1; /* Need to make sure to have this error code. */
}
/* If we still didn't found it, try an external lookup. */
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
rc = find_up_external (kh, issuer, keyid);
/* Print a note so that the user does not feel too helpless when
an issuer certificate was found and gpgsm prints BAD
signature because it is not the correct one. */
if (rc == -1)
{
log_info ("%sissuer certificate (#", find_next?"next ":"");
gpgsm_dump_serial (authidno);
log_printf ("/");
gpgsm_dump_string (s);
log_printf (") not found using authorityKeyIdentifier\n");
log_info ("%sissuer certificate ", find_next?"next ":"");
if (keyid)
{
log_printf ("{");
gpgsm_dump_serial (keyid);
log_printf ("} ");
}
if (authidno)
{
log_printf ("(#");
gpgsm_dump_serial (authidno);
log_printf ("/");
gpgsm_dump_string (s);
log_printf (") ");
}
log_printf ("not found using authorityKeyIdentifier\n");
}
else if (rc)
log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc);
xfree (keyid);
ksba_name_release (authid);
xfree (authidno);
/* Fixme: There is no way to do an external lookup with
serial+issuer. */
}
if (rc) /* Not found via authorithyKeyIdentifier, try regular issuer name. */
@ -409,7 +480,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
/* Still not found. If enabled, try an external lookup. */
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
rc = find_up_external (kh, issuer);
rc = find_up_external (kh, issuer, NULL);
return rc;
}
@ -468,7 +539,7 @@ gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next)
rc = keydb_get_cert (kh, r_next);
if (rc)
{
log_error ("failed to get cert: rc=%d\n", rc);
log_error ("keydb_get_cert() failed: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_GENERAL);
}
@ -791,7 +862,7 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
rc = keydb_get_cert (kh, &issuer_cert);
if (rc)
{
log_error ("failed to get cert: rc=%d\n", rc);
log_error ("keydb_get_cert() failed: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}
@ -818,6 +889,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
might have been used. This is required because some
CAs are reusing the issuer and subject DN for new
root certificates. */
/* FIXME: Do this only if we don't have an
AKI.keyIdentifier */
rc = find_up (kh, subject_cert, issuer, 1);
if (!rc)
{
@ -1008,7 +1081,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert)
rc = keydb_get_cert (kh, &issuer_cert);
if (rc)
{
log_error ("failed to get cert: rc=%d\n", rc);
log_error ("keydb_get_cert() failed: rc=%d\n", rc);
rc = gpg_error (GPG_ERR_GENERAL);
goto leave;
}

View file

@ -75,6 +75,7 @@ gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p)
}
/* Dump the serial number or any other simple S-expression. */
void
gpgsm_dump_serial (ksba_const_sexp_t p)
{

View file

@ -1,5 +1,5 @@
/* certlist.c - build list of certificates
* Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
* Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -412,9 +412,11 @@ gpgsm_release_certlist (CERTLIST list)
/* Like gpgsm_add_to_certlist, but look only for one certificate. No
chain validation is done */
chain validation is done. If KEYID is not NULL it is take as an
additional filter value which must match the
subjectKeyIdentifier. */
int
gpgsm_find_cert (const char *name, ksba_cert_t *r_cert)
gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
{
int rc;
KEYDB_SEARCH_DESC desc;
@ -429,10 +431,38 @@ gpgsm_find_cert (const char *name, ksba_cert_t *r_cert)
rc = gpg_error (GPG_ERR_ENOMEM);
else
{
nextone:
rc = keydb_search (kh, &desc, 1);
if (!rc)
rc = keydb_get_cert (kh, r_cert);
if (!rc)
{
rc = keydb_get_cert (kh, r_cert);
if (!rc && keyid)
{
ksba_sexp_t subj;
rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj);
if (!rc)
{
if (cmp_simple_canon_sexp (keyid, subj))
{
xfree (subj);
goto nextone;
}
xfree (subj);
/* Okay: Here we know that the certificate's
subjectKeyIdentifier matches the requested
one. */
}
else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
goto nextone;
}
}
/* If we don't have the KEYID filter we need to check for
ambigious search results. Note, that it is somehwat
reasonable to assume that a specification of a KEYID
won't lead to ambiguous names. */
if (!rc && !keyid)
{
rc = keydb_search (kh, &desc, 1);
if (rc == -1)

View file

@ -1566,7 +1566,7 @@ main ( int argc, char **argv)
ksba_cert_t cert = NULL;
char *grip = NULL;
rc = gpgsm_find_cert (*argv, &cert);
rc = gpgsm_find_cert (*argv, NULL, &cert);
if (rc)
;
else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))

View file

@ -252,7 +252,7 @@ int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert,
int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
certlist_t *listaddr, int is_encrypt_to);
void gpgsm_release_certlist (certlist_t list);
int gpgsm_find_cert (const char *name, ksba_cert_t *r_cert);
int gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert);
/*-- keylist.c --*/
gpg_error_t gpgsm_list_keys (ctrl_t ctrl, STRLIST names,

View file

@ -1,6 +1,6 @@
/* keylist.c
/* keylist.c - Print certificates in various formats.
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
* 2004 Free Software Foundation, Inc.
* 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -122,7 +122,7 @@ static struct {
{ "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
/* X.509 id-ce */
{ "2.5.29.14", "subjectKeyIdentifier"},
{ "2.5.29.14", "subjectKeyIdentifier", 1},
{ "2.5.29.15", "keyUsage", 1 },
{ "2.5.29.16", "privateKeyUsagePeriod" },
{ "2.5.29.17", "subjectAltName", 1 },
@ -512,7 +512,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
{
gpg_error_t err;
size_t off, len;
ksba_sexp_t sexp;
ksba_sexp_t sexp, keyid;
char *dn;
ksba_isotime_t t;
int idx, i;
@ -588,9 +588,27 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?");
}
/* subjectKeyIdentifier */
fputs (" subjKeyId: ", fp);
err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
{
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
fputs ("[none]\n", fp);
else
{
gpgsm_print_serial (fp, keyid);
ksba_free (keyid);
putc ('\n', fp);
}
}
else
fputs ("[?]\n", fp);
/* authorityKeyIdentifier */
fputs (" authKeyId: ", fp);
err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp);
err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
{
if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
@ -603,6 +621,13 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
print_names_raw (fp, -15, name);
ksba_name_release (name);
}
if (keyid)
{
fputs (" authKeyId.ki: ", fp);
gpgsm_print_serial (fp, keyid);
ksba_free (keyid);
putc ('\n', fp);
}
}
else
fputs ("[?]\n", fp);