mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Always search missing certifcates using a running Dirmngr's cache.
This commit is contained in:
parent
2bdbb92939
commit
0819c1e8ca
3
NEWS
3
NEWS
@ -1,6 +1,9 @@
|
|||||||
Noteworthy changes in version 2.0.9 (unreleased)
|
Noteworthy changes in version 2.0.9 (unreleased)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
* Gpgsm always tries to locate missing certificates from a running
|
||||||
|
Dirmngr's cache.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 2.0.8 (2007-12-20)
|
Noteworthy changes in version 2.0.8 (2007-12-20)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2008-01-31 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* audit.c (audit_print_result): Make sure that the output is
|
||||||
|
always UTF8.
|
||||||
|
|
||||||
2008-01-27 Werner Koch <wk@g10code.com>
|
2008-01-27 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* exechelp.c (gnupg_spawn_process): Add arg FLAGS and changed all
|
* exechelp.c (gnupg_spawn_process): Add arg FLAGS and changed all
|
||||||
|
@ -938,10 +938,13 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
|
|||||||
helptag_t helptag;
|
helptag_t helptag;
|
||||||
const char *s;
|
const char *s;
|
||||||
int show_raw = 0;
|
int show_raw = 0;
|
||||||
|
char *orig_codeset;
|
||||||
|
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
orig_codeset = i18n_switchto_utf8 ();
|
||||||
|
|
||||||
/* We use an environment variable to include some debug info in the
|
/* We use an environment variable to include some debug info in the
|
||||||
log. */
|
log. */
|
||||||
if ((s = getenv ("gnupg_debug_audit")))
|
if ((s = getenv ("gnupg_debug_audit")))
|
||||||
@ -1090,5 +1093,6 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
|
|||||||
ctx->outstream = NULL;
|
ctx->outstream = NULL;
|
||||||
ctx->use_html = 0;
|
ctx->use_html = 0;
|
||||||
clear_helptags (ctx);
|
clear_helptags (ctx);
|
||||||
|
i18n_switchback (orig_codeset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,6 +1182,8 @@ The value of @var{what} specifies the kind of information returned:
|
|||||||
@table @code
|
@table @code
|
||||||
@item version
|
@item version
|
||||||
Return the version of the program.
|
Return the version of the program.
|
||||||
|
@item pid
|
||||||
|
Return the process id of the process.
|
||||||
@item socket_name
|
@item socket_name
|
||||||
Return the name of the socket used to connect the agent.
|
Return the name of the socket used to connect the agent.
|
||||||
@item ssh_socket_name
|
@item ssh_socket_name
|
||||||
|
@ -928,6 +928,7 @@ Assuan manual for details.
|
|||||||
* GPGSM EXPORT:: Export certificates.
|
* GPGSM EXPORT:: Export certificates.
|
||||||
* GPGSM IMPORT:: Import certificates.
|
* GPGSM IMPORT:: Import certificates.
|
||||||
* GPGSM DELETE:: Delete certificates.
|
* GPGSM DELETE:: Delete certificates.
|
||||||
|
* GPGSM GETINFO:: Information about the process
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
@ -1197,7 +1198,7 @@ import private keys; a helper program is used for that.
|
|||||||
@node GPGSM DELETE
|
@node GPGSM DELETE
|
||||||
@subsection Delete certificates
|
@subsection Delete certificates
|
||||||
|
|
||||||
To delete certificate the command
|
To delete a certificate the command
|
||||||
|
|
||||||
@example
|
@example
|
||||||
DELKEYS @var{pattern}
|
DELKEYS @var{pattern}
|
||||||
@ -1210,6 +1211,22 @@ this requires that the usual escape quoting rules are done.
|
|||||||
The certificates must be specified unambiguously otherwise an error is
|
The certificates must be specified unambiguously otherwise an error is
|
||||||
returned.
|
returned.
|
||||||
|
|
||||||
|
@node GPGSM GETINFO
|
||||||
|
@subsection Return information about the process
|
||||||
|
|
||||||
|
This is a multipurpose function to return a variety of information.
|
||||||
|
|
||||||
|
@example
|
||||||
|
GETINFO @var{what}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The value of @var{what} specifies the kind of information returned:
|
||||||
|
@table @code
|
||||||
|
@item version
|
||||||
|
Return the version of the program.
|
||||||
|
@item pid
|
||||||
|
Return the process id of the process.
|
||||||
|
@end table
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2008-02-11 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* server.c (cmd_getinfo): New.
|
||||||
|
(register_commands): Register GETINFO.
|
||||||
|
|
||||||
2008-02-09 Marcus Brinkmann <marcus@g10code.de>
|
2008-02-09 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpg.c (main): New variable default_configname. Use it if
|
* gpg.c (main): New variable default_configname. Use it if
|
||||||
|
32
g10/server.c
32
g10/server.c
@ -1,5 +1,5 @@
|
|||||||
/* server.c - server mode for gpg
|
/* server.c - server mode for gpg
|
||||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
* Copyright (C) 2006, 2008 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -386,7 +386,36 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* GETINFO <what>
|
||||||
|
|
||||||
|
Multipurpose function to return a variety of information.
|
||||||
|
Supported values for WHAT are:
|
||||||
|
|
||||||
|
version - Return the version of the program.
|
||||||
|
pid - Return the process id of the server.
|
||||||
|
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmd_getinfo (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!strcmp (line, "version"))
|
||||||
|
{
|
||||||
|
const char *s = VERSION;
|
||||||
|
rc = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "pid"))
|
||||||
|
{
|
||||||
|
char numbuf[50];
|
||||||
|
|
||||||
|
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
||||||
|
rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -414,6 +443,7 @@ register_commands (assuan_context_t ctx)
|
|||||||
{ "LISTSECRETKEYS",cmd_listsecretkeys },
|
{ "LISTSECRETKEYS",cmd_listsecretkeys },
|
||||||
{ "GENKEY", cmd_genkey },
|
{ "GENKEY", cmd_genkey },
|
||||||
{ "DELKEYS", cmd_delkeys },
|
{ "DELKEYS", cmd_delkeys },
|
||||||
|
{ "GETINFO", cmd_getinfo },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
19
sm/ChangeLog
19
sm/ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
2008-02-13 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* call-dirmngr.c (gpgsm_dirmngr_lookup): Add arg CACHE_ONLY.
|
||||||
|
* keylist.c (list_external_keys): Pass false for new arg.
|
||||||
|
* certchain.c (find_up_dirmngr): New.
|
||||||
|
(find_up): Also try to read from the dirmngr cache.
|
||||||
|
(find_up, find_up_external, gpgsm_walk_cert_chain)
|
||||||
|
(gpgsm_basic_cert_check, allowed_ca): Add arg CTRL and changed all
|
||||||
|
callers.
|
||||||
|
* call-agent.c (struct learn_parm_s): Add field CTRL.
|
||||||
|
(gpgsm_agent_learn): Set it.
|
||||||
|
|
||||||
|
2008-02-11 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* server.c (cmd_getinfo): New.
|
||||||
|
(gpgsm_server): Register GETINFO.
|
||||||
|
|
||||||
2008-01-29 Marcus Brinkmann <marcus@g10code.de>
|
2008-01-29 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* keylist.c (list_internal_keys): New variable lastcert. Use it
|
* keylist.c (list_internal_keys): New variable lastcert. Use it
|
||||||
@ -35,7 +52,7 @@
|
|||||||
|
|
||||||
2007-12-03 Werner Koch <wk@g10code.com>
|
2007-12-03 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpgsm.c (main): All gnupg_reopen_std.
|
* gpgsm.c (main): Call gnupg_reopen_std.
|
||||||
|
|
||||||
h2007-11-22 Werner Koch <wk@g10code.com>
|
h2007-11-22 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ struct genkey_parm_s
|
|||||||
struct learn_parm_s
|
struct learn_parm_s
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
ctrl_t ctrl;
|
||||||
assuan_context_t ctx;
|
assuan_context_t ctx;
|
||||||
membuf_t *data;
|
membuf_t *data;
|
||||||
};
|
};
|
||||||
@ -638,7 +639,7 @@ learn_cb (void *opaque, const void *buffer, size_t length)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = gpgsm_basic_cert_check (cert);
|
rc = gpgsm_basic_cert_check (parm->ctrl, cert);
|
||||||
if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT)
|
if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT)
|
||||||
{ /* For later use we store it in the ephemeral database. */
|
{ /* For later use we store it in the ephemeral database. */
|
||||||
log_info ("issuer certificate missing - storing as ephemeral\n");
|
log_info ("issuer certificate missing - storing as ephemeral\n");
|
||||||
@ -679,6 +680,7 @@ gpgsm_agent_learn (ctrl_t ctrl)
|
|||||||
|
|
||||||
init_membuf (&data, 4096);
|
init_membuf (&data, 4096);
|
||||||
learn_parm.error = 0;
|
learn_parm.error = 0;
|
||||||
|
learn_parm.ctrl = ctrl;
|
||||||
learn_parm.ctx = agent_ctx;
|
learn_parm.ctx = agent_ctx;
|
||||||
learn_parm.data = &data;
|
learn_parm.data = &data;
|
||||||
rc = assuan_transact (agent_ctx, "LEARN --send",
|
rc = assuan_transact (agent_ctx, "LEARN --send",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* call-dirmngr.c - communication with the dromngr
|
/* call-dirmngr.c - communication with the dromngr
|
||||||
* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
|
* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -704,9 +704,10 @@ lookup_status_cb (void *opaque, const char *line)
|
|||||||
/* Run the Directroy Managers lookup command using the pattern
|
/* Run the Directroy Managers lookup command using the pattern
|
||||||
compiled from the strings given in NAMES. The caller must provide
|
compiled from the strings given in NAMES. The caller must provide
|
||||||
the callback CB which will be passed cert by cert. Note that CTRL
|
the callback CB which will be passed cert by cert. Note that CTRL
|
||||||
is optional. */
|
is optional. With CACHE_ONLY the dirmngr will search only its own
|
||||||
|
key cache. */
|
||||||
int
|
int
|
||||||
gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names,
|
gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
|
||||||
void (*cb)(void*, ksba_cert_t), void *cb_value)
|
void (*cb)(void*, ksba_cert_t), void *cb_value)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@ -722,7 +723,8 @@ gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names,
|
|||||||
pattern = pattern_from_strlist (names);
|
pattern = pattern_from_strlist (names);
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return out_of_core ();
|
return out_of_core ();
|
||||||
snprintf (line, DIM(line)-1, "LOOKUP %s", pattern);
|
snprintf (line, DIM(line)-1, "LOOKUP%s %s",
|
||||||
|
cache_only? " --cache-only":"", pattern);
|
||||||
line[DIM(line)-1] = 0;
|
line[DIM(line)-1] = 0;
|
||||||
xfree (pattern);
|
xfree (pattern);
|
||||||
|
|
||||||
|
132
sm/certchain.c
132
sm/certchain.c
@ -60,7 +60,7 @@ struct chain_item_s
|
|||||||
typedef struct chain_item_s *chain_item_t;
|
typedef struct chain_item_s *chain_item_t;
|
||||||
|
|
||||||
|
|
||||||
static int get_regtp_ca_info (ksba_cert_t cert, int *chainlen);
|
static int get_regtp_ca_info (ctrl_t ctrl, ksba_cert_t cert, int *chainlen);
|
||||||
|
|
||||||
|
|
||||||
/* This function returns true if we already asked during this session
|
/* This function returns true if we already asked during this session
|
||||||
@ -259,7 +259,8 @@ unknown_criticals (ksba_cert_t cert, int listmode, estream_t fp)
|
|||||||
BasicConstraints extension. The function returns 0 on success and
|
BasicConstraints extension. The function returns 0 on success and
|
||||||
the awlloed length of the chain at CHAINLEN. */
|
the awlloed length of the chain at CHAINLEN. */
|
||||||
static int
|
static int
|
||||||
allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, estream_t fp)
|
allowed_ca (ctrl_t ctrl,
|
||||||
|
ksba_cert_t cert, int *chainlen, int listmode, estream_t fp)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int flag;
|
int flag;
|
||||||
@ -269,7 +270,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, estream_t fp)
|
|||||||
return err;
|
return err;
|
||||||
if (!flag)
|
if (!flag)
|
||||||
{
|
{
|
||||||
if (get_regtp_ca_info (cert, chainlen))
|
if (get_regtp_ca_info (ctrl, cert, chainlen))
|
||||||
{
|
{
|
||||||
/* Note that dirmngr takes a different way to cope with such
|
/* Note that dirmngr takes a different way to cope with such
|
||||||
certs. */
|
certs. */
|
||||||
@ -417,7 +418,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist)
|
|||||||
|
|
||||||
/* Helper function for find_up. This resets the key handle and search
|
/* Helper function for find_up. This resets the key handle and search
|
||||||
for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns
|
for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns
|
||||||
0 obn success or -1 when not found. */
|
0 on success or -1 when not found. */
|
||||||
static int
|
static int
|
||||||
find_up_search_by_keyid (KEYDB_HANDLE kh,
|
find_up_search_by_keyid (KEYDB_HANDLE kh,
|
||||||
const char *issuer, ksba_sexp_t keyid)
|
const char *issuer, ksba_sexp_t keyid)
|
||||||
@ -464,9 +465,10 @@ find_up_store_certs_cb (void *cb_value, ksba_cert_t cert)
|
|||||||
external lookup. KH is the keydb context we are currently using.
|
external lookup. KH is the keydb context we are currently using.
|
||||||
On success 0 is returned and the certificate may be retrieved from
|
On success 0 is returned and the certificate may be retrieved from
|
||||||
the keydb using keydb_get_cert(). KEYID is the keyIdentifier from
|
the keydb using keydb_get_cert(). KEYID is the keyIdentifier from
|
||||||
the AKI or NULL. */
|
the AKI or NULL. */
|
||||||
static int
|
static int
|
||||||
find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid)
|
find_up_external (ctrl_t ctrl, KEYDB_HANDLE kh,
|
||||||
|
const char *issuer, ksba_sexp_t keyid)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
strlist_t names = NULL;
|
strlist_t names = NULL;
|
||||||
@ -476,14 +478,13 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid)
|
|||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("looking up issuer at external location\n"));
|
log_info (_("looking up issuer at external location\n"));
|
||||||
/* The DIRMNGR process is confused about unknown attributes. As a
|
/* The Dirmngr process is confused about unknown attributes. As a
|
||||||
quick and ugly hack we locate the CN and use the issuer string
|
quick and ugly hack we locate the CN and use the issuer string
|
||||||
starting at this attribite. Fixme: we should have far better
|
starting at this attribite. Fixme: we should have far better
|
||||||
parsing in the dirmngr. */
|
parsing for external lookups in the Dirmngr. */
|
||||||
s = strstr (issuer, "CN=");
|
s = strstr (issuer, "CN=");
|
||||||
if (!s || s == issuer || s[-1] != ',')
|
if (!s || s == issuer || s[-1] != ',')
|
||||||
s = issuer;
|
s = issuer;
|
||||||
|
|
||||||
pattern = xtrymalloc (strlen (s)+2);
|
pattern = xtrymalloc (strlen (s)+2);
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
@ -491,7 +492,7 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid)
|
|||||||
add_to_strlist (&names, pattern);
|
add_to_strlist (&names, pattern);
|
||||||
xfree (pattern);
|
xfree (pattern);
|
||||||
|
|
||||||
rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count);
|
rc = gpgsm_dirmngr_lookup (ctrl, names, 0, find_up_store_certs_cb, &count);
|
||||||
free_strlist (names);
|
free_strlist (names);
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
@ -522,6 +523,54 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper for find_up(). Ask the dirmngr for the certificate for
|
||||||
|
ISSUER with optional SERIALNO. KH is the keydb context we are
|
||||||
|
currently using. With SUBJECT_MODE set, ISSUER is searched as the
|
||||||
|
subject. On success 0 is returned and the certificate is available
|
||||||
|
in the ephemeral DB. */
|
||||||
|
static int
|
||||||
|
find_up_dirmngr (ctrl_t ctrl, KEYDB_HANDLE kh,
|
||||||
|
ksba_sexp_t serialno, const char *issuer, int subject_mode)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
strlist_t names = NULL;
|
||||||
|
int count = 0;
|
||||||
|
char *pattern;
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info (_("looking up issuer from the Dirmngr cache\n"));
|
||||||
|
if (subject_mode)
|
||||||
|
{
|
||||||
|
pattern = xtrymalloc (strlen (issuer)+2);
|
||||||
|
if (pattern)
|
||||||
|
strcpy (stpcpy (pattern, "/"), issuer);
|
||||||
|
}
|
||||||
|
else if (serialno)
|
||||||
|
pattern = gpgsm_format_sn_issuer (serialno, issuer);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pattern = xtrymalloc (strlen (issuer)+3);
|
||||||
|
if (pattern)
|
||||||
|
strcpy (stpcpy (pattern, "#/"), issuer);
|
||||||
|
}
|
||||||
|
if (!pattern)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
add_to_strlist (&names, pattern);
|
||||||
|
xfree (pattern);
|
||||||
|
|
||||||
|
rc = gpgsm_dirmngr_lookup (ctrl, names, 1, find_up_store_certs_cb, &count);
|
||||||
|
free_strlist (names);
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info (_("number of matching certificates: %d\n"), count);
|
||||||
|
if (rc)
|
||||||
|
log_info (_("dirmngr cache-only key lookup failed: %s\n"),
|
||||||
|
gpg_strerror (rc));
|
||||||
|
return (!rc && count)? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Locate issuing certificate for CERT. ISSUER is the name of the
|
/* Locate issuing certificate for CERT. ISSUER is the name of the
|
||||||
issuer used as a fallback if the other methods don't work. If
|
issuer used as a fallback if the other methods don't work. If
|
||||||
FIND_NEXT is true, the function shall return the next possible
|
FIND_NEXT is true, the function shall return the next possible
|
||||||
@ -529,7 +578,8 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid)
|
|||||||
keydb_get_cert on the keyDb context KH will return it. Returns 0
|
keydb_get_cert on the keyDb context KH will return it. Returns 0
|
||||||
on success, -1 if not found or an error code. */
|
on success, -1 if not found or an error code. */
|
||||||
static int
|
static int
|
||||||
find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
find_up (ctrl_t ctrl, 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;
|
||||||
@ -545,6 +595,14 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
|||||||
if (rc)
|
if (rc)
|
||||||
keydb_search_reset (kh);
|
keydb_search_reset (kh);
|
||||||
|
|
||||||
|
/* In case of an error, try to get the certifcate from the
|
||||||
|
dirmngr. That is done by trying to put that certifcate
|
||||||
|
into the ephemeral DB and let the code below do the
|
||||||
|
actual retrieve. Thus there is no error checking.
|
||||||
|
Skipped in find_next mode as usual. */
|
||||||
|
if (rc == -1 && !find_next)
|
||||||
|
find_up_dirmngr (ctrl, kh, authidno, s, 0);
|
||||||
|
|
||||||
/* In case of an error try the ephemeral DB. We can't do
|
/* In case of an error try the ephemeral DB. We can't do
|
||||||
that in find_next mode because we can't keep the search
|
that in find_next mode because we can't keep the search
|
||||||
state then. */
|
state then. */
|
||||||
@ -559,7 +617,8 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
|||||||
}
|
}
|
||||||
keydb_set_ephemeral (kh, old);
|
keydb_set_ephemeral (kh, old);
|
||||||
}
|
}
|
||||||
|
if (rc)
|
||||||
|
rc = -1; /* Need to make sure to have this error code. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == -1 && keyid && !find_next)
|
if (rc == -1 && keyid && !find_next)
|
||||||
@ -568,6 +627,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
|||||||
instead. Loop over all certificates with that issuer as
|
instead. Loop over all certificates with that issuer as
|
||||||
subject and stop for the one with a matching
|
subject and stop for the one with a matching
|
||||||
subjectKeyIdentifier. */
|
subjectKeyIdentifier. */
|
||||||
|
/* Fixme: Should we also search in the dirmngr? */
|
||||||
rc = find_up_search_by_keyid (kh, issuer, keyid);
|
rc = find_up_search_by_keyid (kh, issuer, keyid);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -580,9 +640,29 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
|||||||
rc = -1; /* Need to make sure to have this error code. */
|
rc = -1; /* Need to make sure to have this error code. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we still didn't found it, try to find it via the subject
|
||||||
|
from the dirmngr-cache. */
|
||||||
|
if (rc == -1 && !find_next)
|
||||||
|
{
|
||||||
|
if (!find_up_dirmngr (ctrl, kh, NULL, issuer, 1))
|
||||||
|
{
|
||||||
|
int old = keydb_set_ephemeral (kh, 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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 we still didn't found it, try an external lookup. */
|
||||||
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
|
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
|
||||||
rc = find_up_external (kh, issuer, keyid);
|
rc = find_up_external (ctrl, kh, issuer, keyid);
|
||||||
|
|
||||||
/* 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
|
||||||
@ -617,6 +697,10 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
|||||||
rc = keydb_search_subject (kh, issuer);
|
rc = keydb_search_subject (kh, issuer);
|
||||||
if (rc == -1 && !find_next)
|
if (rc == -1 && !find_next)
|
||||||
{
|
{
|
||||||
|
/* Also try to get it from the Dirmngr cache. The function
|
||||||
|
merely puts it into the ephemeral database. */
|
||||||
|
find_up_dirmngr (ctrl, kh, NULL, issuer, 0);
|
||||||
|
|
||||||
/* Not found, let us see whether we have one in the ephemeral key DB. */
|
/* Not found, let us see whether we have one in the ephemeral key DB. */
|
||||||
int old = keydb_set_ephemeral (kh, 1);
|
int old = keydb_set_ephemeral (kh, 1);
|
||||||
if (!old)
|
if (!old)
|
||||||
@ -629,7 +713,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. */
|
/* Still not found. If enabled, try an external lookup. */
|
||||||
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
|
if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
|
||||||
rc = find_up_external (kh, issuer, NULL);
|
rc = find_up_external (ctrl, kh, issuer, NULL);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -638,7 +722,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
|
|||||||
/* Return the next certificate up in the chain starting at START.
|
/* Return the next certificate up in the chain starting at START.
|
||||||
Returns -1 when there are no more certificates. */
|
Returns -1 when there are no more certificates. */
|
||||||
int
|
int
|
||||||
gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next)
|
gpgsm_walk_cert_chain (ctrl_t ctrl, ksba_cert_t start, ksba_cert_t *r_next)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
char *issuer = NULL;
|
char *issuer = NULL;
|
||||||
@ -674,7 +758,7 @@ gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = find_up (kh, start, issuer, 0);
|
rc = find_up (ctrl, 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
|
||||||
@ -1194,7 +1278,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
|
|||||||
}
|
}
|
||||||
if (!rootca_flags->relax)
|
if (!rootca_flags->relax)
|
||||||
{
|
{
|
||||||
rc = allowed_ca (subject_cert, NULL, listmode, listfp);
|
rc = allowed_ca (ctrl, subject_cert, NULL, listmode, listfp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1301,7 +1385,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
|
|||||||
|
|
||||||
/* 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, 0);
|
rc = find_up (ctrl, kh, subject_cert, issuer, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
@ -1353,7 +1437,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
|
|||||||
root certificates. */
|
root certificates. */
|
||||||
/* FIXME: Do this only if we don't have an
|
/* FIXME: Do this only if we don't have an
|
||||||
AKI.keyIdentifier */
|
AKI.keyIdentifier */
|
||||||
rc = find_up (kh, subject_cert, issuer, 1);
|
rc = find_up (ctrl, kh, subject_cert, issuer, 1);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
ksba_cert_t tmp_cert;
|
ksba_cert_t tmp_cert;
|
||||||
@ -1393,7 +1477,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
|
|||||||
{
|
{
|
||||||
int chainlen;
|
int chainlen;
|
||||||
|
|
||||||
rc = allowed_ca (issuer_cert, &chainlen, listmode, listfp);
|
rc = allowed_ca (ctrl, issuer_cert, &chainlen, listmode, listfp);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
/* Not allowed. Check whether this is a trusted root
|
/* Not allowed. Check whether this is a trusted root
|
||||||
@ -1656,7 +1740,7 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
|
|||||||
the DB and that this one is valid; which it should be because it
|
the DB and that this one is valid; which it should be because it
|
||||||
has been checked using this function. */
|
has been checked using this function. */
|
||||||
int
|
int
|
||||||
gpgsm_basic_cert_check (ksba_cert_t cert)
|
gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
char *issuer = NULL;
|
char *issuer = NULL;
|
||||||
@ -1706,7 +1790,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, 0);
|
rc = find_up (ctrl, kh, cert, issuer, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
@ -1771,7 +1855,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert)
|
|||||||
receive the length of the chain which is either 0 or 1.
|
receive the length of the chain which is either 0 or 1.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
get_regtp_ca_info (ksba_cert_t cert, int *chainlen)
|
get_regtp_ca_info (ctrl_t ctrl, ksba_cert_t cert, int *chainlen)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
ksba_cert_t next;
|
ksba_cert_t next;
|
||||||
@ -1816,7 +1900,7 @@ get_regtp_ca_info (ksba_cert_t cert, int *chainlen)
|
|||||||
ksba_cert_ref (cert);
|
ksba_cert_ref (cert);
|
||||||
array[depth++] = cert;
|
array[depth++] = cert;
|
||||||
ksba_cert_ref (cert);
|
ksba_cert_ref (cert);
|
||||||
while (depth < DIM(array) && !(rc=gpgsm_walk_cert_chain (cert, &next)))
|
while (depth < DIM(array) && !(rc=gpgsm_walk_cert_chain (ctrl, cert, &next)))
|
||||||
{
|
{
|
||||||
ksba_cert_release (cert);
|
ksba_cert_release (cert);
|
||||||
ksba_cert_ref (next);
|
ksba_cert_ref (next);
|
||||||
|
@ -455,7 +455,7 @@ gpgsm_release_certlist (certlist_t list)
|
|||||||
|
|
||||||
|
|
||||||
/* Like gpgsm_add_to_certlist, but look only for one certificate. No
|
/* Like gpgsm_add_to_certlist, but look only for one certificate. No
|
||||||
chain validation is done. If KEYID is not NULL it is take as an
|
chain validation is done. If KEYID is not NULL it is taken as an
|
||||||
additional filter value which must match the
|
additional filter value which must match the
|
||||||
subjectKeyIdentifier. */
|
subjectKeyIdentifier. */
|
||||||
int
|
int
|
||||||
|
@ -285,14 +285,15 @@ int gpgsm_create_cms_signature (ctrl_t ctrl,
|
|||||||
#define VALIDATE_FLAG_CHAIN_MODEL 2
|
#define VALIDATE_FLAG_CHAIN_MODEL 2
|
||||||
|
|
||||||
|
|
||||||
int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next);
|
int gpgsm_walk_cert_chain (ctrl_t ctrl,
|
||||||
|
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 checktime,
|
ksba_isotime_t checktime,
|
||||||
ksba_isotime_t r_exptime,
|
ksba_isotime_t r_exptime,
|
||||||
int listmode, estream_t listfp,
|
int listmode, estream_t listfp,
|
||||||
unsigned int flags, unsigned int *retflags);
|
unsigned int flags, unsigned int *retflags);
|
||||||
int gpgsm_basic_cert_check (ksba_cert_t cert);
|
int gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert);
|
||||||
|
|
||||||
/*-- certlist.c --*/
|
/*-- certlist.c --*/
|
||||||
int gpgsm_cert_use_sign_p (ksba_cert_t cert);
|
int gpgsm_cert_use_sign_p (ksba_cert_t cert);
|
||||||
@ -380,7 +381,7 @@ gpg_error_t gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc);
|
|||||||
int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
||||||
ksba_cert_t cert, ksba_cert_t issuer_cert,
|
ksba_cert_t cert, ksba_cert_t issuer_cert,
|
||||||
int use_ocsp);
|
int use_ocsp);
|
||||||
int gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names,
|
int gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
|
||||||
void (*cb)(void*, ksba_cert_t), void *cb_value);
|
void (*cb)(void*, ksba_cert_t), void *cb_value);
|
||||||
int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
|
int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
|
||||||
int argc, char **argv);
|
int argc, char **argv);
|
||||||
|
@ -172,7 +172,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
|
|||||||
|
|
||||||
Optionally we do a full validation in addition to the basic test.
|
Optionally we do a full validation in addition to the basic test.
|
||||||
*/
|
*/
|
||||||
rc = gpgsm_basic_cert_check (cert);
|
rc = gpgsm_basic_cert_check (ctrl, cert);
|
||||||
if (!rc && ctrl->with_validation)
|
if (!rc && ctrl->with_validation)
|
||||||
rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
|
||||||
if (!rc || (!ctrl->with_validation
|
if (!rc || (!ctrl->with_validation
|
||||||
@ -216,7 +216,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
|
|||||||
the chain. This is required in case we already stored
|
the chain. This is required in case we already stored
|
||||||
parent certificates in the ephemeral keybox. Do not
|
parent certificates in the ephemeral keybox. Do not
|
||||||
update the statistics, though. */
|
update the statistics, though. */
|
||||||
if (!gpgsm_walk_cert_chain (cert, &next))
|
if (!gpgsm_walk_cert_chain (ctrl, cert, &next))
|
||||||
{
|
{
|
||||||
check_and_store (ctrl, NULL, next, depth+1);
|
check_and_store (ctrl, NULL, next, depth+1);
|
||||||
ksba_cert_release (next);
|
ksba_cert_release (next);
|
||||||
|
@ -361,7 +361,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
|
|||||||
{
|
{
|
||||||
ksba_cert_t next;
|
ksba_cert_t next;
|
||||||
|
|
||||||
rc = gpgsm_walk_cert_chain (cert, &next);
|
rc = gpgsm_walk_cert_chain (ctrl, cert, &next);
|
||||||
if (!rc) /* We known the issuer's certificate. */
|
if (!rc) /* We known the issuer's certificate. */
|
||||||
{
|
{
|
||||||
p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
|
p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
|
||||||
@ -1141,7 +1141,7 @@ list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
|
|||||||
else
|
else
|
||||||
list_cert_std (ctrl, cert, fp, 0, with_validation);
|
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 (ctrl, cert, &next))
|
||||||
{
|
{
|
||||||
ksba_cert_release (cert);
|
ksba_cert_release (cert);
|
||||||
es_fputs ("Certified by\n", fp);
|
es_fputs ("Certified by\n", fp);
|
||||||
@ -1382,7 +1382,7 @@ list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
|
|||||||
parm.with_chain = ctrl->with_chain;
|
parm.with_chain = ctrl->with_chain;
|
||||||
parm.raw_mode = raw_mode;
|
parm.raw_mode = raw_mode;
|
||||||
|
|
||||||
rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
|
rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
|
log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
|
||||||
return rc;
|
return rc;
|
||||||
|
33
sm/server.c
33
sm/server.c
@ -1,6 +1,6 @@
|
|||||||
/* server.c - Server mode and main entry point
|
/* server.c - Server mode and main entry point
|
||||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
|
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
* 2007 Free Software Foundation, Inc.
|
* 2007, 2008 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -1007,6 +1007,36 @@ cmd_getauditlog (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* GETINFO <what>
|
||||||
|
|
||||||
|
Multipurpose function to return a variety of information.
|
||||||
|
Supported values for WHAT are:
|
||||||
|
|
||||||
|
version - Return the version of the program.
|
||||||
|
pid - Return the process id of the server.
|
||||||
|
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmd_getinfo (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!strcmp (line, "version"))
|
||||||
|
{
|
||||||
|
const char *s = VERSION;
|
||||||
|
rc = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "pid"))
|
||||||
|
{
|
||||||
|
char numbuf[50];
|
||||||
|
|
||||||
|
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
||||||
|
rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1036,6 +1066,7 @@ register_commands (assuan_context_t ctx)
|
|||||||
{ "GENKEY", cmd_genkey },
|
{ "GENKEY", cmd_genkey },
|
||||||
{ "DELKEYS", cmd_delkeys },
|
{ "DELKEYS", cmd_delkeys },
|
||||||
{ "GETAUDITLOG", cmd_getauditlog },
|
{ "GETAUDITLOG", cmd_getauditlog },
|
||||||
|
{ "GETINFO", cmd_getinfo },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
@ -272,7 +272,7 @@ add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert)
|
|||||||
/* Walk the chain to include all other certificates. Note that a -1
|
/* Walk the chain to include all other certificates. Note that a -1
|
||||||
used for N makes sure that there is no limit and all certs get
|
used for N makes sure that there is no limit and all certs get
|
||||||
included. */
|
included. */
|
||||||
while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) )
|
while ( n-- && !(rc = gpgsm_walk_cert_chain (ctrl, cert, &next)) )
|
||||||
{
|
{
|
||||||
if (not_root && gpgsm_is_root_cert (next))
|
if (not_root && gpgsm_is_root_cert (next))
|
||||||
err = 0;
|
err = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user