* gpgsm.c: New option --auto-issuer-key-retrieve.

* certpath.c (find_up): Try to retrieve an issuer key from an
external source and from the ephemeral key DB.
(find_up_store_certs_cb): New.

* keydb.c (keydb_set_ephemeral): Does now return the old
state.  Call the backend only when required.

* call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR.
(lookup_status_cb): Issue status only when CTRL is not NULL.
(gpgsm_dirmngr_lookup): Document that CTRL is optional.

* call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT.
This commit is contained in:
Werner Koch 2002-06-29 14:01:53 +00:00
parent 2082905525
commit df58e024e7
8 changed files with 214 additions and 23 deletions

View File

@ -1,3 +1,19 @@
2002-06-29 Werner Koch <wk@gnupg.org>
* gpgsm.c: New option --auto-issuer-key-retrieve.
* certpath.c (find_up): Try to retrieve an issuer key from an
external source and from the ephemeral key DB.
(find_up_store_certs_cb): New.
* keydb.c (keydb_set_ephemeral): Does now return the old
state. Call the backend only when required.
* call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR.
(lookup_status_cb): Issue status only when CTRL is not NULL.
(gpgsm_dirmngr_lookup): Document that CTRL is optional.
* call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT.
2002-06-28 Werner Koch <wk@gnupg.org>
* server.c (cmd_recipient): Add more reason codes.

View File

@ -164,7 +164,7 @@ start_agent (void)
}
if (!opt.agent_program || !*opt.agent_program)
opt.agent_program = "../agent/gpg-agent";
opt.agent_program = GNUPG_DEFAULT_AGENT;
if ( !(pgmname = strrchr (opt.agent_program, '/')))
pgmname = opt.agent_program;
else

View File

@ -156,7 +156,7 @@ start_dirmngr (void)
}
if (!opt.dirmngr_program || !*opt.dirmngr_program)
opt.dirmngr_program = "/usr/sbin/dirmngr";
opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR;
if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
pgmname = opt.dirmngr_program;
else
@ -432,9 +432,12 @@ lookup_status_cb (void *opaque, const char *line)
if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
{
for (line +=9; *line == ' '; line++)
;
gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
if (parm->ctrl)
{
for (line +=9; *line == ' '; line++)
;
gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
}
}
return 0;
}
@ -442,7 +445,8 @@ lookup_status_cb (void *opaque, const char *line)
/* Run the Directroy Managers lookup command using the apptern
compiled from the strings given in NAMES. The caller must provide
the callback CB which will be passed cert by cert. */
the callback CB which will be passed cert by cert. Note that CTRL
is optional. */
int
gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names,
void (*cb)(void*, KsbaCert), void *cb_value)

View File

@ -196,6 +196,15 @@ check_cert_policy (KsbaCert cert)
}
static void
find_up_store_certs_cb (void *cb_value, KsbaCert cert)
{
if (keydb_store_cert (cert, 1))
log_error ("error storing issuer certificate as ephemeral\n");
++*(int*)cb_value;
}
static int
find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
{
@ -211,13 +220,82 @@ find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
rc = keydb_search_issuer_sn (kh, s, authidno);
if (rc)
keydb_search_reset (kh);
if (rc == -1)
{ /* And try the ephemeral DB. */
int old = keydb_set_ephemeral (kh, 1);
if (!old)
{
rc = keydb_search_issuer_sn (kh, s, authidno);
if (rc)
keydb_search_reset (kh);
}
keydb_set_ephemeral (kh, old);
}
}
ksba_name_release (authid);
xfree (authidno);
/* Fixme: don't know how to do dirmngr lookup with serial+issuer. */
}
if (rc)
rc = keydb_search_subject (kh, issuer);
if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */
rc = keydb_search_subject (kh, issuer);
if (rc == -1)
{
/* Not found, lets see whether we have one in the ephemeral key DB. */
int old = keydb_set_ephemeral (kh, 1);
if (!old)
{
keydb_search_reset (kh);
rc = keydb_search_subject (kh, issuer);
}
keydb_set_ephemeral (kh, old);
}
if (rc == -1 && opt.auto_issuer_key_retrieve)
{
STRLIST names = NULL;
int count = 0;
char *pattern;
const char *s;
if (opt.verbose)
log_info (_("looking up issuer at external location\n"));
/* dirmngr is confused about unknown attributes so has a quick
and ugly hack we locate the CN and use this and the
following. Fixme: we should have far ebtter parsing in the
dirmngr. */
s = strstr (issuer, "CN=");
if (!s || s == issuer || s[-1] != ',')
s = issuer;
pattern = xtrymalloc (strlen (s)+2);
if (!pattern)
return GNUPG_Out_Of_Core;
strcpy (stpcpy (pattern, "/"), s);
add_to_strlist (&names, pattern);
xfree (pattern);
rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count);
free_strlist (names);
if (opt.verbose)
log_info (_("number of issuers matching: %d\n"), count);
if (rc)
{
log_error ("external key lookup failed: %s\n", gnupg_strerror (rc));
rc = -1;
}
else if (!count)
rc = -1;
else
{
int old;
/* 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);
keydb_set_ephemeral (kh, old);
}
}
return rc;
}

View File

@ -196,6 +196,15 @@ check_cert_policy (KsbaCert cert)
}
static void
find_up_store_certs_cb (void *cb_value, KsbaCert cert)
{
if (keydb_store_cert (cert, 1))
log_error ("error storing issuer certificate as ephemeral\n");
++*(int*)cb_value;
}
static int
find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
{
@ -211,13 +220,82 @@ find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
rc = keydb_search_issuer_sn (kh, s, authidno);
if (rc)
keydb_search_reset (kh);
if (rc == -1)
{ /* And try the ephemeral DB. */
int old = keydb_set_ephemeral (kh, 1);
if (!old)
{
rc = keydb_search_issuer_sn (kh, s, authidno);
if (rc)
keydb_search_reset (kh);
}
keydb_set_ephemeral (kh, old);
}
}
ksba_name_release (authid);
xfree (authidno);
/* Fixme: don't know how to do dirmngr lookup with serial+issuer. */
}
if (rc)
rc = keydb_search_subject (kh, issuer);
if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */
rc = keydb_search_subject (kh, issuer);
if (rc == -1)
{
/* Not found, lets see whether we have one in the ephemeral key DB. */
int old = keydb_set_ephemeral (kh, 1);
if (!old)
{
keydb_search_reset (kh);
rc = keydb_search_subject (kh, issuer);
}
keydb_set_ephemeral (kh, old);
}
if (rc == -1 && opt.auto_issuer_key_retrieve)
{
STRLIST names = NULL;
int count = 0;
char *pattern;
const char *s;
if (opt.verbose)
log_info (_("looking up issuer at external location\n"));
/* dirmngr is confused about unknown attributes so has a quick
and ugly hack we locate the CN and use this and the
following. Fixme: we should have far ebtter parsing in the
dirmngr. */
s = strstr (issuer, "CN=");
if (!s || s == issuer || s[-1] != ',')
s = issuer;
pattern = xtrymalloc (strlen (s)+2);
if (!pattern)
return GNUPG_Out_Of_Core;
strcpy (stpcpy (pattern, "/"), s);
add_to_strlist (&names, pattern);
xfree (pattern);
rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count);
free_strlist (names);
if (opt.verbose)
log_info (_("number of issuers matching: %d\n"), count);
if (rc)
{
log_error ("external key lookup failed: %s\n", gnupg_strerror (rc));
rc = -1;
}
else if (!count)
rc = -1;
else
{
int old;
/* 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);
keydb_set_ephemeral (kh, old);
}
}
return rc;
}

View File

@ -112,7 +112,7 @@ enum cmd_and_opt_values {
oPolicyFile,
oDisablePolicyChecks,
oEnablePolicyChecks,
oAutoIssuerKeyRetrieve,
oTextmode,
@ -259,6 +259,9 @@ static ARGPARSE_OPTS opts[] = {
N_("do not check certificate policies")},
{ oEnablePolicyChecks, "enable-policy-checks", 0, "@"},
{ oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0,
N_("fetch missing issuer certificates")},
#if 0
{ oDefRecipient, "default-recipient" ,2,
N_("|NAME|use NAME as default recipient")},
@ -809,7 +812,10 @@ main ( int argc, char **argv)
case oEnablePolicyChecks:
opt.no_policy_check = 0;
break;
case oAutoIssuerKeyRetrieve:
opt.auto_issuer_key_retrieve = 1;
break;
case oOutput: opt.outfile = pargs.r.ret_str; break;

View File

@ -79,6 +79,8 @@ struct {
char *policy_file; /* full pathname of policy file */
int no_policy_check; /* ignore certificate policies */
int no_path_validation; /* Bypass all cert path validity tests */
int auto_issuer_key_retrieve; /* try to retrieve a missing issuer key. */
} opt;

View File

@ -59,7 +59,7 @@ struct keydb_handle {
int locked;
int found;
int current;
int ephemeral;
int is_ephemeral;
int used; /* items in active */
struct resource_item active[MAX_KEYDB_RESOURCES];
};
@ -332,27 +332,34 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
return s? s: "";
}
/* Switch the handle into ephemeral mode and return the orginal value. */
int
keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
{
int i;
if (!hd)
return GNUPG_Invalid_Value;
return 0;
for (i=0; i < hd->used; i++)
yes = !!yes;
if (hd->is_ephemeral != yes)
{
switch (hd->active[i].type)
for (i=0; i < hd->used; i++)
{
case KEYDB_RESOURCE_TYPE_NONE:
break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
keybox_set_ephemeral (hd->active[i].u.kr, yes);
break;
switch (hd->active[i].type)
{
case KEYDB_RESOURCE_TYPE_NONE:
break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
keybox_set_ephemeral (hd->active[i].u.kr, yes);
break;
}
}
}
return 0;
i = hd->is_ephemeral;
hd->is_ephemeral = yes;
return i;
}