mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Exporting secret keys via gpg-agent is now basically supported.
A couple of forward ported changes. Doc updates.
This commit is contained in:
parent
aeb31977ec
commit
bfbd80feb9
8
NEWS
8
NEWS
@ -30,8 +30,8 @@ Noteworthy changes in version 2.1.x (under development)
|
||||
by default.
|
||||
|
||||
* Dirmngr is now a part of this package. Dirmngr is now also
|
||||
expected to run as a system service and the configuraion
|
||||
directories are changed to the gnupg name space.
|
||||
expected to run as a system service and the configuration
|
||||
directories are changed to the GnuPG name space.
|
||||
|
||||
* Given sufficient permissions Dirmngr is started automagically.
|
||||
|
||||
@ -43,6 +43,10 @@ Noteworthy changes in version 2.1.x (under development)
|
||||
|
||||
* The OpenPGP import command is now able to merge secret keys.
|
||||
|
||||
* Removed options:
|
||||
--export-options: export-secret-subkey-passwd
|
||||
--simple-sk-checksum
|
||||
|
||||
|
||||
Noteworthy changes in version 2.0.13 (2009-09-04)
|
||||
-------------------------------------------------
|
||||
|
@ -23,6 +23,7 @@ Release process:
|
||||
(Mainly config.guess and config.sub).
|
||||
* [1.4 only] Update gpg.texi and gpgv.texi from the trunk:
|
||||
make -C doc update-source-from-gnupg-2
|
||||
* [1.4 and 2.0] Copy needed texinfo files from trunk.
|
||||
* Run "make -C po update-po".
|
||||
* Write NEWS entries and set the release date in NEWS.
|
||||
* In configure.ac set "my_issvn" to "no".
|
||||
|
@ -1,3 +1,47 @@
|
||||
2010-09-30 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpg-agent.c (agent_exit): Run cleanup.
|
||||
(cleanup): Run only once.
|
||||
|
||||
* call-pinentry.c (close_button_status_cb): New.
|
||||
(agent_askpin): Add arg R_CANCEL_ALL. Change all callers.
|
||||
* genkey.c (agent_ask_new_passphrase): Ditto.
|
||||
* findkey.c (unprotect): Return GPG_ERR_FULLY_CANCELED if needed.
|
||||
|
||||
* command.c (cmd_export_key): Add support for OpenPGP keys.
|
||||
* findkey.c (unprotect): Add optional arg R_PASSPHRASE.
|
||||
(agent_key_from_file): Ditto. Change all callers.
|
||||
|
||||
* findkey.c (unprotect): Do not put the passphrase into the cache
|
||||
if it has been changed.
|
||||
|
||||
* cvt-openpgp.c (convert_to_openpgp, apply_protection)
|
||||
(key_from_sexp): New.
|
||||
|
||||
2010-09-29 Werner Koch <wk@g10code.com>
|
||||
|
||||
* cvt-openpgp.c (convert_openpgp): Rename to convert_from_openpgp.
|
||||
|
||||
* command.c (has_option): Stop at "--".
|
||||
(has_option_name, option_value): Ditto.
|
||||
(skip_options): Skip initial spaces.
|
||||
|
||||
2010-09-24 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpg-agent.c (main, reread_configuration): Always test whether
|
||||
the default configuration file has been created in the meantime.
|
||||
Fixes bug#1285.
|
||||
|
||||
2010-09-17 Werner Koch <wk@g10code.com>
|
||||
|
||||
* command.c (cmd_havekey): Allow testing of several keygrips.
|
||||
|
||||
2010-09-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* protect.c (calculate_mic): Take care of shared secret format.
|
||||
|
||||
* agent.h (PROTECTED_SHARED_SECRET): New.
|
||||
|
||||
2010-09-02 Werner Koch <wk@g10code.com>
|
||||
|
||||
* cache.c (new_data): Change arg and callers to use a string and
|
||||
|
@ -182,7 +182,8 @@ enum
|
||||
PRIVATE_KEY_UNKNOWN = 0,
|
||||
PRIVATE_KEY_CLEAR = 1,
|
||||
PRIVATE_KEY_PROTECTED = 2,
|
||||
PRIVATE_KEY_SHADOWED = 3
|
||||
PRIVATE_KEY_SHADOWED = 3,
|
||||
PROTECTED_SHARED_SECRET = 4
|
||||
};
|
||||
|
||||
|
||||
@ -233,7 +234,8 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl,
|
||||
unsigned char **shadow_info,
|
||||
cache_mode_t cache_mode,
|
||||
lookup_ttl_t lookup_ttl,
|
||||
gcry_sexp_t *result);
|
||||
gcry_sexp_t *result,
|
||||
char **r_passphrase);
|
||||
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result);
|
||||
@ -251,7 +253,7 @@ int pinentry_active_p (ctrl_t ctrl, int waitseconds);
|
||||
int agent_askpin (ctrl_t ctrl,
|
||||
const char *desc_text, const char *prompt_text,
|
||||
const char *inital_errtext,
|
||||
struct pin_entry_info_s *pininfo);
|
||||
struct pin_entry_info_s *pininfo, int *r_cancelall);
|
||||
int agent_get_passphrase (ctrl_t ctrl, char **retpass,
|
||||
const char *desc, const char *prompt,
|
||||
const char *errtext, int with_qualitybar);
|
||||
@ -289,7 +291,7 @@ int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
||||
/*-- genkey.c --*/
|
||||
int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent);
|
||||
gpg_error_t agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||
char **r_passphrase);
|
||||
char **r_passphrase, int *r_cancelall);
|
||||
int agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
||||
const char *keyparam, size_t keyparmlen, membuf_t *outbuf);
|
||||
int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
|
||||
|
@ -696,6 +696,29 @@ setup_qualitybar (void)
|
||||
}
|
||||
|
||||
|
||||
/* Check the button_info line for a close action. */
|
||||
static gpg_error_t
|
||||
close_button_status_cb (void *opaque, const char *line)
|
||||
{
|
||||
int *flag = opaque;
|
||||
const char *keyword = line;
|
||||
int keywordlen;
|
||||
|
||||
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
|
||||
;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
if (keywordlen == 11 && !memcmp (keyword, "BUTTON_INFO", keywordlen))
|
||||
{
|
||||
if ( !strcmp (line, "close") )
|
||||
*flag = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Call the Entry and ask for the PIN. We do check for a valid PIN
|
||||
number here and repeat it as long as we have invalid formed
|
||||
@ -704,7 +727,7 @@ int
|
||||
agent_askpin (ctrl_t ctrl,
|
||||
const char *desc_text, const char *prompt_text,
|
||||
const char *initial_errtext,
|
||||
struct pin_entry_info_s *pininfo)
|
||||
struct pin_entry_info_s *pininfo, int *r_cancel_all)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
@ -712,6 +735,10 @@ agent_askpin (ctrl_t ctrl,
|
||||
const char *errtext = NULL;
|
||||
int is_pin = 0;
|
||||
int saveflag;
|
||||
int close_button;
|
||||
|
||||
if (r_cancel_all)
|
||||
*r_cancel_all = 0;
|
||||
|
||||
if (opt.batch)
|
||||
return 0; /* fixme: we should return BAD PIN */
|
||||
@ -791,8 +818,10 @@ agent_askpin (ctrl_t ctrl,
|
||||
|
||||
saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
|
||||
assuan_begin_confidential (entry_ctx);
|
||||
close_button = 0;
|
||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
|
||||
inq_quality, entry_ctx, NULL, NULL);
|
||||
inq_quality, entry_ctx,
|
||||
close_button_status_cb, &close_button);
|
||||
assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
|
||||
/* Most pinentries out in the wild return the old Assuan error code
|
||||
for canceled which gets translated to an assuan Cancel error and
|
||||
@ -801,6 +830,11 @@ agent_askpin (ctrl_t ctrl,
|
||||
&& gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
|
||||
/* Set a flag in case the window close button was clicked to
|
||||
cancel the operation. */
|
||||
if (close_button && r_cancel_all && gpg_err_code (rc) == GPG_ERR_CANCELED)
|
||||
*r_cancel_all = 1;
|
||||
|
||||
if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
|
||||
errtext = is_pin? _("PIN too long")
|
||||
: _("Passphrase too long");
|
||||
|
@ -2425,7 +2425,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
|
||||
err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL);
|
||||
initial_errtext = NULL;
|
||||
if (err)
|
||||
goto out;
|
||||
@ -2433,7 +2433,7 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
|
||||
/* Unless the passphrase is empty, ask to confirm it. */
|
||||
if (pi->pin && *pi->pin)
|
||||
{
|
||||
err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
|
||||
err = agent_askpin (ctrl, description2, NULL, NULL, pi2, NULL);
|
||||
if (err == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
|
147
agent/command.c
147
agent/command.c
@ -169,6 +169,23 @@ reset_notify (assuan_context_t ctx, char *line)
|
||||
}
|
||||
|
||||
|
||||
/* Skip over options.
|
||||
Blanks after the options are also removed. */
|
||||
static char *
|
||||
skip_options (const char *line)
|
||||
{
|
||||
while (spacep (line))
|
||||
line++;
|
||||
while ( *line == '-' && line[1] == '-' )
|
||||
{
|
||||
while (*line && !spacep (line))
|
||||
line++;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
}
|
||||
return (char*)line;
|
||||
}
|
||||
|
||||
/* Check whether the option NAME appears in LINE */
|
||||
static int
|
||||
has_option (const char *line, const char *name)
|
||||
@ -177,6 +194,8 @@ has_option (const char *line, const char *name)
|
||||
int n = strlen (name);
|
||||
|
||||
s = strstr (line, name);
|
||||
if (s && s >= skip_options (line))
|
||||
return 0;
|
||||
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
|
||||
}
|
||||
|
||||
@ -190,6 +209,8 @@ has_option_name (const char *line, const char *name)
|
||||
int n = strlen (name);
|
||||
|
||||
s = strstr (line, name);
|
||||
if (s && s >= skip_options (line))
|
||||
return 0;
|
||||
return (s && (s == line || spacep (s-1))
|
||||
&& (!s[n] || spacep (s+n) || s[n] == '='));
|
||||
}
|
||||
@ -203,6 +224,8 @@ option_value (const char *line, const char *name)
|
||||
int n = strlen (name);
|
||||
|
||||
s = strstr (line, name);
|
||||
if (s && s >= skip_options (line))
|
||||
return NULL;
|
||||
if (s && (s == line || spacep (s-1))
|
||||
&& s[n] && (spacep (s+n) || s[n] == '='))
|
||||
{
|
||||
@ -215,23 +238,6 @@ option_value (const char *line, const char *name)
|
||||
}
|
||||
|
||||
|
||||
/* Skip over options. It is assumed that leading spaces have been
|
||||
removed (this is the case for lines passed to a handler from
|
||||
assuan). Blanks after the options are also removed. */
|
||||
static char *
|
||||
skip_options (char *line)
|
||||
{
|
||||
while ( *line == '-' && line[1] == '-' )
|
||||
{
|
||||
while (*line && !spacep (line))
|
||||
line++;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
/* Replace all '+' by a blank. */
|
||||
static void
|
||||
plus_to_blank (char *s)
|
||||
@ -530,23 +536,35 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
static const char hlp_havekey[] =
|
||||
"HAVEKEY <hexstring_with_keygrip>\n"
|
||||
"HAVEKEY <hexstrings_with_keygrips>\n"
|
||||
"\n"
|
||||
"Return success when the secret key is available.";
|
||||
"Return success if at least one of the secret keys with the given\n"
|
||||
"keygrips is available.";
|
||||
static gpg_error_t
|
||||
cmd_havekey (assuan_context_t ctx, char *line)
|
||||
{
|
||||
int rc;
|
||||
gpg_error_t err;
|
||||
unsigned char buf[20];
|
||||
|
||||
rc = parse_keygrip (ctx, line, buf);
|
||||
if (rc)
|
||||
return rc;
|
||||
do
|
||||
{
|
||||
err = parse_keygrip (ctx, line, buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (agent_key_available (buf))
|
||||
return gpg_error (GPG_ERR_NO_SECKEY);
|
||||
if (!agent_key_available (buf))
|
||||
return 0; /* Found. */
|
||||
|
||||
return 0;
|
||||
while (*line && *line != ' ' && *line != '\t')
|
||||
line++;
|
||||
while (*line == ' ' || *line == '\t')
|
||||
line++;
|
||||
}
|
||||
while (*line);
|
||||
|
||||
/* No leave_cmd() here because errors are expected and would clutter
|
||||
the log. */
|
||||
return gpg_error (GPG_ERR_NO_SECKEY);
|
||||
}
|
||||
|
||||
|
||||
@ -1316,9 +1334,14 @@ cmd_passwd (assuan_context_t ctx, char *line)
|
||||
ctrl->in_passwd++;
|
||||
rc = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc,
|
||||
grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
|
||||
&s_skey);
|
||||
&s_skey, NULL);
|
||||
if (rc)
|
||||
;
|
||||
{
|
||||
/* Not all users of gpg-agent know about fully cancled; thus we
|
||||
map it back. */
|
||||
if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
}
|
||||
else if (!s_skey)
|
||||
{
|
||||
log_error ("changing a smartcard PIN is not yet supported\n");
|
||||
@ -1590,9 +1613,9 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
||||
used to protect the key using the same code as for regular
|
||||
key import. */
|
||||
|
||||
err = convert_openpgp (ctrl, openpgp_sexp, grip,
|
||||
ctrl->server_local->keydesc, cache_nonce,
|
||||
&key, &passphrase);
|
||||
err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
|
||||
ctrl->server_local->keydesc, cache_nonce,
|
||||
&key, &passphrase);
|
||||
if (err)
|
||||
goto leave;
|
||||
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
||||
@ -1620,7 +1643,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
||||
err = agent_ask_new_passphrase
|
||||
(ctrl, _("Please enter the passphrase to protect the "
|
||||
"imported object within the GnuPG system."),
|
||||
&passphrase);
|
||||
&passphrase, NULL);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
@ -1650,7 +1673,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
static const char hlp_export_key[] =
|
||||
"EXPORT_KEY <hexstring_with_keygrip>\n"
|
||||
"EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
|
||||
"\n"
|
||||
"Export a secret key from the key store. The key will be encrypted\n"
|
||||
"using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
|
||||
@ -1668,6 +1691,26 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
||||
gcry_cipher_hd_t cipherhd = NULL;
|
||||
unsigned char *wrappedkey = NULL;
|
||||
size_t wrappedkeylen;
|
||||
int openpgp;
|
||||
char *cache_nonce;
|
||||
char *passphrase = NULL;
|
||||
|
||||
openpgp = has_option (line, "--openpgp");
|
||||
cache_nonce = option_value (line, "--cache-nonce");
|
||||
if (cache_nonce)
|
||||
{
|
||||
for (; *line && !spacep (line); line++)
|
||||
;
|
||||
if (*line)
|
||||
*line++ = '\0';
|
||||
cache_nonce = xtrystrdup (cache_nonce);
|
||||
if (!cache_nonce)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
line = skip_options (line);
|
||||
|
||||
if (!ctrl->server_local->export_key)
|
||||
{
|
||||
@ -1685,8 +1728,11 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Get the key from the file. With the openpgp flag we also ask for
|
||||
the passphrase so that we can use it to re-encrypt it. */
|
||||
err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
|
||||
NULL, CACHE_MODE_IGNORE, NULL, &s_skey);
|
||||
NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
|
||||
openpgp ? &passphrase : NULL);
|
||||
if (err)
|
||||
goto leave;
|
||||
if (!s_skey)
|
||||
@ -1698,7 +1744,32 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
|
||||
if (openpgp)
|
||||
{
|
||||
/* The openpgp option changes the key format into the OpenPGP
|
||||
key transfer format. The result is already a padded
|
||||
canonical S-expression. */
|
||||
if (!passphrase)
|
||||
{
|
||||
int fully_canceled;
|
||||
err = agent_ask_new_passphrase
|
||||
(ctrl, _("This key (or subkey) is not protected with a passphrase."
|
||||
" Please enter a new passphrase to export it."),
|
||||
&passphrase, &fully_canceled);
|
||||
if (err)
|
||||
{
|
||||
if (fully_canceled)
|
||||
err = gpg_error (GPG_ERR_FULLY_CANCELED);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert into a canonical S-expression and wrap that. */
|
||||
err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
|
||||
}
|
||||
if (err)
|
||||
goto leave;
|
||||
gcry_sexp_release (s_skey);
|
||||
@ -1735,12 +1806,18 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
leave:
|
||||
xfree (passphrase);
|
||||
xfree (wrappedkey);
|
||||
gcry_cipher_close (cipherhd);
|
||||
xfree (key);
|
||||
gcry_sexp_release (s_skey);
|
||||
xfree (ctrl->server_local->keydesc);
|
||||
ctrl->server_local->keydesc = NULL;
|
||||
|
||||
/* Not all users of gpg-agent know about fully cancled; thus we map
|
||||
it back unless we know that it is okay. */
|
||||
if (!openpgp && gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
|
||||
err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);
|
||||
return leave_cmd (ctx, err);
|
||||
}
|
||||
|
||||
|
@ -525,10 +525,10 @@ try_do_unprotect_cb (struct pin_entry_info_s *pi)
|
||||
pointed to by GRIP. On error NULL is stored at all return
|
||||
arguments. */
|
||||
gpg_error_t
|
||||
convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||
unsigned char *grip, const char *prompt,
|
||||
const char *cache_nonce,
|
||||
unsigned char **r_key, char **r_passphrase)
|
||||
convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||
unsigned char *grip, const char *prompt,
|
||||
const char *cache_nonce,
|
||||
unsigned char **r_key, char **r_passphrase)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_sexp_t top_list;
|
||||
@ -779,7 +779,7 @@ convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||
err = try_do_unprotect_cb (pi);
|
||||
}
|
||||
if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
|
||||
err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
|
||||
err = agent_askpin (ctrl, prompt, NULL, NULL, pi, NULL);
|
||||
skeyidx = pi_arg.skeyidx;
|
||||
if (!err)
|
||||
{
|
||||
@ -824,4 +824,267 @@ convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
key_from_sexp (gcry_sexp_t sexp, const char *elems, gcry_mpi_t *array)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
gcry_sexp_t l2;
|
||||
int idx;
|
||||
|
||||
for (idx=0; *elems; elems++, idx++)
|
||||
{
|
||||
l2 = gcry_sexp_find_token (sexp, elems, 1);
|
||||
if (!l2)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_NO_OBJ); /* Required parameter not found. */
|
||||
goto leave;
|
||||
}
|
||||
array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||
gcry_sexp_release (l2);
|
||||
if (!array[idx])
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_OBJ); /* Required parameter invalid. */
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
if (err)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < idx; i++)
|
||||
{
|
||||
gcry_mpi_release (array[i]);
|
||||
array[i] = NULL;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Given an ARRAY of mpis with the key parameters, protect the secret
|
||||
parameters in that array and replace them by one opaque encoded
|
||||
mpi. NPKEY is the number of public key parameters and NSKEY is
|
||||
the number of secret key parameters (including the public ones).
|
||||
On success the array will have NPKEY+1 elements. */
|
||||
static gpg_error_t
|
||||
apply_protection (gcry_mpi_t *array, int npkey, int nskey,
|
||||
const char *passphrase,
|
||||
int protect_algo, void *protect_iv, size_t protect_ivlen,
|
||||
int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int i, j;
|
||||
gcry_cipher_hd_t cipherhd;
|
||||
unsigned char *bufarr[10];
|
||||
size_t narr[10];
|
||||
unsigned int nbits[10];
|
||||
int ndata;
|
||||
unsigned char *p, *data;
|
||||
|
||||
assert (npkey < nskey);
|
||||
assert (nskey < DIM (bufarr));
|
||||
|
||||
/* Collect only the secret key parameters into BUFARR et al and
|
||||
compute the required size of the data buffer. */
|
||||
ndata = 20; /* Space for the SHA-1 checksum. */
|
||||
for (i = npkey, j = 0; i < nskey; i++, j++ )
|
||||
{
|
||||
err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j, narr+j, array[i]);
|
||||
if (err)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
for (i = 0; i < j; i++)
|
||||
xfree (bufarr[i]);
|
||||
return err;
|
||||
}
|
||||
nbits[j] = gcry_mpi_get_nbits (array[i]);
|
||||
ndata += 2 + narr[j];
|
||||
}
|
||||
|
||||
/* Allocate data buffer and stuff it with the secret key parameters. */
|
||||
data = xtrymalloc_secure (ndata);
|
||||
if (!data)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
for (i = 0; i < (nskey-npkey); i++ )
|
||||
xfree (bufarr[i]);
|
||||
return err;
|
||||
}
|
||||
p = data;
|
||||
for (i = 0; i < (nskey-npkey); i++ )
|
||||
{
|
||||
*p++ = nbits[i] >> 8 ;
|
||||
*p++ = nbits[i];
|
||||
memcpy (p, bufarr[i], narr[i]);
|
||||
p += narr[i];
|
||||
xfree (bufarr[i]);
|
||||
bufarr[i] = NULL;
|
||||
}
|
||||
assert (p == data + ndata - 20);
|
||||
|
||||
/* Append a hash of the secret key parameters. */
|
||||
gcry_md_hash_buffer (GCRY_MD_SHA1, p, data, ndata - 20);
|
||||
|
||||
/* Encrypt it. */
|
||||
err = gcry_cipher_open (&cipherhd, protect_algo,
|
||||
GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
|
||||
if (!err)
|
||||
err = hash_passphrase_and_set_key (passphrase, cipherhd, protect_algo,
|
||||
s2k_mode, s2k_algo, s2k_salt, s2k_count);
|
||||
if (!err)
|
||||
err = gcry_cipher_setiv (cipherhd, protect_iv, protect_ivlen);
|
||||
if (!err)
|
||||
err = gcry_cipher_encrypt (cipherhd, data, ndata, NULL, 0);
|
||||
gcry_cipher_close (cipherhd);
|
||||
if (err)
|
||||
{
|
||||
xfree (data);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Replace the secret key parameters in the array by one opaque value. */
|
||||
for (i = npkey; i < nskey; i++ )
|
||||
{
|
||||
gcry_mpi_release (array[i]);
|
||||
array[i] = NULL;
|
||||
}
|
||||
array[npkey] = gcry_mpi_set_opaque (NULL, data, ndata*8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Convert our key S_KEY into an OpenPGP key transfer format. On
|
||||
success a canonical encoded S-expression is stored at R_TRANSFERKEY
|
||||
and its length at R_TRANSFERKEYLEN; this S-expression is also
|
||||
padded to a multiple of 64 bits. */
|
||||
gpg_error_t
|
||||
convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
|
||||
unsigned char **r_transferkey, size_t *r_transferkeylen)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_sexp_t list, l2;
|
||||
char *name;
|
||||
int algo;
|
||||
const char *algoname;
|
||||
const char *elems;
|
||||
int npkey, nskey;
|
||||
gcry_mpi_t array[10];
|
||||
char protect_iv[16];
|
||||
char salt[8];
|
||||
unsigned long s2k_count;
|
||||
int i, j;
|
||||
|
||||
(void)ctrl;
|
||||
|
||||
*r_transferkey = NULL;
|
||||
|
||||
for (i=0; i < DIM (array); i++)
|
||||
array[i] = NULL;
|
||||
|
||||
list = gcry_sexp_find_token (s_key, "private-key", 0);
|
||||
if (!list)
|
||||
return gpg_error (GPG_ERR_NO_OBJ); /* Does not contain a key object. */
|
||||
l2 = gcry_sexp_cadr (list);
|
||||
gcry_sexp_release (list);
|
||||
list = l2;
|
||||
name = gcry_sexp_nth_string (list, 0);
|
||||
if (!name)
|
||||
{
|
||||
gcry_sexp_release (list);
|
||||
return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
|
||||
}
|
||||
|
||||
algo = gcry_pk_map_name (name);
|
||||
xfree (name);
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_PK_RSA: algoname = "rsa"; npkey = 2; elems = "nedpqu"; break;
|
||||
case GCRY_PK_ELG: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
|
||||
case GCRY_PK_ELG_E: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
|
||||
case GCRY_PK_DSA: algoname = "dsa"; npkey = 4; elems = "pqgyx"; break;
|
||||
case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break;
|
||||
default: algoname = ""; npkey = 0; elems = NULL; break;
|
||||
}
|
||||
assert (!elems || strlen (elems) < DIM (array) );
|
||||
nskey = elems? strlen (elems) : 0;
|
||||
|
||||
if (!elems)
|
||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||
else
|
||||
err = key_from_sexp (list, elems, array);
|
||||
gcry_sexp_release (list);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gcry_create_nonce (protect_iv, sizeof protect_iv);
|
||||
gcry_create_nonce (salt, sizeof salt);
|
||||
s2k_count = get_standard_s2k_count ();
|
||||
err = apply_protection (array, npkey, nskey, passphrase,
|
||||
GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
|
||||
3, GCRY_MD_SHA1, salt, s2k_count);
|
||||
/* Turn it into the transfer key S-expression. Note that we always
|
||||
return a protected key. */
|
||||
if (!err)
|
||||
{
|
||||
char countbuf[35];
|
||||
membuf_t mbuf;
|
||||
void *format_args_buf_ptr[1];
|
||||
int format_args_buf_int[1];
|
||||
void *format_args[10+2];
|
||||
size_t n;
|
||||
gcry_sexp_t tmpkey, tmpsexp;
|
||||
|
||||
snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
|
||||
|
||||
init_membuf (&mbuf, 50);
|
||||
put_membuf_str (&mbuf, "(skey");
|
||||
for (i=j=0; i < npkey; i++)
|
||||
{
|
||||
put_membuf_str (&mbuf, " _ %m");
|
||||
format_args[j++] = array + i;
|
||||
}
|
||||
put_membuf_str (&mbuf, " e %b");
|
||||
format_args_buf_ptr[0] = gcry_mpi_get_opaque (array[npkey], &n);
|
||||
format_args_buf_int[0] = (n+7)/8;
|
||||
format_args[j++] = format_args_buf_int;
|
||||
format_args[j++] = format_args_buf_ptr;
|
||||
put_membuf_str (&mbuf, ")\n");
|
||||
put_membuf (&mbuf, "", 1);
|
||||
|
||||
tmpkey = NULL;
|
||||
{
|
||||
char *format = get_membuf (&mbuf, NULL);
|
||||
if (!format)
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args);
|
||||
xfree (format);
|
||||
}
|
||||
if (!err)
|
||||
err = gcry_sexp_build (&tmpsexp, NULL,
|
||||
"(openpgp-private-key\n"
|
||||
" (version 1:4)\n"
|
||||
" (algo %s)\n"
|
||||
" %S\n"
|
||||
" (protection sha1 aes %b 1:3 sha1 %b %s))\n",
|
||||
algoname,
|
||||
tmpkey,
|
||||
(int)sizeof protect_iv, protect_iv,
|
||||
(int)sizeof salt, salt,
|
||||
countbuf);
|
||||
gcry_sexp_release (tmpkey);
|
||||
if (!err)
|
||||
err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen);
|
||||
gcry_sexp_release (tmpsexp);
|
||||
}
|
||||
|
||||
for (i=0; i < DIM (array); i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,14 @@
|
||||
#ifndef GNUPG_AGENT_CVT_OPENPGP_H
|
||||
#define GNUPG_AGENT_CVT_OPENPGP_H
|
||||
|
||||
gpg_error_t convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||
unsigned char *grip, const char *prompt,
|
||||
const char *cache_nonce,
|
||||
unsigned char **r_key, char **r_passphrase);
|
||||
gpg_error_t convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||
unsigned char *grip, const char *prompt,
|
||||
const char *cache_nonce,
|
||||
unsigned char **r_key, char **r_passphrase);
|
||||
|
||||
gpg_error_t convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key,
|
||||
const char *passphrase,
|
||||
unsigned char **r_transferkey,
|
||||
size_t *r_transferkeylen);
|
||||
|
||||
#endif /*GNUPG_AGENT_CVT_OPENPGP_H*/
|
||||
|
@ -266,7 +266,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
||||
|
||||
if (any_flags)
|
||||
{
|
||||
rc = agent_askpin (ctrl, info, prompt, again_text, pi);
|
||||
rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL);
|
||||
again_text = NULL;
|
||||
if (!rc && newpin)
|
||||
{
|
||||
@ -288,7 +288,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
||||
is_puk?
|
||||
_("Repeat this PUK"):
|
||||
_("Repeat this PIN")),
|
||||
prompt, NULL, pi2);
|
||||
prompt, NULL, pi2, NULL);
|
||||
if (!rc && strcmp (pi->pin, pi2->pin))
|
||||
{
|
||||
again_text = (resetcode?
|
||||
@ -312,7 +312,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
||||
info? info:"",
|
||||
info? "')":"") < 0)
|
||||
desc = NULL;
|
||||
rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi);
|
||||
rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL);
|
||||
xfree (desc);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ agent_write_private_key (const unsigned char *grip,
|
||||
}
|
||||
|
||||
|
||||
/* Callback function to try the unprotection from the passpharse query
|
||||
/* Callback function to try the unprotection from the passphrase query
|
||||
code. */
|
||||
static int
|
||||
try_unprotect_cb (struct pin_entry_info_s *pi)
|
||||
@ -273,11 +273,16 @@ modify_description (const char *in, const char *comment, char **result)
|
||||
should be the hex encoded keygrip of that key to be used with the
|
||||
caching mechanism. DESC_TEXT may be set to override the default
|
||||
description used for the pinentry. If LOOKUP_TTL is given this
|
||||
function is used to lookup the default ttl. */
|
||||
function is used to lookup the default ttl. If R_PASSPHRASE is not
|
||||
NULL, the function succeeded and the key was protected the used
|
||||
passphrase (entered or from the cache) is stored there; if not NULL
|
||||
will be stored. The caller needs to free the returned
|
||||
passphrase. */
|
||||
static int
|
||||
unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||
unsigned char **keybuf, const unsigned char *grip,
|
||||
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
|
||||
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
|
||||
char **r_passphrase)
|
||||
{
|
||||
struct pin_entry_info_s *pi;
|
||||
struct try_unprotect_arg_s arg;
|
||||
@ -285,6 +290,10 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||
unsigned char *result;
|
||||
size_t resultlen;
|
||||
char hexgrip[40+1];
|
||||
int fully_canceled;
|
||||
|
||||
if (r_passphrase)
|
||||
*r_passphrase = NULL;
|
||||
|
||||
bin2hex (grip, 20, hexgrip);
|
||||
|
||||
@ -297,13 +306,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||
if (pw)
|
||||
{
|
||||
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
|
||||
xfree (pw);
|
||||
if (!rc)
|
||||
{
|
||||
if (r_passphrase)
|
||||
*r_passphrase = pw;
|
||||
else
|
||||
xfree (pw);
|
||||
xfree (*keybuf);
|
||||
*keybuf = result;
|
||||
return 0;
|
||||
}
|
||||
xfree (pw);
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,13 +331,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||
if (pw)
|
||||
{
|
||||
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
|
||||
xfree (pw);
|
||||
if (!rc)
|
||||
{
|
||||
if (r_passphrase)
|
||||
*r_passphrase = pw;
|
||||
else
|
||||
xfree (pw);
|
||||
xfree (*keybuf);
|
||||
*keybuf = result;
|
||||
return 0;
|
||||
}
|
||||
xfree (pw);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
@ -366,7 +383,9 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||
arg.change_required = 0;
|
||||
pi->check_cb_arg = &arg;
|
||||
|
||||
rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
|
||||
rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, &fully_canceled);
|
||||
if (gpg_err_code (rc) == GPG_ERR_CANCELED && fully_canceled)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
|
||||
if (!rc)
|
||||
{
|
||||
assert (arg.unprotected_key);
|
||||
@ -400,8 +419,13 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
agent_put_cache (hexgrip, cache_mode, pi->pin,
|
||||
lookup_ttl? lookup_ttl (hexgrip) : 0);
|
||||
else
|
||||
{
|
||||
agent_put_cache (hexgrip, cache_mode, pi->pin,
|
||||
lookup_ttl? lookup_ttl (hexgrip) : 0);
|
||||
if (r_passphrase && *pi->pin)
|
||||
*r_passphrase = xtrystrdup (pi->pin);
|
||||
}
|
||||
xfree (*keybuf);
|
||||
*keybuf = arg.unprotected_key;
|
||||
}
|
||||
@ -501,13 +525,17 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result)
|
||||
not simply pass the TTL value because the value is only needed if
|
||||
an unprotect action was needed and looking up the TTL may have some
|
||||
overhead (e.g. scanning the sshcontrol file). If a CACHE_NONCE is
|
||||
given that cache item is first tried to get a passphrase. */
|
||||
given that cache item is first tried to get a passphrase. If
|
||||
R_PASSPHRASE is not NULL, the function succeeded and the key was
|
||||
protected the used passphrase (entered or from the cache) is stored
|
||||
there; if not NULL will be stored. The caller needs to free the
|
||||
returned passphrase. */
|
||||
gpg_error_t
|
||||
agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
const char *desc_text,
|
||||
const unsigned char *grip, unsigned char **shadow_info,
|
||||
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
|
||||
gcry_sexp_t *result)
|
||||
gcry_sexp_t *result, char **r_passphrase)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf;
|
||||
@ -518,6 +546,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
*result = NULL;
|
||||
if (shadow_info)
|
||||
*shadow_info = NULL;
|
||||
if (r_passphrase)
|
||||
*r_passphrase = NULL;
|
||||
|
||||
rc = read_key_file (grip, &s_skey);
|
||||
if (rc)
|
||||
@ -579,7 +609,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
if (!rc)
|
||||
{
|
||||
rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
|
||||
cache_mode, lookup_ttl);
|
||||
cache_mode, lookup_ttl, r_passphrase);
|
||||
if (rc)
|
||||
log_error ("failed to unprotect the secret key: %s\n",
|
||||
gpg_strerror (rc));
|
||||
@ -626,6 +656,11 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
if (rc || got_shadow_info)
|
||||
{
|
||||
xfree (buf);
|
||||
if (r_passphrase)
|
||||
{
|
||||
xfree (*r_passphrase);
|
||||
*r_passphrase = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -637,6 +672,11 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||
{
|
||||
log_error ("failed to build S-Exp (off=%u): %s\n",
|
||||
(unsigned int)erroff, gpg_strerror (rc));
|
||||
if (r_passphrase)
|
||||
{
|
||||
xfree (*r_passphrase);
|
||||
*r_passphrase = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -290,10 +290,12 @@ reenter_compare_cb (struct pin_entry_info_s *pi)
|
||||
function returns 0 and store the passphrase at R_PASSPHRASE; if the
|
||||
user opted not to use a passphrase NULL will be stored there. The
|
||||
user needs to free the returned string. In case of an error and
|
||||
error code is returned and NULL stored at R_PASSPHRASE. */
|
||||
error code is returned and NULL stored at R_PASSPHRASE. If
|
||||
R_CANCEL_ALL is not NULL and the user canceled by directly closing
|
||||
the window true will be stored at this address. */
|
||||
gpg_error_t
|
||||
agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||
char **r_passphrase)
|
||||
char **r_passphrase, int *r_cancel_all)
|
||||
{
|
||||
gpg_error_t err;
|
||||
const char *text1 = prompt;
|
||||
@ -314,7 +316,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||
pi2->check_cb_arg = pi->pin;
|
||||
|
||||
next_try:
|
||||
err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
|
||||
err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, r_cancel_all);
|
||||
initial_errtext = NULL;
|
||||
if (!err)
|
||||
{
|
||||
@ -327,7 +329,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||
/* Unless the passphrase is empty, ask to confirm it. */
|
||||
if (pi->pin && *pi->pin)
|
||||
{
|
||||
err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
|
||||
err = agent_askpin (ctrl, text2, NULL, NULL, pi2, NULL);
|
||||
if (err == -1)
|
||||
{ /* The re-entered one did not match and the user did not
|
||||
hit cancel. */
|
||||
@ -379,7 +381,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
||||
rc = agent_ask_new_passphrase (ctrl,
|
||||
_("Please enter the passphrase to%0A"
|
||||
"to protect your new key"),
|
||||
&passphrase);
|
||||
&passphrase, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -471,7 +473,7 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey)
|
||||
|
||||
rc = agent_ask_new_passphrase (ctrl,
|
||||
_("Please enter the new passphrase"),
|
||||
&passphrase);
|
||||
&passphrase, NULL);
|
||||
if (!rc)
|
||||
{
|
||||
rc = store_key (s_skey, passphrase, 1);
|
||||
|
@ -440,6 +440,11 @@ remove_socket (char *name)
|
||||
static void
|
||||
cleanup (void)
|
||||
{
|
||||
static int done;
|
||||
|
||||
if (done)
|
||||
return;
|
||||
done = 1;
|
||||
deinitialize_module_cache ();
|
||||
remove_socket (socket_name);
|
||||
remove_socket (socket_name_ssh);
|
||||
@ -724,6 +729,12 @@ main (int argc, char **argv )
|
||||
if( parse_debug )
|
||||
log_info (_("NOTE: no default option file `%s'\n"),
|
||||
configname );
|
||||
/* Save the default conf file name so that
|
||||
reread_configuration is able to test whether the
|
||||
config file has been created in the meantime. */
|
||||
xfree (config_filename);
|
||||
config_filename = configname;
|
||||
configname = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -811,10 +822,15 @@ main (int argc, char **argv )
|
||||
fclose( configfp );
|
||||
configfp = NULL;
|
||||
/* Keep a copy of the name so that it can be read on SIGHUP. */
|
||||
config_filename = configname;
|
||||
if (config_filename != configname)
|
||||
{
|
||||
xfree (config_filename);
|
||||
config_filename = configname;
|
||||
}
|
||||
configname = NULL;
|
||||
goto next_pass;
|
||||
}
|
||||
|
||||
xfree (configname);
|
||||
configname = NULL;
|
||||
if (log_get_errorcount(0))
|
||||
@ -1262,6 +1278,12 @@ void
|
||||
agent_exit (int rc)
|
||||
{
|
||||
/*FIXME: update_random_seed_file();*/
|
||||
|
||||
/* We run our cleanup handler because that may close cipher contexts
|
||||
stored in secure memory and thus this needs to be done before we
|
||||
explicitly terminate secure memory. */
|
||||
cleanup ();
|
||||
|
||||
#if 1
|
||||
/* at this time a bit annoying */
|
||||
if (opt.debug & DBG_MEMSTAT_VALUE)
|
||||
@ -1337,8 +1359,8 @@ reread_configuration (void)
|
||||
fp = fopen (config_filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
log_error (_("option file `%s': %s\n"),
|
||||
config_filename, strerror(errno) );
|
||||
log_info (_("option file `%s': %s\n"),
|
||||
config_filename, strerror(errno) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,8 @@ the ~/.gnupg home directory. This directory is named
|
||||
and should have permissions 700.
|
||||
|
||||
The secret keys are stored in files with a name matching the
|
||||
hexadecimal representation of the keygrip[2].
|
||||
hexadecimal representation of the keygrip[2] and suffixed with ".key".
|
||||
|
||||
|
||||
Unprotected Private Key Format
|
||||
==============================
|
||||
@ -166,21 +167,23 @@ This format is used to transfer keys between gpg and gpg-agent.
|
||||
|
||||
(openpgp-private-key
|
||||
(version V)
|
||||
(protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT)
|
||||
(algo PUBKEYALGO)
|
||||
(skey CSUM c P1 c P2 c P3 ... e PN))
|
||||
(skey _ P1 _ P2 _ P3 ... e PN)
|
||||
(csum n)
|
||||
(protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT))
|
||||
|
||||
|
||||
* V is the packet version number (3 or 4).
|
||||
* PUBKEYALGO is a Libgcrypt algo name
|
||||
* CSUM is the 16 bit checksum as defined by OpenPGP.
|
||||
* P1 .. PN are the parameters; the public parameters are never encrypted
|
||||
the secrect key parameters are encrypted if the "protection" list is
|
||||
given. To make this more explicit each parameter is preceded by a
|
||||
flag "_" for cleartext or "e" for encrypted text.
|
||||
* CSUM is the depreciated 16 bit checksum as defined by OpenPGP. This
|
||||
is an optional element.
|
||||
* If PROTTYPE is "sha1" the new style SHA1 checksum is used if it is "sum"
|
||||
the old 16 bit checksum is used and if it is "none" no protection at
|
||||
all is used.
|
||||
the old 16 bit checksum (above) is used and if it is "none" no
|
||||
protection at all is used.
|
||||
* PROTALGO is a Libgcrypt style cipher algorithm name
|
||||
* IV is the initialization verctor.
|
||||
* S2KMODE is the value from RFC-4880.
|
||||
@ -189,6 +192,105 @@ This format is used to transfer keys between gpg and gpg-agent.
|
||||
* S2KCOUNT is the count value from RFC-4880.
|
||||
|
||||
|
||||
Persistent Passphrase Format
|
||||
============================
|
||||
|
||||
To allow persistent storage of cached passphrases we use a scheme
|
||||
similar to the private-key storage format. This is a master
|
||||
passphrase format where each file may protect several secrets under
|
||||
one master passphrase. It is possible to have several of those files
|
||||
each protected by a dedicated master passphrase. Clear text keywords
|
||||
allow to list the available protected passphrases.
|
||||
|
||||
The name of the files with these protected secrets have this form:
|
||||
pw-<string>.dat. STRING may be an arbitrary string, as a default name
|
||||
for the passphrase storage the name "pw-default.dat" is suggested.
|
||||
|
||||
|
||||
(protected-shared-secret
|
||||
((desc descriptive_text)
|
||||
(key [key_1] (keyword_1 keyword_2 keyword_n))
|
||||
(key [key_2] (keyword_21 keyword_22 keyword_2n))
|
||||
(key [key_n] (keyword_n1 keyword_n2 keyword_nn))
|
||||
(protected mode (parms) encrypted_octet_string)
|
||||
(protected-at <isotimestamp>)
|
||||
)
|
||||
)
|
||||
|
||||
After decryption the encrypted_octet_string yields this S-expression:
|
||||
|
||||
(
|
||||
(
|
||||
(value key_1 value_1)
|
||||
(value key_2 value_2)
|
||||
(value key_n value_n)
|
||||
)
|
||||
(hash sha1 #...[hashvalue]...#)
|
||||
)
|
||||
|
||||
The "descriptive_text" is displayed with the prompt to enter the
|
||||
unprotection passphrase.
|
||||
|
||||
KEY_1 to KEY_N are unique identifiers for the shared secret, for
|
||||
example an URI. In case this information should be kept confidential
|
||||
as well, they may not appear in the unprotected part; however they are
|
||||
mandatory in the encrypted_octet_string. The list of keywords is
|
||||
optional. The oder of the "key" lists and the order of the "value"
|
||||
lists mut match, that is the first "key"-list is associated with the
|
||||
first "value" list in the encrypted_octet_string.
|
||||
|
||||
The protection mode etc. is indentical to the protection mode as
|
||||
decribed for the private key format.
|
||||
|
||||
list of the secret key parameters. The protected-at expression is
|
||||
optional; the isotimestamp is 15 bytes long (e.g. "19610711T172000").
|
||||
|
||||
The "hash" in the encrypted_octet_string is calculated on the
|
||||
concatenation of the key list and value lists: i.e it is required to
|
||||
hash the concatenation of all these lists, including the
|
||||
parenthesis and (if used) the protected-at list.
|
||||
|
||||
Example:
|
||||
|
||||
(protected-shared-secret
|
||||
((desc "List of system passphrases")
|
||||
(key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
|
||||
(key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
|
||||
(key)
|
||||
(protected mode (parms) encrypted_octet_string)
|
||||
(protected-at "20100915T111722")
|
||||
)
|
||||
)
|
||||
|
||||
with "encrypted_octet_string" decoding to:
|
||||
|
||||
(
|
||||
(
|
||||
(value 4:1002 "signal flags at the lock")
|
||||
(value 4:1001 "taocp")
|
||||
(value 1:0 "premature optimization is the root of all evil")
|
||||
)
|
||||
(hash sha1 #0102030405060708091011121314151617181920#)
|
||||
)
|
||||
|
||||
To compute the hash this S-expression (in canoncical format) was
|
||||
hashed:
|
||||
|
||||
((desc "List of system passphrases")
|
||||
(key "uid-1002" ("Knuth" "Donald Ervin Knuth"))
|
||||
(key "uid-1001" ("Dijkstra" "Edsgar Wybe Dijkstra"))
|
||||
(key)
|
||||
(value 4:1002 "signal flags at the lock")
|
||||
(value 4:1001 "taocp")
|
||||
(value 1:0 "premature optimization is the root of all evil")
|
||||
(protected-at "20100915T111722")
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Notes:
|
||||
======
|
||||
|
@ -66,7 +66,9 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
||||
}
|
||||
rc = agent_key_from_file (ctrl, NULL, desc_text,
|
||||
ctrl->keygrip, &shadow_info,
|
||||
CACHE_MODE_NORMAL, NULL, &s_skey);
|
||||
CACHE_MODE_NORMAL, NULL, &s_skey, NULL);
|
||||
if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
if (rc)
|
||||
{
|
||||
if (gpg_err_code (rc) == GPG_ERR_ENOENT)
|
||||
|
@ -255,7 +255,9 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
|
||||
|
||||
rc = agent_key_from_file (ctrl, cache_nonce, desc_text, ctrl->keygrip,
|
||||
&shadow_info, cache_mode, lookup_ttl,
|
||||
&s_skey);
|
||||
&s_skey, NULL);
|
||||
if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to read the secret key\n");
|
||||
|
@ -191,14 +191,16 @@ get_standard_s2k_count (void)
|
||||
|
||||
|
||||
|
||||
/* Calculate the MIC for a private key S-Exp. SHA1HASH should point to
|
||||
a 20 byte buffer. This function is suitable for any algorithms. */
|
||||
/* Calculate the MIC for a private key or shared secret S-expression.
|
||||
SHA1HASH should point to a 20 byte buffer. This function is
|
||||
suitable for all algorithms. */
|
||||
static int
|
||||
calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
|
||||
{
|
||||
const unsigned char *hash_begin, *hash_end;
|
||||
const unsigned char *s;
|
||||
size_t n;
|
||||
int is_shared_secret;
|
||||
|
||||
s = plainkey;
|
||||
if (*s != '(')
|
||||
@ -207,16 +209,23 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
if (!smatch (&s, n, "private-key"))
|
||||
if (smatch (&s, n, "private-key"))
|
||||
is_shared_secret = 0;
|
||||
else if (smatch (&s, n, "shared-secret"))
|
||||
is_shared_secret = 1;
|
||||
else
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
if (*s != '(')
|
||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||
hash_begin = s;
|
||||
s++;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
s += n; /* skip over the algorithm name */
|
||||
if (!is_shared_secret)
|
||||
{
|
||||
s++;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
s += n; /* Skip the algorithm name. */
|
||||
}
|
||||
|
||||
while (*s == '(')
|
||||
{
|
||||
@ -955,7 +964,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
|
||||
xfree (final);
|
||||
return rc;
|
||||
}
|
||||
/* Now remove tha part which is included in the MIC but should not
|
||||
/* Now remove the part which is included in the MIC but should not
|
||||
go into the final thing. */
|
||||
if (cutlen)
|
||||
{
|
||||
|
@ -289,6 +289,13 @@ test_agent_get_shadow_info (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_agent_protect_shared_secret (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
@ -305,6 +312,7 @@ main (int argc, char **argv)
|
||||
test_make_shadow_info ();
|
||||
test_agent_shadow_key ();
|
||||
test_agent_get_shadow_info ();
|
||||
test_agent_protect_shared_secret ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
2010-09-30 Werner Koch <wk@g10code.com>
|
||||
|
||||
* util.h (GPG_ERR_FULLY_CANCELED): Add replacement.
|
||||
|
||||
2010-09-17 Werner Koch <wk@g10code.com>
|
||||
|
||||
* http.c (INADDR_NONE): Provide fallback.
|
||||
* logging.c (INADDR_NONE): Ditto.
|
||||
|
||||
2010-09-16 Werner Koch <wk@g10code.com>
|
||||
|
||||
* util.h: Add GPG_ERR_MISSING_ISSUER_CERT.
|
||||
* status.c (get_inv_recpsgnr_code): Ditto.
|
||||
|
||||
2010-09-13 Werner Koch <wk@g10code.com>
|
||||
|
||||
* homedir.c (gnupg_bindir) [W32CE]: Change to bin/.
|
||||
|
@ -114,6 +114,9 @@ struct srventry
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
#endif
|
||||
#ifndef INADDR_NONE /* Slowaris is missing that. */
|
||||
#define INADDR_NONE ((unsigned long)(-1))
|
||||
#endif /*INADDR_NONE*/
|
||||
|
||||
#define HTTP_PROXY_ENV "http_proxy"
|
||||
#define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
|
||||
|
@ -68,6 +68,9 @@
|
||||
#ifndef EAFNOSUPPORT
|
||||
# define EAFNOSUPPORT EINVAL
|
||||
#endif
|
||||
#ifndef INADDR_NONE /* Slowaris is missing that. */
|
||||
#define INADDR_NONE ((unsigned long)(-1))
|
||||
#endif /*INADDR_NONE*/
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#define sock_close(a) closesocket(a)
|
||||
|
@ -82,7 +82,7 @@ sskip (unsigned char const **buf, int *depth)
|
||||
|
||||
/* Check whether the the string at the address BUF points to matches
|
||||
the token. Return true on match and update BUF to point behind the
|
||||
token. Return false and dont update tha buffer if it does not
|
||||
token. Return false and do not update the buffer if it does not
|
||||
match. */
|
||||
static inline int
|
||||
smatch (unsigned char const **buf, size_t buflen, const char *token)
|
||||
|
@ -58,6 +58,7 @@ get_inv_recpsgnr_code (gpg_error_t err)
|
||||
|
||||
case GPG_ERR_NOT_TRUSTED: errstr = "10"; break;
|
||||
case GPG_ERR_MISSING_CERT: errstr = "11"; break;
|
||||
case GPG_ERR_MISSING_ISSUER_CERT: errstr = "12"; break;
|
||||
default: errstr = "0"; break;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,12 @@
|
||||
#ifndef GPG_ERR_NOT_INITIALIZED
|
||||
#define GPG_ERR_NOT_INITIALIZED 184
|
||||
#endif
|
||||
#ifndef GPG_ERR_MISSING_ISSUER_CERT
|
||||
#define GPG_ERR_MISSING_ISSUER_CERT 185
|
||||
#endif
|
||||
#ifndef GPG_ERR_FULLY_CANCELED
|
||||
#define GPG_ERR_FULLY_CANCELED 198
|
||||
#endif
|
||||
|
||||
|
||||
/* Hash function used with libksba. */
|
||||
|
@ -396,7 +396,7 @@ AH_BOTTOM([
|
||||
# define GNUPG_DEFAULT_HOMEDIR "/gnupg"
|
||||
# endif
|
||||
#elif defined(__VMS)
|
||||
#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
|
||||
#define GNUPG_DEFAULT_HOMEDIR "/SYS$LOGIN/gnupg"
|
||||
#else
|
||||
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
||||
#endif
|
||||
|
@ -1,3 +1,7 @@
|
||||
2010-09-16 Werner Koch <wk@g10code.com>
|
||||
|
||||
* validate.c (validate_cert_chain): Use GPG_ERR_MISSING_ISSUER_CERT.
|
||||
|
||||
2010-08-13 Werner Koch <wk@g10code.com>
|
||||
|
||||
* Makefile.am (dirmngr_SOURCES): Add w32-ldap-help.h.
|
||||
|
@ -623,7 +623,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
|
||||
log_error (_("issuer certificate not found: %s\n"),
|
||||
gpg_strerror (err));
|
||||
/* Use a better understandable error code. */
|
||||
err = gpg_error (GPG_ERR_MISSING_CERT);
|
||||
err = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2010-09-28 Werner Koch <wk@g10code.com>
|
||||
|
||||
* Makefile.am (AM_MAKEINFOFLAGS): Add define gpgtwoone.
|
||||
|
||||
2010-09-28 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* gpg.texi (OpenPGP Options): Clarify that --force-v3-sigs
|
||||
|
@ -586,7 +586,8 @@ more arguments in future versions.
|
||||
8 := "Policy mismatch"
|
||||
9 := "Not a secret key"
|
||||
10 := "Key not trusted"
|
||||
11 := "Missing certificate" (e.g. intermediate or root cert.)
|
||||
11 := "Missing certificate"
|
||||
12 := "Missing issuer certificate"
|
||||
|
||||
Note that for historical reasons the INV_RECP status is also
|
||||
used for gpgsm's SIGNER command where it relates to signer's
|
||||
|
@ -57,9 +57,9 @@ gnupg_TEXINFOS = \
|
||||
|
||||
DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips
|
||||
|
||||
AM_MAKEINFOFLAGS = -I $(srcdir) --css-include=$(srcdir)/texi.css
|
||||
AM_MAKEINFOFLAGS = -I $(srcdir) --css-include=$(srcdir)/texi.css -D gpgtwoone
|
||||
|
||||
YAT2M_OPTIONS = -I $(srcdir) \
|
||||
YAT2M_OPTIONS = -I $(srcdir) -D gpgtwoone \
|
||||
--release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard"
|
||||
|
||||
myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
|
||||
|
@ -194,7 +194,7 @@ or other purposes and don't have a corresponding certificate.
|
||||
@item A root certificate does not verify
|
||||
|
||||
A common problem is that the root certificate misses the required
|
||||
basicConstrains attribute and thus @command{gpgsm} rejects this
|
||||
basicConstraints attribute and thus @command{gpgsm} rejects this
|
||||
certificate. An error message indicating ``no value'' is a sign for
|
||||
such a certificate. You may use the @code{relax} flag in
|
||||
@file{trustlist.txt} to accept the certificate anyway. Note that the
|
||||
|
@ -317,8 +317,12 @@ should in general not be used to avoid X-sniffing attacks.
|
||||
|
||||
@item --log-file @var{file}
|
||||
@opindex log-file
|
||||
Append all logging output to @var{file}. This is very helpful in
|
||||
seeing what the agent actually does.
|
||||
Append all logging output to @var{file}. This is very helpful in seeing
|
||||
what the agent actually does. If neither a log file nor a log file
|
||||
descriptor has been set on a Windows platform, the Registry entry
|
||||
@var{HKCU\Software\GNU\GnuPG:DefaultLogFile}, if set, is used to specify
|
||||
the logging output.
|
||||
|
||||
|
||||
@anchor{option --allow-mark-trusted}
|
||||
@item --allow-mark-trusted
|
||||
@ -1148,11 +1152,13 @@ This can be used to see whether a secret key is available. It does
|
||||
not return any information on whether the key is somehow protected.
|
||||
|
||||
@example
|
||||
HAVEKEY @var{keygrip}
|
||||
HAVEKEY @var{keygrips}
|
||||
@end example
|
||||
|
||||
The Agent answers either with OK or @code{No_Secret_Key} (208). The
|
||||
caller may want to check for other error codes as well.
|
||||
The agent answers either with OK or @code{No_Secret_Key} (208). The
|
||||
caller may want to check for other error codes as well. More than one
|
||||
keygrip may be given. In this case the command returns success if at
|
||||
least one of the keygrips corresponds to an available secret key.
|
||||
|
||||
|
||||
@node Agent LEARN
|
||||
|
32
doc/gpg.texi
32
doc/gpg.texi
@ -3,6 +3,11 @@
|
||||
@c This is part of the GnuPG manual.
|
||||
@c For copying conditions, see the file gnupg.texi.
|
||||
|
||||
@c Note that we use this texinfo file for all versions of GnuPG: 1.4.x,
|
||||
@c 2.0 and 2.1. The macro "gpgone" controls parts which are only valid
|
||||
@c for GnuPG 1.4, the macro "gpgtwoone" controls parts which are only
|
||||
@c valid for GnupG 2.1 and later.
|
||||
|
||||
@node Invoking GPG
|
||||
@chapter Invoking GPG
|
||||
@cindex GPG command options
|
||||
@ -68,18 +73,19 @@ implementation.
|
||||
|
||||
@ifset gpgone
|
||||
This is the standalone version of @command{gpg}. For desktop use you
|
||||
should consider using @command{gpg2}.
|
||||
should consider using @command{gpg2} @footnote{On some platforms gpg2 is
|
||||
installed under the name @command{gpg}}.
|
||||
@end ifset
|
||||
|
||||
@ifclear gpgone
|
||||
In contrast to the standalone version @command{gpg}, which is more
|
||||
suited for server and embedded platforms, this version is installed
|
||||
under the name @command{gpg2} and more targeted to the desktop as it
|
||||
requires several other modules to be installed. The standalone version
|
||||
will be kept maintained and it is possible to install both versions on
|
||||
the same system. If you need to use different configuration files, you
|
||||
should make use of something like @file{gpg.conf-2} instead of just
|
||||
@file{gpg.conf}.
|
||||
suited for server and embedded platforms, this version is commonly
|
||||
installed under the name @command{gpg2} and more targeted to the desktop
|
||||
as it requires several other modules to be installed. The standalone
|
||||
version will be kept maintained and it is possible to install both
|
||||
versions on the same system. If you need to use different configuration
|
||||
files, you should make use of something like @file{gpg.conf-2} instead
|
||||
of just @file{gpg.conf}.
|
||||
@end ifclear
|
||||
|
||||
@manpause
|
||||
@ -415,8 +421,10 @@ normally not very useful and a security risk. The second form of the
|
||||
command has the special property to render the secret part of the
|
||||
primary key useless; this is a GNU extension to OpenPGP and other
|
||||
implementations can not be expected to successfully import such a key.
|
||||
@ifclear gpgtwoone
|
||||
See the option @option{--simple-sk-checksum} if you want to import such
|
||||
an exported key with an older OpenPGP implementation.
|
||||
@end ifclear
|
||||
|
||||
@item --import
|
||||
@itemx --fast-import
|
||||
@ -1550,6 +1558,7 @@ key signer (defaults to 3)
|
||||
@item --max-cert-depth @code{n}
|
||||
Maximum depth of a certification chain (default is 5).
|
||||
|
||||
@ifclear gpgtwoone
|
||||
@item --simple-sk-checksum
|
||||
Secret keys are integrity protected by using a SHA-1 checksum. This
|
||||
method is part of the upcoming enhanced OpenPGP specification but
|
||||
@ -1560,6 +1569,7 @@ a security risk. Note that using this option only takes effect when
|
||||
the secret key is encrypted - the simplest way to make this happen is
|
||||
to change the passphrase on the key (even changing it to the same
|
||||
value is acceptable).
|
||||
@end ifclear
|
||||
|
||||
@item --no-sig-cache
|
||||
Do not cache the verification status of key signatures.
|
||||
@ -1884,11 +1894,17 @@ program that does not accept attribute user IDs. Defaults to yes.
|
||||
Include designated revoker information that was marked as
|
||||
"sensitive". Defaults to no.
|
||||
|
||||
@c Since GnuPG 2.1 gpg-agent manages the secret key and thus the
|
||||
@c export-reset-subkey-passwd hack is not anymore justified. Such use
|
||||
@c cases need to be implemented using a specialized secret key export
|
||||
@c tool.
|
||||
@ifclear gpgtwoone
|
||||
@item export-reset-subkey-passwd
|
||||
When using the @option{--export-secret-subkeys} command, this option resets
|
||||
the passphrases for all exported subkeys to empty. This is useful
|
||||
when the exported subkey is to be used on an unattended machine where
|
||||
a passphrase doesn't necessarily make sense. Defaults to no.
|
||||
@end ifclear
|
||||
|
||||
@item export-clean
|
||||
Compact (remove all signatures from) user IDs on the key being
|
||||
|
@ -31,7 +31,7 @@
|
||||
@command{gpgsm} is a tool similar to @command{gpg} to provide digital
|
||||
encryption and signing services on X.509 certificates and the CMS
|
||||
protocol. It is mainly used as a backend for S/MIME mail processing.
|
||||
@command{gpgsm} includes a full features certificate management and
|
||||
@command{gpgsm} includes a full featured certificate management and
|
||||
complies with all rules defined for the German Sphinx project.
|
||||
|
||||
@manpause
|
||||
@ -286,7 +286,7 @@ smartcard is not yet supported.
|
||||
@node GPGSM Options
|
||||
@section Option Summary
|
||||
|
||||
@command{GPGSM} comes features a bunch of options to control the exact behaviour
|
||||
@command{GPGSM} features a bunch of options to control the exact behaviour
|
||||
and to change the default configuration.
|
||||
|
||||
@menu
|
||||
@ -566,10 +566,9 @@ certificate.
|
||||
@item --include-certs @var{n}
|
||||
@opindex include-certs
|
||||
Using @var{n} of -2 includes all certificate except for the root cert,
|
||||
-1 includes all certs, 0 does not include any certs, 1 includes only
|
||||
the signers cert (this is the default) and all other positive
|
||||
values include up to @var{n} certificates starting with the signer cert.
|
||||
The default is -2.
|
||||
-1 includes all certs, 0 does not include any certs, 1 includes only the
|
||||
signers cert and all other positive values include up to @var{n}
|
||||
certificates starting with the signer cert. The default is -2.
|
||||
|
||||
@item --cipher-algo @var{oid}
|
||||
@opindex cipher-algo
|
||||
|
@ -1,3 +1,67 @@
|
||||
2010-10-01 Werner Koch <wk@g10code.com>
|
||||
|
||||
* export.c (do_export_stream): Rewrite to take the secret keys
|
||||
from the agent.
|
||||
(canon_pubkey_algo, transfer_format_to_openpgp): New.
|
||||
|
||||
2010-09-29 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keygen.c (key_from_sexp): Fix memory leak in the error case.
|
||||
|
||||
* call-agent.c (agent_export_key): New.
|
||||
|
||||
2010-09-29 Werner Koch <wk@g10code.com>
|
||||
|
||||
* build-packet.c (build_packet): Fix up the pkttype.
|
||||
|
||||
* keyid.c (keystr_with_sub): Make SUB_KID optional.
|
||||
(keystr_from_pk_with_sub): Ditto.
|
||||
|
||||
* call-agent.c (agent_scd_pksign): Add missing space.
|
||||
|
||||
* mainproc.c (struct mainproc_context): Add field CTRL.
|
||||
(proc_packets): Add arg CTRL. Change all callers.
|
||||
(proc_signature_packets, proc_signature_packets_by_fd)
|
||||
(proc_encryption_packets): Add arg CTRL. Change all callers.
|
||||
* compress.c (handle_compressed): Ditto.
|
||||
* getkey.c (get_pubkey_byname): Ditto.
|
||||
* keyserver.c (keyserver_spawn, keyserver_work): Ditto.
|
||||
(show_prompt, keyserver_export, keyserver_import)
|
||||
(keyserver_import_fprint, keyserver_import_keyid)
|
||||
(keyserver_refresh, keyserver_search, keyserver_fetch)
|
||||
(keyserver_import_name, keyserver_search_prompt)
|
||||
(keyserver_import_pka, keyserver_import_cert): Ditto.
|
||||
callers.
|
||||
* verify.c (verify_signatures, verify_files): Ditto.
|
||||
* sign.c (sign_file): Ditto.
|
||||
* encrypt.c (encrypt_crypt, encrypt_crypt_files): Ditto.
|
||||
* pkclist.c (find_and_check_key, build_pk_list): Ditto.
|
||||
* keylist.c (locate_one, public_key_list, secret_key_list): Ditto.
|
||||
* card-util.c (fetch_url, card_edit): Ditto.
|
||||
* import.c (check_prefs, import_one, revocation_present): Ditto.
|
||||
* keyedit.c (menu_addrevoker, keyedit_menu): Ditto.
|
||||
* decrypt-data.c (decrypt_data): Ditto.
|
||||
* decrypt.c (decrypt_message, decrypt_messages)
|
||||
(decrypt_message_fd): Ditto.
|
||||
* gpgv.c (main): Add CTRL structure.
|
||||
|
||||
2010-09-28 Werner Koch <wk@g10code.com>
|
||||
|
||||
* options.h (struct opt): Remove SIMPLE_SK_CHECKSUM.
|
||||
|
||||
* export.c (parse_export_options): Remove option
|
||||
export-resert-subkey-passwd.
|
||||
(do_export_stream, do_export, export_pubkeys)
|
||||
(export_pubkeys_stream, export_seckeys, export_secsubkeys): Add
|
||||
arg CTRL. Change all callers.
|
||||
|
||||
* call-agent.c (hash_algo_option): New.
|
||||
(agent_scd_pksign): Use it.
|
||||
|
||||
2010-09-17 Werner Koch <wk@g10code.com>
|
||||
|
||||
* call-agent.c (agent_probe_any_secret_key): New.
|
||||
|
||||
2010-09-28 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* options.skel: Make the example for force-v3-sigs match
|
||||
|
@ -26,10 +26,10 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "status.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "i18n.h"
|
||||
#include "options.h"
|
||||
@ -71,8 +71,16 @@ build_packet( IOBUF out, PACKET *pkt )
|
||||
log_debug("build_packet() type=%d\n", pkt->pkttype );
|
||||
assert( pkt->pkt.generic );
|
||||
|
||||
switch( (pkttype = pkt->pkttype) )
|
||||
switch ((pkttype = pkt->pkttype))
|
||||
{
|
||||
case PKT_PUBLIC_KEY:
|
||||
if (pkt->pkt.public_key->seckey_info)
|
||||
pkttype = PKT_SECRET_KEY;
|
||||
break;
|
||||
case PKT_PUBLIC_SUBKEY:
|
||||
if (pkt->pkt.public_key->seckey_info)
|
||||
pkttype = PKT_SECRET_SUBKEY;
|
||||
break;
|
||||
case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
|
||||
case PKT_ENCRYPTED:
|
||||
case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
|
||||
|
140
g10/call-agent.c
140
g10/call-agent.c
@ -902,6 +902,26 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Helper returning a command option to describe the used hash
|
||||
algorithm. See scd/command.c:cmd_pksign. */
|
||||
static const char *
|
||||
hash_algo_option (int algo)
|
||||
{
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_MD_RMD160: return "--hash=rmd160";
|
||||
case GCRY_MD_SHA1 : return "--hash=sha1";
|
||||
case GCRY_MD_SHA224: return "--hash=sha224";
|
||||
case GCRY_MD_SHA256: return "--hash=sha256";
|
||||
case GCRY_MD_SHA384: return "--hash=sha384";
|
||||
case GCRY_MD_SHA512: return "--hash=sha512";
|
||||
case GCRY_MD_MD5 : return "--hash=md5";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Send a sign command to the scdaemon via gpg-agent's pass thru
|
||||
mechanism. */
|
||||
int
|
||||
@ -942,14 +962,11 @@ agent_scd_pksign (const char *serialno, int hashalgo,
|
||||
return rc;
|
||||
|
||||
init_membuf (&data, 1024);
|
||||
#if 0
|
||||
if (!hashalgo) /* Temporary test hack. */
|
||||
snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
|
||||
else
|
||||
#endif
|
||||
snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
|
||||
hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
|
||||
serialno);
|
||||
/* if (!hashalgo) /\* Temporary test hack. *\/ */
|
||||
/* snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); */
|
||||
/* else */
|
||||
snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s",
|
||||
hash_algo_option (hashalgo), serialno);
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
|
||||
default_inq_cb, NULL, NULL, NULL);
|
||||
@ -1325,6 +1342,57 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Ask the agent whether a secret key is availabale for any of the
|
||||
keys (primary or sub) in KEYBLOCK. Returns 0 if available. */
|
||||
gpg_error_t
|
||||
agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
|
||||
{
|
||||
gpg_error_t err;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
char *p;
|
||||
kbnode_t kbctx, node;
|
||||
int nkeys;
|
||||
unsigned char grip[20];
|
||||
|
||||
err = start_agent (ctrl, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY); /* Just in case no key was
|
||||
found in KEYBLOCK. */
|
||||
p = stpcpy (line, "HAVEKEY");
|
||||
for (kbctx=NULL, nkeys=0; (node = walk_kbnode (keyblock, &kbctx, 0)); )
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
|| node->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2))
|
||||
{
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (err != gpg_err_code (GPG_ERR_NO_SECKEY))
|
||||
break; /* Seckey available or unexpected error - ready. */
|
||||
p = stpcpy (line, "HAVEKEY");
|
||||
nkeys = 0;
|
||||
}
|
||||
|
||||
err = keygrip_from_pk (node->pkt->pkt.public_key, grip);
|
||||
if (err)
|
||||
return err;
|
||||
*p++ = ' ';
|
||||
bin2hex (grip, 20, p);
|
||||
p += 40;
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
if (!err && nkeys)
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
@ -1393,7 +1461,8 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
|
||||
}
|
||||
|
||||
|
||||
/* Status callback for agent_import_key and agent_genkey. */
|
||||
/* Status callback for agent_import_key, agent_export_key and
|
||||
agent_genkey. */
|
||||
static gpg_error_t
|
||||
cache_nonce_status_cb (void *opaque, const char *line)
|
||||
{
|
||||
@ -1849,3 +1918,56 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Receive a secret key from the agent. HEXKEYGRIP is the hexified
|
||||
keygrip, DESC a prompt to be displayed with the agent's passphrase
|
||||
question (needs to be plus+percent escaped). On success the key is
|
||||
stored as a canonical S-expression at R_RESULT and R_RESULTLEN. */
|
||||
gpg_error_t
|
||||
agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
||||
char **cache_nonce_addr,
|
||||
unsigned char **r_result, size_t *r_resultlen)
|
||||
{
|
||||
gpg_error_t err;
|
||||
membuf_t data;
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
*r_result = NULL;
|
||||
|
||||
err = start_agent (ctrl, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
snprintf (line, DIM(line)-1, "EXPORT_KEY --openpgp %s%s %s",
|
||||
cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
|
||||
cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
|
||||
hexkeygrip);
|
||||
|
||||
init_membuf_secure (&data, 1024);
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
membuf_data_cb, &data,
|
||||
default_inq_cb, ctrl,
|
||||
cache_nonce_status_cb, cache_nonce_addr);
|
||||
if (err)
|
||||
{
|
||||
xfree (get_membuf (&data, &len));
|
||||
return err;
|
||||
}
|
||||
buf = get_membuf (&data, &len);
|
||||
if (!buf)
|
||||
return gpg_error_from_syserror ();
|
||||
*r_result = buf;
|
||||
*r_resultlen = len;
|
||||
return 0;
|
||||
}
|
||||
|
@ -144,6 +144,11 @@ gpg_error_t agent_get_s2k_count (unsigned long *r_count);
|
||||
0 if the secret key is available. */
|
||||
gpg_error_t agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk);
|
||||
|
||||
/* Ask the agent whether a secret key is availabale for any of the
|
||||
keys (primary or sub) in KEYBLOCK. Returns 0 if available. */
|
||||
gpg_error_t agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
|
||||
|
||||
|
||||
/* Return infos about the secret key with HEXKEYGRIP. */
|
||||
gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
|
||||
char **r_serialno);
|
||||
@ -174,6 +179,11 @@ gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
|
||||
char **cache_nonce_addr,
|
||||
const void *key, size_t keylen);
|
||||
|
||||
/* Receive a key from the agent. */
|
||||
gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,
|
||||
const char *desc, char **cache_nonce_addr,
|
||||
unsigned char **r_result, size_t *r_resultlen);
|
||||
|
||||
|
||||
#endif /*GNUPG_G10_CALL_AGENT_H*/
|
||||
|
||||
|
@ -721,7 +721,7 @@ change_url (void)
|
||||
/* Fetch the key from the URL given on the card or try to get it from
|
||||
the default keyserver. */
|
||||
static int
|
||||
fetch_url(void)
|
||||
fetch_url (ctrl_t ctrl)
|
||||
{
|
||||
int rc;
|
||||
struct agent_card_info_s info;
|
||||
@ -751,13 +751,13 @@ fetch_url(void)
|
||||
event, the fpr/keyid is not meaningful for straight
|
||||
HTTP fetches, but using it allows the card to point
|
||||
to HKP and LDAP servers as well. */
|
||||
rc=keyserver_import_fprint(info.fpr1,20,spec);
|
||||
rc = keyserver_import_fprint (ctrl, info.fpr1, 20, spec);
|
||||
free_keyserver_spec(spec);
|
||||
}
|
||||
}
|
||||
else if (info.fpr1valid)
|
||||
{
|
||||
rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
|
||||
rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1765,7 +1765,7 @@ card_edit_completion(const char *text, int start, int end)
|
||||
/* Menu to edit all user changeable values on an OpenPGP card. Only
|
||||
Key creation is not handled here. */
|
||||
void
|
||||
card_edit (strlist_t commands)
|
||||
card_edit (ctrl_t ctrl, strlist_t commands)
|
||||
{
|
||||
enum cmdids cmd = cmdNOP;
|
||||
int have_commands = !!commands;
|
||||
@ -1924,7 +1924,7 @@ card_edit (strlist_t commands)
|
||||
break;
|
||||
|
||||
case cmdFETCH:
|
||||
fetch_url();
|
||||
fetch_url (ctrl);
|
||||
break;
|
||||
|
||||
case cmdLOGIN:
|
||||
|
@ -300,7 +300,7 @@ release_context (compress_filter_context_t *ctx)
|
||||
* Handle a compressed packet
|
||||
*/
|
||||
int
|
||||
handle_compressed( void *procctx, PKT_compressed *cd,
|
||||
handle_compressed (ctrl_t ctrl, void *procctx, PKT_compressed *cd,
|
||||
int (*callback)(IOBUF, void *), void *passthru )
|
||||
{
|
||||
compress_filter_context_t *cfx;
|
||||
@ -315,7 +315,7 @@ handle_compressed( void *procctx, PKT_compressed *cd,
|
||||
if( callback )
|
||||
rc = callback(cd->buf, passthru );
|
||||
else
|
||||
rc = proc_packets(procctx, cd->buf);
|
||||
rc = proc_packets (ctrl,procctx, cd->buf);
|
||||
cd->buf = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ release_dfx_context (decode_filter_ctx_t dfx)
|
||||
* Decrypt the data, specified by ED with the key DEK.
|
||||
*/
|
||||
int
|
||||
decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
|
||||
{
|
||||
decode_filter_ctx_t dfx;
|
||||
byte *p;
|
||||
@ -191,7 +191,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
else
|
||||
iobuf_push_filter ( ed->buf, decode_filter, dfx );
|
||||
|
||||
proc_packets ( procctx, ed->buf );
|
||||
proc_packets (ctrl, procctx, ed->buf );
|
||||
ed->buf = NULL;
|
||||
if (dfx->eof_seen > 1 )
|
||||
rc = gpg_error (GPG_ERR_INV_PACKET);
|
||||
|
@ -43,7 +43,7 @@
|
||||
* rejects files which don't begin with an encrypted message.
|
||||
*/
|
||||
int
|
||||
decrypt_message (const char *filename)
|
||||
decrypt_message (ctrl_t ctrl, const char *filename)
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t *afx = NULL;
|
||||
@ -86,7 +86,7 @@ decrypt_message (const char *filename)
|
||||
no_out = 1;
|
||||
opt.outfile = "-";
|
||||
}
|
||||
rc = proc_encryption_packets ( NULL, fp );
|
||||
rc = proc_encryption_packets (ctrl, NULL, fp );
|
||||
if (no_out)
|
||||
opt.outfile = NULL;
|
||||
|
||||
@ -100,7 +100,7 @@ decrypt_message (const char *filename)
|
||||
/* Same as decrypt_message but takes a file descriptor for input and
|
||||
output. */
|
||||
gpg_error_t
|
||||
decrypt_message_fd (int input_fd, int output_fd)
|
||||
decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd)
|
||||
{
|
||||
gpg_error_t err;
|
||||
IOBUF fp;
|
||||
@ -158,7 +158,7 @@ decrypt_message_fd (int input_fd, int output_fd)
|
||||
}
|
||||
}
|
||||
|
||||
err = proc_encryption_packets ( NULL, fp );
|
||||
err = proc_encryption_packets (ctrl, NULL, fp );
|
||||
|
||||
iobuf_close (fp);
|
||||
fclose (opt.outfp);
|
||||
@ -170,7 +170,7 @@ decrypt_message_fd (int input_fd, int output_fd)
|
||||
|
||||
|
||||
void
|
||||
decrypt_messages (int nfiles, char *files[])
|
||||
decrypt_messages (ctrl_t ctrl, int nfiles, char *files[])
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t *afx = NULL;
|
||||
@ -251,7 +251,7 @@ decrypt_messages (int nfiles, char *files[])
|
||||
push_armor_filter ( afx, fp );
|
||||
}
|
||||
}
|
||||
rc = proc_packets(NULL, fp);
|
||||
rc = proc_packets (ctrl,NULL, fp);
|
||||
iobuf_close(fp);
|
||||
if (rc)
|
||||
log_error("%s: decryption failed: %s\n", print_fname_stdin(filename),
|
||||
|
@ -461,7 +461,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
||||
* PROVIDED_PKS; if not the function builds a list of keys on its own.
|
||||
*/
|
||||
int
|
||||
encrypt_crypt (int filefd, const char *filename,
|
||||
encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
|
||||
int outputfd)
|
||||
{
|
||||
@ -503,7 +503,7 @@ encrypt_crypt (int filefd, const char *filename,
|
||||
pk_list = provided_keys;
|
||||
else
|
||||
{
|
||||
if ((rc = build_pk_list (remusr, &pk_list, PUBKEY_USAGE_ENC)))
|
||||
if ((rc = build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
|
||||
{
|
||||
release_progress_context (pfx);
|
||||
return rc;
|
||||
@ -939,7 +939,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
||||
|
||||
|
||||
void
|
||||
encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
||||
encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@ -963,7 +963,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
||||
}
|
||||
line[strlen(line)-1] = '\0';
|
||||
print_file_status(STATUS_FILE_START, line, 2);
|
||||
rc = encrypt_crypt (-1, line, remusr, 0, NULL, -1);
|
||||
rc = encrypt_crypt (ctrl, -1, line, remusr, 0, NULL, -1);
|
||||
if (rc)
|
||||
log_error ("encryption of `%s' failed: %s\n",
|
||||
print_fname_stdin(line), g10_errstr(rc) );
|
||||
@ -975,7 +975,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
||||
while (nfiles--)
|
||||
{
|
||||
print_file_status(STATUS_FILE_START, *files, 2);
|
||||
if ( (rc = encrypt_crypt (-1, *files, remusr, 0, NULL, -1)) )
|
||||
if ( (rc = encrypt_crypt (ctrl, -1, *files, remusr, 0, NULL, -1)) )
|
||||
log_error("encryption of `%s' failed: %s\n",
|
||||
print_fname_stdin(*files), g10_errstr(rc) );
|
||||
write_status( STATUS_FILE_DONE );
|
||||
|
743
g10/export.c
743
g10/export.c
@ -1,6 +1,6 @@
|
||||
/* export.c
|
||||
/* export.c - Export keys in the OpenPGP defined format.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
* 2005, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
#include "trustdb.h"
|
||||
|
||||
#include "call-agent.h"
|
||||
|
||||
/* An object to keep track of subkeys. */
|
||||
struct subkey_list_s
|
||||
@ -45,10 +45,12 @@ struct subkey_list_s
|
||||
typedef struct subkey_list_s *subkey_list_t;
|
||||
|
||||
|
||||
static int do_export( strlist_t users, int secret, unsigned int options );
|
||||
static int do_export_stream( IOBUF out, strlist_t users, int secret,
|
||||
KBNODE *keyblock_out, unsigned int options,
|
||||
int *any );
|
||||
static int do_export (ctrl_t ctrl,
|
||||
strlist_t users, int secret, unsigned int options );
|
||||
static int do_export_stream (ctrl_t ctrl, iobuf_t out,
|
||||
strlist_t users, int secret,
|
||||
kbnode_t *keyblock_out, unsigned int options,
|
||||
int *any);
|
||||
static int build_sexp (iobuf_t out, PACKET *pkt, int *indent);
|
||||
|
||||
|
||||
@ -63,8 +65,6 @@ parse_export_options(char *str,unsigned int *options,int noisy)
|
||||
N_("export attribute user IDs (generally photo IDs)")},
|
||||
{"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
|
||||
N_("export revocation keys marked as \"sensitive\"")},
|
||||
{"export-reset-subkey-passwd",EXPORT_RESET_SUBKEY_PASSWD,NULL,
|
||||
N_("remove the passphrase from exported subkeys")},
|
||||
{"export-clean",EXPORT_CLEAN,NULL,
|
||||
N_("remove unusable parts from key during export")},
|
||||
{"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
|
||||
@ -93,9 +93,9 @@ parse_export_options(char *str,unsigned int *options,int noisy)
|
||||
* options are defined in main.h.
|
||||
* If USERS is NULL, the complete ring will be exported. */
|
||||
int
|
||||
export_pubkeys( strlist_t users, unsigned int options )
|
||||
export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options )
|
||||
{
|
||||
return do_export( users, 0, options );
|
||||
return do_export (ctrl, users, 0, options );
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -103,35 +103,41 @@ export_pubkeys( strlist_t users, unsigned int options )
|
||||
* been exported
|
||||
*/
|
||||
int
|
||||
export_pubkeys_stream( IOBUF out, strlist_t users,
|
||||
KBNODE *keyblock_out, unsigned int options )
|
||||
export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
|
||||
kbnode_t *keyblock_out, unsigned int options )
|
||||
{
|
||||
int any, rc;
|
||||
int any, rc;
|
||||
|
||||
rc = do_export_stream( out, users, 0, keyblock_out, options, &any );
|
||||
if( !rc && !any )
|
||||
rc = -1;
|
||||
return rc;
|
||||
rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any);
|
||||
if (!rc && !any)
|
||||
rc = -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
export_seckeys( strlist_t users )
|
||||
export_seckeys (ctrl_t ctrl, strlist_t users )
|
||||
{
|
||||
/* Use only relevant options for the secret key. */
|
||||
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
||||
return do_export( users, 1, options );
|
||||
return do_export (ctrl, users, 1, options);
|
||||
}
|
||||
|
||||
int
|
||||
export_secsubkeys( strlist_t users )
|
||||
export_secsubkeys (ctrl_t ctrl, strlist_t users )
|
||||
{
|
||||
/* Use only relevant options for the secret key. */
|
||||
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
||||
return do_export( users, 2, options );
|
||||
return do_export (ctrl, users, 2, options);
|
||||
}
|
||||
|
||||
|
||||
/* Export the keys identified by the list of strings in USERS. If
|
||||
Secret is false public keys will be exported. With secret true
|
||||
secret keys will be exported; in this case 1 means the entire
|
||||
secret keyblock and 2 only the subkeys. OPTIONS are the export
|
||||
options to apply. */
|
||||
static int
|
||||
do_export( strlist_t users, int secret, unsigned int options )
|
||||
do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options )
|
||||
{
|
||||
IOBUF out = NULL;
|
||||
int any, rc;
|
||||
@ -156,7 +162,7 @@ do_export( strlist_t users, int secret, unsigned int options )
|
||||
push_compress_filter (out,&zfx,default_compress_algo());
|
||||
}
|
||||
|
||||
rc = do_export_stream ( out, users, secret, NULL, options, &any );
|
||||
rc = do_export_stream (ctrl, out, users, secret, NULL, options, &any );
|
||||
|
||||
if ( rc || !any )
|
||||
iobuf_cancel (out);
|
||||
@ -275,11 +281,324 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
|
||||
}
|
||||
|
||||
|
||||
/* If keyblock_out is non-NULL, AND the exit code is zero, then it
|
||||
contains a pointer to the first keyblock found and exported. No
|
||||
other keyblocks are exported. The caller must free it. */
|
||||
/* Return a canonicalized public key algoithms. This is used to
|
||||
compare different flavors of algorithms (e.g. ELG and ELG_E are
|
||||
considered the same). */
|
||||
static int
|
||||
do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
canon_pubkey_algo (int algo)
|
||||
{
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_PK_RSA:
|
||||
case GCRY_PK_RSA_E:
|
||||
case GCRY_PK_RSA_S: return GCRY_PK_RSA;
|
||||
case GCRY_PK_ELG:
|
||||
case GCRY_PK_ELG_E: return GCRY_PK_ELG;
|
||||
default: return algo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Use the key transfer format given in S_PGP to create the secinfo
|
||||
structure in PK and chnage the parameter array in PK to include the
|
||||
secret parameters. */
|
||||
static gpg_error_t
|
||||
transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_sexp_t top_list;
|
||||
gcry_sexp_t list = NULL;
|
||||
const char *value;
|
||||
size_t valuelen;
|
||||
char *string;
|
||||
int idx;
|
||||
int is_v4, is_protected;
|
||||
int pubkey_algo;
|
||||
int protect_algo = 0;
|
||||
char iv[16];
|
||||
int ivlen = 0;
|
||||
int s2k_mode = 0;
|
||||
int s2k_algo = 0;
|
||||
byte s2k_salt[8];
|
||||
u32 s2k_count = 0;
|
||||
size_t npkey, nskey;
|
||||
gcry_mpi_t skey[10]; /* We support up to 9 parameters. */
|
||||
u16 desired_csum;
|
||||
int skeyidx = 0;
|
||||
struct seckey_info *ski;
|
||||
|
||||
top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
|
||||
if (!top_list)
|
||||
goto bad_seckey;
|
||||
|
||||
list = gcry_sexp_find_token (top_list, "version", 0);
|
||||
if (!list)
|
||||
goto bad_seckey;
|
||||
value = gcry_sexp_nth_data (list, 1, &valuelen);
|
||||
if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4'))
|
||||
goto bad_seckey;
|
||||
is_v4 = (value[0] == '4');
|
||||
|
||||
gcry_sexp_release (list);
|
||||
list = gcry_sexp_find_token (top_list, "protection", 0);
|
||||
if (!list)
|
||||
goto bad_seckey;
|
||||
value = gcry_sexp_nth_data (list, 1, &valuelen);
|
||||
if (!value)
|
||||
goto bad_seckey;
|
||||
if (valuelen == 4 && !memcmp (value, "sha1", 4))
|
||||
is_protected = 2;
|
||||
else if (valuelen == 3 && !memcmp (value, "sum", 3))
|
||||
is_protected = 1;
|
||||
else if (valuelen == 4 && !memcmp (value, "none", 4))
|
||||
is_protected = 0;
|
||||
else
|
||||
goto bad_seckey;
|
||||
if (is_protected)
|
||||
{
|
||||
string = gcry_sexp_nth_string (list, 2);
|
||||
if (!string)
|
||||
goto bad_seckey;
|
||||
protect_algo = gcry_cipher_map_name (string);
|
||||
xfree (string);
|
||||
|
||||
value = gcry_sexp_nth_data (list, 3, &valuelen);
|
||||
if (!value || !valuelen || valuelen > sizeof iv)
|
||||
goto bad_seckey;
|
||||
memcpy (iv, value, valuelen);
|
||||
ivlen = valuelen;
|
||||
|
||||
string = gcry_sexp_nth_string (list, 4);
|
||||
if (!string)
|
||||
goto bad_seckey;
|
||||
s2k_mode = strtol (string, NULL, 10);
|
||||
xfree (string);
|
||||
|
||||
string = gcry_sexp_nth_string (list, 5);
|
||||
if (!string)
|
||||
goto bad_seckey;
|
||||
s2k_algo = gcry_md_map_name (string);
|
||||
xfree (string);
|
||||
|
||||
value = gcry_sexp_nth_data (list, 6, &valuelen);
|
||||
if (!value || !valuelen || valuelen > sizeof s2k_salt)
|
||||
goto bad_seckey;
|
||||
memcpy (s2k_salt, value, valuelen);
|
||||
|
||||
string = gcry_sexp_nth_string (list, 7);
|
||||
if (!string)
|
||||
goto bad_seckey;
|
||||
s2k_count = strtoul (string, NULL, 10);
|
||||
xfree (string);
|
||||
}
|
||||
|
||||
gcry_sexp_release (list);
|
||||
list = gcry_sexp_find_token (top_list, "algo", 0);
|
||||
if (!list)
|
||||
goto bad_seckey;
|
||||
string = gcry_sexp_nth_string (list, 1);
|
||||
if (!string)
|
||||
goto bad_seckey;
|
||||
pubkey_algo = gcry_pk_map_name (string);
|
||||
xfree (string);
|
||||
|
||||
if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
|
||||
|| gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
|
||||
|| !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY)
|
||||
goto bad_seckey;
|
||||
|
||||
gcry_sexp_release (list);
|
||||
list = gcry_sexp_find_token (top_list, "skey", 0);
|
||||
if (!list)
|
||||
goto bad_seckey;
|
||||
for (idx=0;;)
|
||||
{
|
||||
int is_enc;
|
||||
|
||||
value = gcry_sexp_nth_data (list, ++idx, &valuelen);
|
||||
if (!value && skeyidx >= npkey)
|
||||
break; /* Ready. */
|
||||
|
||||
/* Check for too many parameters. Note that depending on the
|
||||
protection mode and version number we may see less than NSKEY
|
||||
(but at least NPKEY+1) parameters. */
|
||||
if (idx >= 2*nskey)
|
||||
goto bad_seckey;
|
||||
if (skeyidx >= DIM (skey)-1)
|
||||
goto bad_seckey;
|
||||
|
||||
if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e'))
|
||||
goto bad_seckey;
|
||||
is_enc = (value[0] == 'e');
|
||||
value = gcry_sexp_nth_data (list, ++idx, &valuelen);
|
||||
if (!value || !valuelen)
|
||||
goto bad_seckey;
|
||||
if (is_enc)
|
||||
{
|
||||
void *p = xtrymalloc (valuelen);
|
||||
if (!p)
|
||||
goto outofmem;
|
||||
memcpy (p, value, valuelen);
|
||||
skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8);
|
||||
if (!skey[skeyidx])
|
||||
goto outofmem;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD,
|
||||
value, valuelen, NULL))
|
||||
goto bad_seckey;
|
||||
}
|
||||
skeyidx++;
|
||||
}
|
||||
skey[skeyidx++] = NULL;
|
||||
|
||||
gcry_sexp_release (list);
|
||||
list = gcry_sexp_find_token (top_list, "csum", 0);
|
||||
if (list)
|
||||
{
|
||||
string = gcry_sexp_nth_string (list, 1);
|
||||
if (!string)
|
||||
goto bad_seckey;
|
||||
desired_csum = strtoul (string, NULL, 10);
|
||||
xfree (string);
|
||||
}
|
||||
else
|
||||
desired_csum = 0;
|
||||
|
||||
|
||||
gcry_sexp_release (list); list = NULL;
|
||||
gcry_sexp_release (top_list); top_list = NULL;
|
||||
|
||||
/* log_debug ("XXX is_v4=%d\n", is_v4); */
|
||||
/* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */
|
||||
/* log_debug ("XXX is_protected=%d\n", is_protected); */
|
||||
/* log_debug ("XXX protect_algo=%d\n", protect_algo); */
|
||||
/* log_printhex ("XXX iv", iv, ivlen); */
|
||||
/* log_debug ("XXX ivlen=%d\n", ivlen); */
|
||||
/* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */
|
||||
/* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */
|
||||
/* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */
|
||||
/* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */
|
||||
/* for (idx=0; skey[idx]; idx++) */
|
||||
/* { */
|
||||
/* int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */
|
||||
/* log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */
|
||||
/* if (is_enc) */
|
||||
/* { */
|
||||
/* void *p; */
|
||||
/* unsigned int nbits; */
|
||||
/* p = gcry_mpi_get_opaque (skey[idx], &nbits); */
|
||||
/* log_printhex (NULL, p, (nbits+7)/8); */
|
||||
/* } */
|
||||
/* else */
|
||||
/* gcry_mpi_dump (skey[idx]); */
|
||||
/* log_printf ("\n"); */
|
||||
/* } */
|
||||
|
||||
if (!is_v4 || is_protected != 2 )
|
||||
{
|
||||
/* We only support the v4 format and a SHA-1 checksum. */
|
||||
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Do some sanity checks. */
|
||||
if (s2k_count <= 1024)
|
||||
{
|
||||
/* The count must be larger so that encode_s2k_iterations does
|
||||
not fall into a backward compatibility mode. */
|
||||
err = gpg_error (GPG_ERR_INV_DATA);
|
||||
goto leave;
|
||||
}
|
||||
if (canon_pubkey_algo (pubkey_algo) != canon_pubkey_algo (pk->pubkey_algo))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||
goto leave;
|
||||
}
|
||||
err = openpgp_cipher_test_algo (protect_algo);
|
||||
if (err)
|
||||
goto leave;
|
||||
err = openpgp_md_test_algo (s2k_algo);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* Check that the public key parameters match. */
|
||||
for (idx=0; idx < npkey; idx++)
|
||||
if (gcry_mpi_get_flag (pk->pkey[idx], GCRYMPI_FLAG_OPAQUE)
|
||||
|| gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)
|
||||
|| gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_BAD_PUBKEY);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Check that the first secret key parameter in SKEY is encrypted
|
||||
and that there are no more secret key parameters. The latter is
|
||||
guaranteed by the v4 packet format. */
|
||||
if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE))
|
||||
goto bad_seckey;
|
||||
if (npkey+1 < DIM (skey) && skey[npkey+1])
|
||||
goto bad_seckey;
|
||||
|
||||
/* Check that the secret key parameters in PK are all set to NULL. */
|
||||
for (idx=npkey; idx < nskey; idx++)
|
||||
if (pk->pkey[idx])
|
||||
goto bad_seckey;
|
||||
|
||||
/* Now build the protection info. */
|
||||
pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
|
||||
if (!ski)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
ski->is_protected = 1;
|
||||
ski->sha1chk = 1;
|
||||
ski->algo = protect_algo;
|
||||
ski->s2k.mode = s2k_mode;
|
||||
ski->s2k.hash_algo = s2k_algo;
|
||||
assert (sizeof ski->s2k.salt == sizeof s2k_salt);
|
||||
memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt);
|
||||
ski->s2k.count = encode_s2k_iterations (s2k_count);
|
||||
assert (ivlen <= sizeof ski->iv);
|
||||
memcpy (ski->iv, iv, ivlen);
|
||||
ski->ivlen = ivlen;
|
||||
|
||||
/* Store the protected secret key parameter. */
|
||||
pk->pkey[npkey] = skey[npkey];
|
||||
skey[npkey] = NULL;
|
||||
|
||||
/* That's it. */
|
||||
|
||||
leave:
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (top_list);
|
||||
for (idx=0; idx < skeyidx; idx++)
|
||||
gcry_mpi_release (skey[idx]);
|
||||
return err;
|
||||
|
||||
bad_seckey:
|
||||
err = gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
goto leave;
|
||||
|
||||
outofmem:
|
||||
err = gpg_error (GPG_ERR_ENOMEM);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Export the keys identified by the list of strings in USERS to the
|
||||
stream OUT. If Secret is false public keys will be exported. With
|
||||
secret true secret keys will be exported; in this case 1 means the
|
||||
entire secret keyblock and 2 only the subkeys. OPTIONS are the
|
||||
export options to apply. If KEYBLOCK_OUT is not NULL, AND the exit
|
||||
code is zero, a pointer to the first keyblock found and exported
|
||||
will be stored at this address; no other keyblocks are exported in
|
||||
this case. The caller must free it the returned keyblock. If any
|
||||
key has been exported true is stored at ANY. */
|
||||
static int
|
||||
do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
||||
kbnode_t *keyblock_out, unsigned int options, int *any)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
@ -292,6 +611,7 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
KEYDB_HANDLE kdbhd;
|
||||
strlist_t sl;
|
||||
int indent = 0;
|
||||
gcry_cipher_hd_t cipherhd = NULL;
|
||||
|
||||
*any = 0;
|
||||
init_packet (&pkt);
|
||||
@ -330,21 +650,51 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
if (secret)
|
||||
{
|
||||
log_error (_("exporting secret keys not allowed\n"));
|
||||
err = G10ERR_GENERAL;
|
||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For secret key export we need to setup a decryption context. */
|
||||
if (secret)
|
||||
{
|
||||
void *kek = NULL;
|
||||
size_t keklen;
|
||||
|
||||
err = agent_keywrap_key (ctrl, 1, &kek, &keklen);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error getting the KEK: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Prepare a cipher context. */
|
||||
err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
|
||||
GCRY_CIPHER_MODE_AESWRAP, 0);
|
||||
if (!err)
|
||||
err = gcry_cipher_setkey (cipherhd, kek, keklen);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error setting up an encryption context: %s\n",
|
||||
gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
xfree (kek);
|
||||
kek = NULL;
|
||||
}
|
||||
|
||||
while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex)))
|
||||
{
|
||||
int sha1_warned = 0;
|
||||
int skip_until_subkey = 0;
|
||||
u32 keyid[2];
|
||||
PKT_public_key *pk;
|
||||
|
||||
if (!users)
|
||||
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
||||
|
||||
/* Read the keyblock. */
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
err = keydb_get_keyblock (kdbhd, &keyblock);
|
||||
if (err)
|
||||
{
|
||||
@ -352,60 +702,57 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if ((node=find_kbnode(keyblock, PKT_SECRET_KEY)))
|
||||
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
||||
if (!node)
|
||||
{
|
||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||
log_error ("public key packet not found in keyblock - skipped\n");
|
||||
continue;
|
||||
}
|
||||
pk = node->pkt->pkt.public_key;
|
||||
keyid_from_pk (pk, keyid);
|
||||
|
||||
keyid_from_pk (pk, keyid);
|
||||
/* If a secret key export is required we need to check whether
|
||||
we have a secret key at all and if so create the seckey_info
|
||||
structure. */
|
||||
if (secret)
|
||||
{
|
||||
if (agent_probe_any_secret_key (ctrl, keyblock))
|
||||
continue; /* No secret key (neither primary nor subkey). */
|
||||
|
||||
/* We can't apply GNU mode 1001 on an unprotected key. */
|
||||
if( secret == 2
|
||||
&& pk->seckey_info && !pk->seckey_info->is_protected )
|
||||
/* No v3 keys with GNU mode 1001. */
|
||||
if (secret == 2 && pk->version == 3)
|
||||
{
|
||||
log_info (_("key %s: not protected - skipped\n"),
|
||||
log_info (_("key %s: PGP 2.x style key - skipped\n"),
|
||||
keystr (keyid));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No v3 keys with GNU mode 1001. */
|
||||
if( secret == 2 && pk->version == 3 )
|
||||
/* The agent does not yet allow to export v3 packets. It is
|
||||
actually questionable whether we should allow them at
|
||||
all. */
|
||||
if (pk->version == 3)
|
||||
{
|
||||
log_info(_("key %s: PGP 2.x style key - skipped\n"),
|
||||
keystr (keyid));
|
||||
log_info ("key %s: PGP 2.x style key (v3) export "
|
||||
"not yet supported - skipped\n", keystr (keyid));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* It does not make sense to export a key with a primary
|
||||
key on card using a non-key stub. We simply skip those
|
||||
keys when used with --export-secret-subkeys. */
|
||||
if (secret == 2
|
||||
&& pk->seckey_info && pk->seckey_info->is_protected
|
||||
&& pk->seckey_info->s2k.mode == 1002 )
|
||||
{
|
||||
log_info(_("key %s: key material on-card - skipped\n"),
|
||||
keystr (keyid));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's a public key export, so do the cleaning if
|
||||
requested. Note that both export-clean and
|
||||
export-minimal only apply to UID sigs (0x10, 0x11, 0x12,
|
||||
and 0x13). A designated revocation is never stripped,
|
||||
even with export-minimal set. */
|
||||
if ( (options & EXPORT_CLEAN) )
|
||||
clean_key (keyblock, opt.verbose, options&EXPORT_MINIMAL,
|
||||
NULL, NULL);
|
||||
}
|
||||
/* Always do the cleaning on the public key part if requested.
|
||||
Note that we don't yet set this option if we are exporting
|
||||
secret keys. Note that both export-clean and export-minimal
|
||||
only apply to UID sigs (0x10, 0x11, 0x12, and 0x13). A
|
||||
designated revocation is never stripped, even with
|
||||
export-minimal set. */
|
||||
if ((options & EXPORT_CLEAN))
|
||||
clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
|
||||
|
||||
/* And write it. */
|
||||
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
|
||||
{
|
||||
if (skip_until_subkey)
|
||||
{
|
||||
if (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
|
||||
|| node->pkt->pkttype==PKT_SECRET_SUBKEY)
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
skip_until_subkey = 0;
|
||||
else
|
||||
continue;
|
||||
@ -425,8 +772,7 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
(plus the primary key, if the user didn't specifically
|
||||
request it). */
|
||||
if (desc[descindex].exact
|
||||
&& (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY))
|
||||
&& node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
if (!exact_subkey_match_p (desc+descindex, node))
|
||||
{
|
||||
@ -440,9 +786,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
skip in any case if the key is in that list.
|
||||
|
||||
We need this whole mess because the import
|
||||
function is not able to merge secret keys and
|
||||
thus it is useless to output them as two separate
|
||||
keys and have import merge them. */
|
||||
function of GnuPG < 2.1 is not able to merge
|
||||
secret keys and thus it is useless to output them
|
||||
as two separate keys and have import merge them. */
|
||||
if (subkey_in_list_p (subkey_list, node))
|
||||
skip_until_subkey = 1; /* Already processed this one. */
|
||||
else
|
||||
@ -508,88 +854,181 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY)
|
||||
if (secret && (node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
|
||||
{
|
||||
/* We don't want to export the secret parts of the
|
||||
* primary key, this is done by temporary switching to
|
||||
* GNU protection mode 1001. */
|
||||
int save_mode = node->pkt->pkt.public_key->seckey_info->s2k.mode;
|
||||
node->pkt->pkt.public_key->seckey_info->s2k.mode = 1001;
|
||||
if ((options&EXPORT_SEXP_FORMAT))
|
||||
err = build_sexp (out, node->pkt, &indent);
|
||||
u32 subkidbuf[2], *subkid;
|
||||
char *hexgrip, *serialno;
|
||||
|
||||
pk = node->pkt->pkt.public_key;
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
subkid = NULL;
|
||||
else
|
||||
err = build_packet (out, node->pkt);
|
||||
node->pkt->pkt.public_key->seckey_info->s2k.mode = save_mode;
|
||||
}
|
||||
else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
|
||||
&& (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
|
||||
{
|
||||
/* If the subkey is protected reset the passphrase to
|
||||
export an unprotected subkey. This feature is useful
|
||||
in cases of a subkey copied to an unattended machine
|
||||
where a passphrase is not required. */
|
||||
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
goto leave;
|
||||
#warning We need to implement this
|
||||
/* PKT_secret_key *sk_save, *sk; */
|
||||
{
|
||||
keyid_from_pk (pk, subkidbuf);
|
||||
subkid = subkidbuf;
|
||||
}
|
||||
|
||||
/* sk_save = node->pkt->pkt.secret_key; */
|
||||
/* sk = copy_secret_key (NULL, sk_save); */
|
||||
/* node->pkt->pkt.secret_key = sk; */
|
||||
if (pk->seckey_info)
|
||||
{
|
||||
log_error ("key %s: oops: seckey_info already set"
|
||||
" - skipped\n", keystr_with_sub (keyid, subkid));
|
||||
skip_until_subkey = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* log_info (_("about to export an unprotected subkey\n")); */
|
||||
/* switch (is_secret_key_protected (sk)) */
|
||||
/* { */
|
||||
/* case -1: */
|
||||
/* err = gpg_error (GPG_ERR_PUBKEY_ALGO); */
|
||||
/* break; */
|
||||
/* case 0: */
|
||||
/* break; */
|
||||
/* default: */
|
||||
/* if (sk->protect.s2k.mode == 1001) */
|
||||
/* ; /\* No secret parts. *\/ */
|
||||
/* else if( sk->protect.s2k.mode == 1002 ) */
|
||||
/* ; /\* Card key stub. *\/ */
|
||||
/* else */
|
||||
/* { */
|
||||
/* /\* err = check_secret_key( sk, 0 ); *\/ */
|
||||
/* } */
|
||||
/* break; */
|
||||
/* } */
|
||||
/* if (err) */
|
||||
/* { */
|
||||
/* node->pkt->pkt.secret_key = sk_save; */
|
||||
/* free_secret_key (sk); */
|
||||
/* log_error (_("failed to unprotect the subkey: %s\n"), */
|
||||
/* g10_errstr (rc)); */
|
||||
/* goto leave; */
|
||||
/* } */
|
||||
err = hexkeygrip_from_pk (pk, &hexgrip);
|
||||
if (err)
|
||||
{
|
||||
log_error ("key %s: error computing keygrip: %s"
|
||||
" - skipped\n", keystr_with_sub (keyid, subkid),
|
||||
gpg_strerror (err));
|
||||
skip_until_subkey = 1;
|
||||
err = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ((options&EXPORT_SEXP_FORMAT)) */
|
||||
/* err = build_sexp (out, node->pkt, &indent); */
|
||||
/* else */
|
||||
/* err = build_packet (out, node->pkt); */
|
||||
if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
{
|
||||
/* We are asked not to export the secret parts of
|
||||
the primary key. Make up an error code to create
|
||||
the stub. */
|
||||
err = GPG_ERR_NOT_FOUND;
|
||||
serialno = NULL;
|
||||
}
|
||||
else
|
||||
err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
|
||||
|
||||
/* node->pkt->pkt.secret_key = sk_save; */
|
||||
/* free_secret_key (sk); */
|
||||
if ((!err && serialno)
|
||||
&& secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
{
|
||||
/* It does not make sense to export a key with its
|
||||
primary key on card using a non-key stub. Thus
|
||||
we skip those keys when used with
|
||||
--export-secret-subkeys. */
|
||||
log_info (_("key %s: key material on-card - skipped\n"),
|
||||
keystr_with_sub (keyid, subkid));
|
||||
skip_until_subkey = 1;
|
||||
}
|
||||
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
|
||||
|| (!err && serialno))
|
||||
{
|
||||
/* Create a key stub. */
|
||||
struct seckey_info *ski;
|
||||
const char *s;
|
||||
|
||||
pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
|
||||
if (!ski)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
xfree (hexgrip);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
ski->is_protected = 1;
|
||||
if (err)
|
||||
ski->s2k.mode = 1001; /* GNU dummy (no secret key). */
|
||||
else
|
||||
{
|
||||
ski->s2k.mode = 1002; /* GNU-divert-to-card. */
|
||||
for (s=serialno; sizeof (ski->ivlen) && *s && s[1];
|
||||
ski->ivlen++, s += 2)
|
||||
ski->iv[ski->ivlen] = xtoi_2 (s);
|
||||
}
|
||||
|
||||
if ((options&EXPORT_SEXP_FORMAT))
|
||||
err = build_sexp (out, node->pkt, &indent);
|
||||
else
|
||||
err = build_packet (out, node->pkt);
|
||||
}
|
||||
else if (!err)
|
||||
{
|
||||
/* FIXME: Move this spaghetti code into a separate
|
||||
function. */
|
||||
unsigned char *wrappedkey = NULL;
|
||||
size_t wrappedkeylen;
|
||||
unsigned char *key = NULL;
|
||||
size_t keylen, realkeylen;
|
||||
gcry_sexp_t s_skey;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("key %s: asking agent for the secret parts\n",
|
||||
keystr_with_sub (keyid, subkid));
|
||||
|
||||
err = agent_export_key (ctrl, hexgrip, "Key foo", NULL,
|
||||
&wrappedkey, &wrappedkeylen);
|
||||
if (err)
|
||||
goto unwraperror;
|
||||
if (wrappedkeylen < 24)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_LENGTH);
|
||||
goto unwraperror;
|
||||
}
|
||||
keylen = wrappedkeylen - 8;
|
||||
key = xtrymalloc_secure (keylen);
|
||||
if (!key)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto unwraperror;
|
||||
}
|
||||
err = gcry_cipher_decrypt (cipherhd, key, keylen,
|
||||
wrappedkey, wrappedkeylen);
|
||||
if (err)
|
||||
goto unwraperror;
|
||||
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
||||
if (!realkeylen)
|
||||
goto unwraperror; /* Invalid csexp. */
|
||||
|
||||
err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
|
||||
xfree (key);
|
||||
key = NULL;
|
||||
if (err)
|
||||
goto unwraperror;
|
||||
err = transfer_format_to_openpgp (s_skey, pk);
|
||||
gcry_sexp_release (s_skey);
|
||||
if (err)
|
||||
goto unwraperror;
|
||||
|
||||
if ((options&EXPORT_SEXP_FORMAT))
|
||||
err = build_sexp (out, node->pkt, &indent);
|
||||
else
|
||||
err = build_packet (out, node->pkt);
|
||||
goto unwraperror_leave;
|
||||
|
||||
unwraperror:
|
||||
xfree (wrappedkey);
|
||||
xfree (key);
|
||||
if (err)
|
||||
{
|
||||
log_error ("key %s: error receiving key from agent:"
|
||||
" %s%s\n",
|
||||
keystr_with_sub (keyid, subkid),
|
||||
gpg_strerror (err),
|
||||
gpg_err_code (err) == GPG_ERR_FULLY_CANCELED?
|
||||
"":_(" - skipped"));
|
||||
if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
|
||||
goto leave;
|
||||
skip_until_subkey = 1;
|
||||
err = 0;
|
||||
}
|
||||
unwraperror_leave:
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error ("key %s: error getting keyinfo from agent: %s"
|
||||
" - skipped\n", keystr_with_sub (keyid, subkid),
|
||||
gpg_strerror (err));
|
||||
skip_until_subkey = 1;
|
||||
err = 0;
|
||||
}
|
||||
|
||||
xfree (pk->seckey_info);
|
||||
pk->seckey_info = NULL;
|
||||
xfree (hexgrip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Warn the user if the secret key or any of the secret
|
||||
subkeys are protected with SHA1 and we have
|
||||
simple_sk_checksum set. */
|
||||
if (!sha1_warned && opt.simple_sk_checksum &&
|
||||
(node->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
&& node->pkt->pkt.public_key->seckey_info->sha1chk)
|
||||
{
|
||||
/* I hope this warning doesn't confuse people. */
|
||||
log_info(_("WARNING: secret key %s does not have a "
|
||||
"simple SK checksum\n"), keystr (keyid));
|
||||
|
||||
sha1_warned = 1;
|
||||
}
|
||||
|
||||
if ((options&EXPORT_SEXP_FORMAT))
|
||||
err = build_sexp (out, node->pkt, &indent);
|
||||
else
|
||||
@ -602,6 +1041,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
node->pkt->pkttype, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!skip_until_subkey)
|
||||
*any = 1;
|
||||
}
|
||||
|
||||
if ((options&EXPORT_SEXP_FORMAT) && indent)
|
||||
@ -611,10 +1053,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
iobuf_put (out, '\n');
|
||||
}
|
||||
|
||||
++*any;
|
||||
if(keyblock_out)
|
||||
if (keyblock_out)
|
||||
{
|
||||
*keyblock_out=keyblock;
|
||||
*keyblock_out = keyblock;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -624,10 +1065,11 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
iobuf_put (out, ')');
|
||||
iobuf_put (out, '\n');
|
||||
}
|
||||
if( err == -1 )
|
||||
if (err == -1)
|
||||
err = 0;
|
||||
|
||||
leave:
|
||||
gcry_cipher_close (cipherhd);
|
||||
release_subkey_list (subkey_list);
|
||||
xfree(desc);
|
||||
keydb_release (kdbhd);
|
||||
@ -672,6 +1114,10 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
||||
static int
|
||||
build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
|
||||
{
|
||||
(void)out;
|
||||
(void)pkt;
|
||||
(void)indent;
|
||||
|
||||
/* FIXME: Not yet implemented. */
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
/* PKT_secret_key *sk = pkt->pkt.secret_key; */
|
||||
@ -759,4 +1205,3 @@ build_sexp (iobuf_t out, PACKET *pkt, int *indent)
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "../common/iobuf.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "options.h"
|
||||
|
||||
|
16
g10/getkey.c
16
g10/getkey.c
@ -676,7 +676,7 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
||||
to import the key via the online mechanisms defined by
|
||||
--auto-key-locate. */
|
||||
int
|
||||
get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
const char *name, KBNODE * ret_keyblock,
|
||||
KEYDB_HANDLE * ret_kdbhd, int include_unusable, int no_akl)
|
||||
{
|
||||
@ -770,21 +770,21 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
case AKL_CERT:
|
||||
mechanism = "DNS CERT";
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
rc = keyserver_import_cert (name, &fpr, &fpr_len);
|
||||
rc = keyserver_import_cert (ctrl, name, &fpr, &fpr_len);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
break;
|
||||
|
||||
case AKL_PKA:
|
||||
mechanism = "PKA";
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
rc = keyserver_import_pka (name, &fpr, &fpr_len);
|
||||
rc = keyserver_import_pka (ctrl, name, &fpr, &fpr_len);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
break;
|
||||
|
||||
case AKL_LDAP:
|
||||
mechanism = "LDAP";
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
rc = keyserver_import_ldap (name, &fpr, &fpr_len);
|
||||
rc = keyserver_import_ldap (ctrl, name, &fpr, &fpr_len);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
break;
|
||||
|
||||
@ -797,9 +797,8 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
{
|
||||
mechanism = opt.keyserver->uri;
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
rc =
|
||||
keyserver_import_name (name, &fpr, &fpr_len,
|
||||
opt.keyserver);
|
||||
rc = keyserver_import_name (ctrl, name, &fpr, &fpr_len,
|
||||
opt.keyserver);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
}
|
||||
else
|
||||
@ -816,7 +815,8 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
mechanism = akl->spec->uri;
|
||||
keyserver = keyserver_match (akl->spec);
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
rc = keyserver_import_name (name, &fpr, &fpr_len, keyserver);
|
||||
rc = keyserver_import_name (ctrl,
|
||||
name, &fpr, &fpr_len, keyserver);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
}
|
||||
break;
|
||||
|
78
g10/gpg.c
78
g10/gpg.c
@ -37,9 +37,9 @@
|
||||
#define INCLUDED_BY_MAIN_MODULE 1
|
||||
#include "gpg.h"
|
||||
#include <assuan.h>
|
||||
#include "packet.h"
|
||||
#include "../common/iobuf.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
@ -273,7 +273,6 @@ enum cmd_and_opt_values
|
||||
oS2KDigest,
|
||||
oS2KCipher,
|
||||
oS2KCount,
|
||||
oSimpleSKChecksum,
|
||||
oDisplayCharset,
|
||||
oNotDashEscaped,
|
||||
oEscapeFrom,
|
||||
@ -565,7 +564,6 @@ static ARGPARSE_OPTS opts[] = {
|
||||
ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"),
|
||||
ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
|
||||
ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
|
||||
ARGPARSE_s_n (oSimpleSKChecksum, "simple-sk-checksum", "@"),
|
||||
ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
|
||||
ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
|
||||
ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
|
||||
@ -2504,7 +2502,6 @@ main (int argc, char **argv)
|
||||
else
|
||||
opt.s2k_count = 0; /* Auto-calibrate when needed. */
|
||||
break;
|
||||
case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
|
||||
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
|
||||
case oEncryptTo: /* store the recipient in the second list */
|
||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
||||
@ -2966,8 +2963,8 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( configfp ) {
|
||||
if (configfp)
|
||||
{
|
||||
fclose( configfp );
|
||||
configfp = NULL;
|
||||
/* Remember the first config file name. */
|
||||
@ -2977,10 +2974,10 @@ main (int argc, char **argv)
|
||||
xfree(configname);
|
||||
configname = NULL;
|
||||
goto next_pass;
|
||||
}
|
||||
xfree( configname ); configname = NULL;
|
||||
if( log_get_errorcount(0) )
|
||||
g10_exit(2);
|
||||
}
|
||||
xfree(configname); configname = NULL;
|
||||
if (log_get_errorcount (0))
|
||||
g10_exit(2);
|
||||
|
||||
/* The command --gpgconf-list is pretty simple and may be called
|
||||
directly after the option parsing. */
|
||||
@ -3405,7 +3402,7 @@ main (int argc, char **argv)
|
||||
if(fname && utf8_strings)
|
||||
opt.flags.utf8_filename=1;
|
||||
|
||||
ctrl = xtrycalloc (1, sizeof *ctrl);
|
||||
ctrl = xcalloc (1, sizeof *ctrl);
|
||||
gpg_init_default_ctrl (ctrl);
|
||||
|
||||
switch( cmd ) {
|
||||
@ -3463,12 +3460,12 @@ main (int argc, char **argv)
|
||||
|
||||
case aEncr: /* encrypt the given file */
|
||||
if(multifile)
|
||||
encrypt_crypt_files(argc, argv, remusr);
|
||||
encrypt_crypt_files (ctrl, argc, argv, remusr);
|
||||
else
|
||||
{
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--encrypt [filename]"));
|
||||
if( (rc = encrypt_crypt (-1, fname, remusr, 0, NULL, -1)) )
|
||||
if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) )
|
||||
log_error("%s: encryption failed: %s\n",
|
||||
print_fname_stdin(fname), g10_errstr(rc) );
|
||||
}
|
||||
@ -3489,7 +3486,7 @@ main (int argc, char **argv)
|
||||
" while in %s mode\n"),compliance_option_string());
|
||||
else
|
||||
{
|
||||
if( (rc = encrypt_crypt (-1, fname, remusr, 1, NULL, -1)) )
|
||||
if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
|
||||
log_error("%s: encryption failed: %s\n",
|
||||
print_fname_stdin(fname), g10_errstr(rc) );
|
||||
}
|
||||
@ -3509,7 +3506,7 @@ main (int argc, char **argv)
|
||||
strcpy(sl->d, fname);
|
||||
}
|
||||
}
|
||||
if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
|
||||
if( (rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)) )
|
||||
log_error("signing failed: %s\n", g10_errstr(rc) );
|
||||
free_strlist(sl);
|
||||
break;
|
||||
@ -3523,7 +3520,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
else
|
||||
sl = NULL;
|
||||
if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
|
||||
if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 1, remusr, NULL)))
|
||||
log_error("%s: sign+encrypt failed: %s\n",
|
||||
print_fname_stdin(fname), g10_errstr(rc) );
|
||||
free_strlist(sl);
|
||||
@ -3547,7 +3544,8 @@ main (int argc, char **argv)
|
||||
}
|
||||
else
|
||||
sl = NULL;
|
||||
if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
|
||||
if ((rc = sign_file (ctrl, sl, detached_sig, locusr,
|
||||
2, remusr, NULL)))
|
||||
log_error("%s: symmetric+sign+encrypt failed: %s\n",
|
||||
print_fname_stdin(fname), g10_errstr(rc) );
|
||||
free_strlist(sl);
|
||||
@ -3572,26 +3570,26 @@ main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case aVerify:
|
||||
if(multifile)
|
||||
if (multifile)
|
||||
{
|
||||
if( (rc = verify_files( argc, argv ) ))
|
||||
if ((rc = verify_files (ctrl, argc, argv)))
|
||||
log_error("verify files failed: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (rc = verify_signatures( argc, argv ) ))
|
||||
if ((rc = verify_signatures (ctrl, argc, argv)))
|
||||
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
break;
|
||||
|
||||
case aDecrypt:
|
||||
if(multifile)
|
||||
decrypt_messages(argc, argv);
|
||||
if (multifile)
|
||||
decrypt_messages (ctrl, argc, argv);
|
||||
else
|
||||
{
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--decrypt [filename]"));
|
||||
if( (rc = decrypt_message( fname ) ))
|
||||
if( (rc = decrypt_message (ctrl, fname) ))
|
||||
log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
break;
|
||||
@ -3616,7 +3614,7 @@ main (int argc, char **argv)
|
||||
|
||||
append_to_strlist( &sl, "save" );
|
||||
username = make_username( fname );
|
||||
keyedit_menu (username, locusr, sl, 0, 0 );
|
||||
keyedit_menu (ctrl, username, locusr, sl, 0, 0 );
|
||||
xfree(username);
|
||||
free_strlist(sl);
|
||||
break;
|
||||
@ -3629,11 +3627,11 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( argc--, argv++ ; argc; argc--, argv++ )
|
||||
append_to_strlist( &sl, *argv );
|
||||
keyedit_menu( username, locusr, sl, 0, 1 );
|
||||
keyedit_menu (ctrl, username, locusr, sl, 0, 1 );
|
||||
free_strlist(sl);
|
||||
}
|
||||
else
|
||||
keyedit_menu(username, locusr, NULL, 0, 1 );
|
||||
keyedit_menu (ctrl, username, locusr, NULL, 0, 1 );
|
||||
xfree(username);
|
||||
break;
|
||||
|
||||
@ -3669,21 +3667,21 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
public_key_list( sl, 0 );
|
||||
public_key_list (ctrl, sl, 0);
|
||||
free_strlist(sl);
|
||||
break;
|
||||
case aListSecretKeys:
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
secret_key_list( sl );
|
||||
secret_key_list (ctrl, sl);
|
||||
free_strlist(sl);
|
||||
break;
|
||||
case aLocateKeys:
|
||||
sl = NULL;
|
||||
for (; argc; argc--, argv++)
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
public_key_list (sl, 1);
|
||||
public_key_list (ctrl, sl, 1);
|
||||
free_strlist (sl);
|
||||
break;
|
||||
|
||||
@ -3718,11 +3716,11 @@ main (int argc, char **argv)
|
||||
for( ; argc; argc--, argv++ )
|
||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||
if( cmd == aSendKeys )
|
||||
rc=keyserver_export( sl );
|
||||
rc = keyserver_export (ctrl, sl );
|
||||
else if( cmd == aRecvKeys )
|
||||
rc=keyserver_import( sl );
|
||||
rc = keyserver_import (ctrl, sl );
|
||||
else
|
||||
rc=export_pubkeys( sl, opt.export_options );
|
||||
rc = export_pubkeys (ctrl, sl, opt.export_options);
|
||||
if(rc)
|
||||
{
|
||||
if(cmd==aSendKeys)
|
||||
@ -3739,7 +3737,7 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||
rc=keyserver_search( sl );
|
||||
rc = keyserver_search (ctrl, sl);
|
||||
if(rc)
|
||||
log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
|
||||
free_strlist(sl);
|
||||
@ -3749,7 +3747,7 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||
rc=keyserver_refresh(sl);
|
||||
rc = keyserver_refresh (ctrl, sl);
|
||||
if(rc)
|
||||
log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
|
||||
free_strlist(sl);
|
||||
@ -3759,7 +3757,7 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||
rc=keyserver_fetch(sl);
|
||||
rc = keyserver_fetch (ctrl, sl);
|
||||
if(rc)
|
||||
log_error("key fetch failed: %s\n",g10_errstr(rc));
|
||||
free_strlist(sl);
|
||||
@ -3769,7 +3767,7 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
export_seckeys( sl );
|
||||
export_seckeys (ctrl, sl);
|
||||
free_strlist(sl);
|
||||
break;
|
||||
|
||||
@ -3777,7 +3775,7 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||
export_secsubkeys( sl );
|
||||
export_secsubkeys (ctrl, sl);
|
||||
free_strlist(sl);
|
||||
break;
|
||||
|
||||
@ -3987,11 +3985,11 @@ main (int argc, char **argv)
|
||||
sl = NULL;
|
||||
for (argc--, argv++ ; argc; argc--, argv++)
|
||||
append_to_strlist (&sl, *argv);
|
||||
card_edit (sl);
|
||||
card_edit (ctrl, sl);
|
||||
free_strlist (sl);
|
||||
}
|
||||
else
|
||||
card_edit (NULL);
|
||||
card_edit (ctrl, NULL);
|
||||
break;
|
||||
|
||||
case aChangePIN:
|
||||
@ -4045,7 +4043,7 @@ main (int argc, char **argv)
|
||||
set_packet_list_mode(1);
|
||||
opt.list_packets=1;
|
||||
}
|
||||
rc = proc_packets(NULL, a );
|
||||
rc = proc_packets (ctrl, NULL, a );
|
||||
if( rc )
|
||||
log_error("processing message failed: %s\n", g10_errstr(rc) );
|
||||
iobuf_close(a);
|
||||
|
14
g10/gpgv.c
14
g10/gpgv.c
@ -35,9 +35,9 @@
|
||||
|
||||
#define INCLUDED_BY_MAIN_MODULE 1
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
@ -140,8 +140,9 @@ main( int argc, char **argv )
|
||||
ARGPARSE_ARGS pargs;
|
||||
int rc=0;
|
||||
strlist_t sl;
|
||||
strlist_t nrings=NULL;
|
||||
strlist_t nrings = NULL;
|
||||
unsigned configlineno;
|
||||
ctrl_t ctrl;
|
||||
|
||||
set_strusage (my_strusage);
|
||||
log_set_prefix ("gpgv", 1);
|
||||
@ -202,9 +203,13 @@ main( int argc, char **argv )
|
||||
|
||||
FREE_STRLIST (nrings);
|
||||
|
||||
if ( (rc = verify_signatures( argc, argv ) ))
|
||||
ctrl = xcalloc (1, sizeof *ctrl);
|
||||
|
||||
if ((rc = verify_signatures (ctrl, argc, argv)))
|
||||
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
||||
|
||||
xfree (ctrl);
|
||||
|
||||
/* cleanup */
|
||||
g10_exit (0);
|
||||
return 8; /*NOTREACHED*/
|
||||
@ -377,8 +382,9 @@ get_override_session_key (DEK *dek, const char *string)
|
||||
|
||||
/* Stub: */
|
||||
int
|
||||
decrypt_data (void *procctx, PKT_encrypted *ed, DEK *dek)
|
||||
decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
|
||||
{
|
||||
(void)ctrl;
|
||||
(void)procctx;
|
||||
(void)ed;
|
||||
(void)dek;
|
||||
|
46
g10/import.c
46
g10/import.c
@ -64,10 +64,11 @@ static int import (ctrl_t ctrl,
|
||||
IOBUF inp, const char* fname, struct stats_s *stats,
|
||||
unsigned char **fpr, size_t *fpr_len, unsigned int options);
|
||||
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
|
||||
static void revocation_present(KBNODE keyblock);
|
||||
static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
|
||||
unsigned char **fpr,size_t *fpr_len,
|
||||
unsigned int options,int from_sk);
|
||||
static void revocation_present (ctrl_t ctrl, kbnode_t keyblock);
|
||||
static int import_one (ctrl_t ctrl,
|
||||
const char *fname, KBNODE keyblock,struct stats_s *stats,
|
||||
unsigned char **fpr,size_t *fpr_len,
|
||||
unsigned int options,int from_sk);
|
||||
static int import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||
struct stats_s *stats, unsigned int options);
|
||||
static int import_revoke_cert( const char *fname, KBNODE node,
|
||||
@ -265,7 +266,8 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats,
|
||||
|
||||
while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
|
||||
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
|
||||
rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0);
|
||||
rc = import_one (ctrl, fname, keyblock,
|
||||
stats, fpr, fpr_len, options, 0);
|
||||
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
|
||||
rc = import_secret_one (ctrl, fname, keyblock, stats, options);
|
||||
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
|
||||
@ -614,9 +616,9 @@ check_prefs_warning(PKT_public_key *pk)
|
||||
}
|
||||
|
||||
static void
|
||||
check_prefs(KBNODE keyblock)
|
||||
check_prefs (ctrl_t ctrl, kbnode_t keyblock)
|
||||
{
|
||||
KBNODE node;
|
||||
kbnode_t node;
|
||||
PKT_public_key *pk;
|
||||
int problem=0;
|
||||
|
||||
@ -711,7 +713,7 @@ check_prefs(KBNODE keyblock)
|
||||
append_to_strlist(&sl,"updpref");
|
||||
append_to_strlist(&sl,"save");
|
||||
|
||||
keyedit_menu( username, locusr, sl, 1, 1 );
|
||||
keyedit_menu (ctrl, username, locusr, sl, 1, 1 );
|
||||
free_strlist(sl);
|
||||
free_strlist(locusr);
|
||||
}
|
||||
@ -728,7 +730,8 @@ check_prefs(KBNODE keyblock)
|
||||
* which called gpg.
|
||||
*/
|
||||
static int
|
||||
import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
||||
import_one (ctrl_t ctrl,
|
||||
const char *fname, KBNODE keyblock, struct stats_s *stats,
|
||||
unsigned char **fpr,size_t *fpr_len,unsigned int options,
|
||||
int from_sk )
|
||||
{
|
||||
@ -1060,15 +1063,15 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
||||
|
||||
if (mod_key)
|
||||
{
|
||||
revocation_present (keyblock_orig);
|
||||
revocation_present (ctrl, keyblock_orig);
|
||||
if (!from_sk && have_secret_key_with_kid (keyid))
|
||||
check_prefs (keyblock_orig);
|
||||
check_prefs (ctrl, keyblock_orig);
|
||||
}
|
||||
else if (new_key)
|
||||
{
|
||||
revocation_present (keyblock);
|
||||
revocation_present (ctrl, keyblock);
|
||||
if (!from_sk && have_secret_key_with_kid (keyid))
|
||||
check_prefs (keyblock);
|
||||
check_prefs (ctrl, keyblock);
|
||||
}
|
||||
|
||||
release_kbnode( keyblock_orig );
|
||||
@ -1425,7 +1428,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||
keystr_from_pk (pk));
|
||||
else
|
||||
{
|
||||
import_one (fname, pub_keyblock, stats,
|
||||
import_one (ctrl, fname, pub_keyblock, stats,
|
||||
NULL, NULL, opt.import_options, 1);
|
||||
/* Fixme: We should check for an invalid keyblock and
|
||||
cancel the secret key import in this case. */
|
||||
@ -1448,7 +1451,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||
keystr_from_pk (pk));
|
||||
if (is_status_enabled ())
|
||||
print_import_ok (pk, 1|16);
|
||||
check_prefs (node);
|
||||
check_prefs (ctrl, node);
|
||||
}
|
||||
release_kbnode (node);
|
||||
}
|
||||
@ -2051,10 +2054,10 @@ collapse_uids( KBNODE *keyblock )
|
||||
present. This may be called without the benefit of merge_xxxx so
|
||||
you can't rely on pk->revkey and friends. */
|
||||
static void
|
||||
revocation_present(KBNODE keyblock)
|
||||
revocation_present (ctrl_t ctrl, kbnode_t keyblock)
|
||||
{
|
||||
KBNODE onode,inode;
|
||||
PKT_public_key *pk=keyblock->pkt->pkt.public_key;
|
||||
kbnode_t onode, inode;
|
||||
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
|
||||
|
||||
for(onode=keyblock->next;onode;onode=onode->next)
|
||||
{
|
||||
@ -2106,9 +2109,10 @@ revocation_present(KBNODE keyblock)
|
||||
log_info(_("WARNING: key %s may be revoked:"
|
||||
" fetching revocation key %s\n"),
|
||||
tempkeystr,keystr(keyid));
|
||||
keyserver_import_fprint(sig->revkey[idx]->fpr,
|
||||
MAX_FINGERPRINT_LEN,
|
||||
opt.keyserver);
|
||||
keyserver_import_fprint (ctrl,
|
||||
sig->revkey[idx]->fpr,
|
||||
MAX_FINGERPRINT_LEN,
|
||||
opt.keyserver);
|
||||
|
||||
/* Do we have it now? */
|
||||
rc=get_pubkey_byfprint_fast (NULL,
|
||||
|
@ -157,8 +157,10 @@ void show_revocation_reason( PKT_public_key *pk, int mode );
|
||||
int check_signatures_trust( PKT_signature *sig );
|
||||
|
||||
void release_pk_list (PK_LIST pk_list);
|
||||
int build_pk_list (strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use);
|
||||
gpg_error_t find_and_check_key (const char *name, unsigned int use,
|
||||
int build_pk_list (ctrl_t ctrl,
|
||||
strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use);
|
||||
gpg_error_t find_and_check_key (ctrl_t ctrl,
|
||||
const char *name, unsigned int use,
|
||||
int mark_hidden, pk_list_t *pk_list_addr);
|
||||
|
||||
int algo_available( preftype_t preftype, int algo,
|
||||
@ -204,7 +206,8 @@ void getkey_disable_caches(void);
|
||||
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
||||
int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
|
||||
KBNODE get_pubkeyblock( u32 *keyid );
|
||||
int get_pubkey_byname (GETKEY_CTX *rx, PKT_public_key *pk, const char *name,
|
||||
int get_pubkey_byname (ctrl_t ctrl,
|
||||
GETKEY_CTX *rx, PKT_public_key *pk, const char *name,
|
||||
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
||||
int include_unusable, int no_akl );
|
||||
int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
|
||||
|
@ -60,7 +60,7 @@ static void menu_deluid (KBNODE pub_keyblock);
|
||||
static int menu_delsig (KBNODE pub_keyblock);
|
||||
static int menu_clean (KBNODE keyblock, int self_only);
|
||||
static void menu_delkey (KBNODE pub_keyblock);
|
||||
static int menu_addrevoker (KBNODE pub_keyblock, int sensitive);
|
||||
static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
|
||||
static int menu_expire (KBNODE pub_keyblock);
|
||||
static int menu_backsign (KBNODE pub_keyblock);
|
||||
static int menu_set_primary_uid (KBNODE pub_keyblock);
|
||||
@ -1586,7 +1586,7 @@ keyedit_completion (const char *text, int start, int end)
|
||||
|
||||
/* Main function of the menu driven key editor. */
|
||||
void
|
||||
keyedit_menu (const char *username, strlist_t locusr,
|
||||
keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
||||
strlist_t commands, int quiet, int seckey_check)
|
||||
{
|
||||
enum cmdids cmd = 0;
|
||||
@ -1599,7 +1599,6 @@ keyedit_menu (const char *username, strlist_t locusr,
|
||||
int modified = 0;
|
||||
int toggle;
|
||||
int have_commands = !!commands;
|
||||
ctrl_t ctrl = NULL; /* Dummy for now. */
|
||||
|
||||
if (opt.command_fd != -1)
|
||||
;
|
||||
@ -1623,7 +1622,7 @@ keyedit_menu (const char *username, strlist_t locusr,
|
||||
#endif
|
||||
|
||||
/* Get the public key */
|
||||
err = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
|
||||
err = get_pubkey_byname (ctrl, NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
|
||||
if (err)
|
||||
goto leave;
|
||||
if (fix_keyblock (keyblock))
|
||||
@ -2095,7 +2094,7 @@ keyedit_menu (const char *username, strlist_t locusr,
|
||||
|
||||
if (ascii_strcasecmp (arg_string, "sensitive") == 0)
|
||||
sensitive = 1;
|
||||
if (menu_addrevoker (keyblock, sensitive))
|
||||
if (menu_addrevoker (ctrl, keyblock, sensitive))
|
||||
{
|
||||
redisplay = 1;
|
||||
modified = 1;
|
||||
@ -2886,9 +2885,10 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
|
||||
if (pk->is_revoked)
|
||||
{
|
||||
char *user = get_user_id_string_native (pk->revoked.keyid);
|
||||
const char *algo = gcry_pk_algo_name (pk->revoked.algo);
|
||||
tty_printf (_("This key was revoked on %s by %s key %s\n"),
|
||||
revokestr_from_pk (pk), algo ? algo : "?", user);
|
||||
tty_printf (_("The following key was revoked on"
|
||||
" %s by %s key %s\n"),
|
||||
revokestr_from_pk (pk),
|
||||
gcry_pk_algo_name (pk->revoked.algo), user);
|
||||
xfree (user);
|
||||
}
|
||||
|
||||
@ -3444,7 +3444,7 @@ menu_delkey (KBNODE pub_keyblock)
|
||||
* the keyblock. Returns true if there is a new revoker.
|
||||
*/
|
||||
static int
|
||||
menu_addrevoker (KBNODE pub_keyblock, int sensitive)
|
||||
menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive)
|
||||
{
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_public_key *revoker_pk = NULL;
|
||||
@ -3508,7 +3508,7 @@ menu_addrevoker (KBNODE pub_keyblock, int sensitive)
|
||||
primary keys only, but some casual testing shows that PGP and
|
||||
GnuPG both can handle a designated revocation from a subkey. */
|
||||
revoker_pk->req_usage = PUBKEY_USAGE_CERT;
|
||||
rc = get_pubkey_byname (NULL, revoker_pk, answer, NULL, NULL, 1, 1);
|
||||
rc = get_pubkey_byname (ctrl, NULL, revoker_pk, answer, NULL, NULL, 1, 1);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("key \"%s\" not found: %s\n"), answer,
|
||||
|
@ -1123,7 +1123,7 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
|
||||
{
|
||||
for (i=0; i<idx; i++)
|
||||
{
|
||||
xfree (array[i]);
|
||||
gcry_mpi_release (array[i]);
|
||||
array[i] = NULL;
|
||||
}
|
||||
gcry_sexp_release (list);
|
||||
|
14
g10/keyid.c
14
g10/keyid.c
@ -242,9 +242,12 @@ keystr_with_sub (u32 *main_kid, u32 *sub_kid)
|
||||
char *p;
|
||||
|
||||
mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
|
||||
p = buffer + strlen (buffer);
|
||||
*p++ = '/';
|
||||
mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
|
||||
if (sub_kid)
|
||||
{
|
||||
p = buffer + strlen (buffer);
|
||||
*p++ = '/';
|
||||
mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -262,9 +265,10 @@ const char *
|
||||
keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
|
||||
{
|
||||
keyid_from_pk (main_pk, NULL);
|
||||
keyid_from_pk (sub_pk, NULL);
|
||||
if (sub_pk)
|
||||
keyid_from_pk (sub_pk, NULL);
|
||||
|
||||
return keystr_with_sub (main_pk->keyid, sub_pk->keyid);
|
||||
return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
static void list_all (int);
|
||||
static void list_one (strlist_t names, int secret);
|
||||
static void locate_one (strlist_t names);
|
||||
static void locate_one (ctrl_t ctrl, strlist_t names);
|
||||
static void print_card_serialno (PKT_public_key *sk);
|
||||
|
||||
struct sig_stats
|
||||
@ -61,7 +61,7 @@ static estream_t attrib_fp;
|
||||
With LOCATE_MODE set the locate algorithm is used to find a
|
||||
key. */
|
||||
void
|
||||
public_key_list (strlist_t list, int locate_mode)
|
||||
public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
|
||||
{
|
||||
if (opt.with_colons)
|
||||
{
|
||||
@ -107,7 +107,7 @@ public_key_list (strlist_t list, int locate_mode)
|
||||
check_trustdb_stale ();
|
||||
|
||||
if (locate_mode)
|
||||
locate_one (list);
|
||||
locate_one (ctrl, list);
|
||||
else if (!list)
|
||||
list_all (0);
|
||||
else
|
||||
@ -116,8 +116,10 @@ public_key_list (strlist_t list, int locate_mode)
|
||||
|
||||
|
||||
void
|
||||
secret_key_list (strlist_t list)
|
||||
secret_key_list (ctrl_t ctrl, strlist_t list)
|
||||
{
|
||||
(void)ctrl;
|
||||
|
||||
check_trustdb_stale ();
|
||||
|
||||
if (!list)
|
||||
@ -533,7 +535,7 @@ list_one (strlist_t names, int secret)
|
||||
|
||||
|
||||
static void
|
||||
locate_one (strlist_t names)
|
||||
locate_one (ctrl_t ctrl, strlist_t names)
|
||||
{
|
||||
int rc = 0;
|
||||
strlist_t sl;
|
||||
@ -545,7 +547,7 @@ locate_one (strlist_t names)
|
||||
|
||||
for (sl = names; sl; sl = sl->next)
|
||||
{
|
||||
rc = get_pubkey_byname (&ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
|
||||
rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
|
||||
if (rc)
|
||||
{
|
||||
if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
|
||||
|
@ -33,20 +33,23 @@ struct keyserver_spec *parse_keyserver_uri(const char *string,
|
||||
const char *configname,
|
||||
unsigned int configlineno);
|
||||
struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig);
|
||||
int keyserver_export(strlist_t users);
|
||||
int keyserver_import(strlist_t users);
|
||||
int keyserver_import_fprint(const byte *fprint,size_t fprint_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver);
|
||||
int keyserver_refresh(strlist_t users);
|
||||
int keyserver_search(strlist_t tokens);
|
||||
int keyserver_fetch(strlist_t urilist);
|
||||
int keyserver_import_cert(const char *name,
|
||||
unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_import_ldap(const char *name,
|
||||
unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_export (ctrl_t ctrl, strlist_t users);
|
||||
int keyserver_import (ctrl_t ctrl, strlist_t users);
|
||||
int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_refresh (ctrl_t ctrl, strlist_t users);
|
||||
int keyserver_search (ctrl_t ctrl, strlist_t tokens);
|
||||
int keyserver_fetch (ctrl_t ctrl, strlist_t urilist);
|
||||
int keyserver_import_cert (ctrl_t ctrl, const char *name,
|
||||
unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_import_pka (ctrl_t ctrl,
|
||||
const char *name,unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_import_name (ctrl_t ctrl,
|
||||
const char *name,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_import_ldap (ctrl_t ctrl, const char *name,
|
||||
unsigned char **fpr,size_t *fpr_len);
|
||||
|
||||
#endif /* !_KEYSERVER_INTERNAL_H_ */
|
||||
|
112
g10/keyserver.c
112
g10/keyserver.c
@ -89,10 +89,10 @@ static struct parse_options keyserver_opts[]=
|
||||
{NULL,0,NULL,NULL}
|
||||
};
|
||||
|
||||
static int keyserver_work(enum ks_action action,strlist_t list,
|
||||
KEYDB_SEARCH_DESC *desc,int count,
|
||||
unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
static int keyserver_work (ctrl_t ctrl, enum ks_action action,strlist_t list,
|
||||
KEYDB_SEARCH_DESC *desc,int count,
|
||||
unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
|
||||
/* Reasonable guess */
|
||||
#define DEFAULT_MAX_CERT_SIZE 16384
|
||||
@ -732,7 +732,8 @@ parse_keyrec(char *keystring)
|
||||
(cosmetics, really) and to better take advantage of the keyservers
|
||||
that can do multiple fetches in one go (LDAP). */
|
||||
static int
|
||||
show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
|
||||
show_prompt (ctrl_t ctrl,
|
||||
KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
|
||||
{
|
||||
char *answer;
|
||||
|
||||
@ -765,8 +766,8 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
|
||||
|
||||
while((num=strsep(&split," ,"))!=NULL)
|
||||
if(atoi(num)>=1 && atoi(num)<=numdesc)
|
||||
keyserver_work(KS_GET,NULL,&desc[atoi(num)-1],1,
|
||||
NULL,NULL,opt.keyserver);
|
||||
keyserver_work (ctrl, KS_GET,NULL,&desc[atoi(num)-1],1,
|
||||
NULL,NULL,opt.keyserver);
|
||||
|
||||
xfree(answer);
|
||||
return 1;
|
||||
@ -779,7 +780,7 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
|
||||
small, it will grow safely. If negative it disables the "Key x-y
|
||||
of z" messages. searchstr should be UTF-8 (rather than native). */
|
||||
static void
|
||||
keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
||||
keyserver_search_prompt (ctrl_t ctrl, IOBUF buffer,const char *searchstr)
|
||||
{
|
||||
int i=0,validcount=0,started=0,header=0,count=1;
|
||||
unsigned int maxlen,buflen,numlines=0;
|
||||
@ -872,7 +873,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(show_prompt(desc,i,validcount?count:0,localstr))
|
||||
if (show_prompt (ctrl, desc, i, validcount?count:0, localstr))
|
||||
break;
|
||||
validcount=0;
|
||||
}
|
||||
@ -901,7 +902,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
||||
/* screen_lines - 1 for the prompt. */
|
||||
if(numlines+keyrec->lines>opt.screen_lines-1)
|
||||
{
|
||||
if(show_prompt(desc,i,validcount?count:0,localstr))
|
||||
if (show_prompt (ctrl, desc, i, validcount?count:0, localstr))
|
||||
break;
|
||||
else
|
||||
numlines=0;
|
||||
@ -977,9 +978,10 @@ direct_uri_map(const char *scheme,unsigned int is_direct)
|
||||
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
|
||||
|
||||
static int
|
||||
keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
int count,int *prog,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
keyserver_spawn (ctrl_t ctrl,
|
||||
enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
int count,int *prog,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
{
|
||||
int ret=0,i,gotversion=0,outofband=0;
|
||||
strlist_t temp;
|
||||
@ -1243,8 +1245,8 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
/* TODO: Remove Comment: lines from keys exported this
|
||||
way? */
|
||||
|
||||
if(export_pubkeys_stream(buffer,temp,&block,
|
||||
opt.keyserver_options.export_options)==-1)
|
||||
if(export_pubkeys_stream (ctrl, buffer,temp,&block,
|
||||
opt.keyserver_options.export_options)==-1)
|
||||
iobuf_close(buffer);
|
||||
else
|
||||
{
|
||||
@ -1510,7 +1512,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
break;
|
||||
|
||||
case KS_SEARCH:
|
||||
keyserver_search_prompt(spawn->fromchild,searchstr);
|
||||
keyserver_search_prompt (ctrl, spawn->fromchild,searchstr);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1529,9 +1531,10 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
}
|
||||
|
||||
static int
|
||||
keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
int count,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
keyserver_work (ctrl_t ctrl,
|
||||
enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
int count,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
{
|
||||
int rc=0,ret=0;
|
||||
|
||||
@ -1549,7 +1552,8 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
#else
|
||||
/* Spawn a handler */
|
||||
|
||||
rc=keyserver_spawn(action,list,desc,count,&ret,fpr,fpr_len,keyserver);
|
||||
rc = keyserver_spawn (ctrl, action, list, desc, count,
|
||||
&ret, fpr, fpr_len, keyserver);
|
||||
if(ret)
|
||||
{
|
||||
switch(ret)
|
||||
@ -1599,7 +1603,7 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_export(strlist_t users)
|
||||
keyserver_export (ctrl_t ctrl, strlist_t users)
|
||||
{
|
||||
gpg_error_t err;
|
||||
strlist_t sl=NULL;
|
||||
@ -1624,7 +1628,7 @@ keyserver_export(strlist_t users)
|
||||
|
||||
if(sl)
|
||||
{
|
||||
rc=keyserver_work(KS_SEND,sl,NULL,0,NULL,NULL,opt.keyserver);
|
||||
rc = keyserver_work (ctrl, KS_SEND,sl,NULL,0,NULL,NULL,opt.keyserver);
|
||||
free_strlist(sl);
|
||||
}
|
||||
|
||||
@ -1632,7 +1636,7 @@ keyserver_export(strlist_t users)
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_import(strlist_t users)
|
||||
keyserver_import (ctrl_t ctrl, strlist_t users)
|
||||
{
|
||||
gpg_error_t err;
|
||||
KEYDB_SEARCH_DESC *desc;
|
||||
@ -1663,7 +1667,8 @@ keyserver_import(strlist_t users)
|
||||
}
|
||||
|
||||
if(count>0)
|
||||
rc=keyserver_work(KS_GET,NULL,desc,count,NULL,NULL,opt.keyserver);
|
||||
rc=keyserver_work (ctrl, KS_GET, NULL, desc, count,
|
||||
NULL, NULL, opt.keyserver);
|
||||
|
||||
xfree(desc);
|
||||
|
||||
@ -1671,8 +1676,8 @@ keyserver_import(strlist_t users)
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_import_fprint(const byte *fprint,size_t fprint_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
{
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
|
||||
@ -1689,11 +1694,12 @@ keyserver_import_fprint(const byte *fprint,size_t fprint_len,
|
||||
|
||||
/* TODO: Warn here if the fingerprint we got doesn't match the one
|
||||
we asked for? */
|
||||
return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
|
||||
return keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, keyserver);
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver)
|
||||
keyserver_import_keyid (ctrl_t ctrl,
|
||||
u32 *keyid,struct keyserver_spec *keyserver)
|
||||
{
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
|
||||
@ -1703,7 +1709,7 @@ keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver)
|
||||
desc.u.kid[0]=keyid[0];
|
||||
desc.u.kid[1]=keyid[1];
|
||||
|
||||
return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
|
||||
return keyserver_work (ctrl, KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
|
||||
}
|
||||
|
||||
/* code mostly stolen from do_export_stream */
|
||||
@ -1865,7 +1871,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
|
||||
usernames to refresh only part of the keyring. */
|
||||
|
||||
int
|
||||
keyserver_refresh(strlist_t users)
|
||||
keyserver_refresh (ctrl_t ctrl, strlist_t users)
|
||||
{
|
||||
int rc,count,numdesc,fakev3=0;
|
||||
KEYDB_SEARCH_DESC *desc;
|
||||
@ -1908,7 +1914,8 @@ keyserver_refresh(strlist_t users)
|
||||
Note that a preferred keyserver without a scheme://
|
||||
will be interpreted as hkp:// */
|
||||
|
||||
rc=keyserver_work(KS_GET,NULL,&desc[i],1,NULL,NULL,keyserver);
|
||||
rc = keyserver_work (ctrl, KS_GET, NULL, &desc[i], 1,
|
||||
NULL, NULL, keyserver);
|
||||
if(rc)
|
||||
log_info(_("WARNING: unable to refresh key %s"
|
||||
" via %s: %s\n"),keystr_from_desc(&desc[i]),
|
||||
@ -1938,7 +1945,8 @@ keyserver_refresh(strlist_t users)
|
||||
count,opt.keyserver->uri);
|
||||
}
|
||||
|
||||
rc=keyserver_work(KS_GET,NULL,desc,numdesc,NULL,NULL,opt.keyserver);
|
||||
rc=keyserver_work (ctrl, KS_GET, NULL, desc, numdesc,
|
||||
NULL, NULL, opt.keyserver);
|
||||
}
|
||||
|
||||
xfree(desc);
|
||||
@ -1954,16 +1962,16 @@ keyserver_refresh(strlist_t users)
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_search(strlist_t tokens)
|
||||
keyserver_search (ctrl_t ctrl, strlist_t tokens)
|
||||
{
|
||||
if(tokens)
|
||||
return keyserver_work(KS_SEARCH,tokens,NULL,0,NULL,NULL,opt.keyserver);
|
||||
else
|
||||
return 0;
|
||||
if (tokens)
|
||||
return keyserver_work (ctrl, KS_SEARCH, tokens, NULL, 0,
|
||||
NULL, NULL, opt.keyserver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_fetch(strlist_t urilist)
|
||||
keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
|
||||
{
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
strlist_t sl;
|
||||
@ -1988,7 +1996,7 @@ keyserver_fetch(strlist_t urilist)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc=keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,spec);
|
||||
rc = keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, spec);
|
||||
if(rc)
|
||||
log_info (_("WARNING: unable to fetch URI %s: %s\n"),
|
||||
sl->d,g10_errstr(rc));
|
||||
@ -2011,7 +2019,8 @@ keyserver_fetch(strlist_t urilist)
|
||||
|
||||
/* Import key in a CERT or pointed to by a CERT */
|
||||
int
|
||||
keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
keyserver_import_cert (ctrl_t ctrl,
|
||||
const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
{
|
||||
char *domain,*look,*url;
|
||||
IOBUF key;
|
||||
@ -2058,7 +2067,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
spec=parse_keyserver_uri(url,1,NULL,0);
|
||||
if(spec)
|
||||
{
|
||||
rc=keyserver_import_fprint(*fpr,*fpr_len,spec);
|
||||
rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec);
|
||||
free_keyserver_spec(spec);
|
||||
}
|
||||
}
|
||||
@ -2067,7 +2076,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
/* If only a fingerprint is provided, try and fetch it from
|
||||
our --keyserver */
|
||||
|
||||
rc=keyserver_import_fprint(*fpr,*fpr_len,opt.keyserver);
|
||||
rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver);
|
||||
}
|
||||
else
|
||||
log_info(_("no keyserver known (use option --keyserver)\n"));
|
||||
@ -2087,7 +2096,8 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
/* Import key pointed to by a PKA record. Return the requested
|
||||
fingerprint in fpr. */
|
||||
int
|
||||
keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
keyserver_import_pka (ctrl_t ctrl,
|
||||
const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
{
|
||||
char *uri;
|
||||
int rc = G10ERR_NO_PUBKEY;
|
||||
@ -2103,7 +2113,7 @@ keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
spec = parse_keyserver_uri (uri, 1, NULL, 0);
|
||||
if (spec)
|
||||
{
|
||||
rc = keyserver_import_fprint (*fpr, 20, spec);
|
||||
rc = keyserver_import_fprint (ctrl, *fpr, 20, spec);
|
||||
free_keyserver_spec (spec);
|
||||
}
|
||||
xfree (uri);
|
||||
@ -2120,15 +2130,17 @@ keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
|
||||
/* Import all keys that match name */
|
||||
int
|
||||
keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
keyserver_import_name (ctrl_t ctrl, const char *name,
|
||||
unsigned char **fpr, size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
{
|
||||
strlist_t list=NULL;
|
||||
int rc;
|
||||
|
||||
append_to_strlist(&list,name);
|
||||
|
||||
rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver);
|
||||
rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
|
||||
0, fpr, fpr_len, keyserver);
|
||||
|
||||
free_strlist(list);
|
||||
|
||||
@ -2137,7 +2149,8 @@ keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
|
||||
|
||||
/* Import a key by name using LDAP */
|
||||
int
|
||||
keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
keyserver_import_ldap (ctrl_t ctrl,
|
||||
const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
{
|
||||
char *domain;
|
||||
struct keyserver_spec *keyserver;
|
||||
@ -2200,7 +2213,8 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
|
||||
append_to_strlist(&list,name);
|
||||
|
||||
rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver);
|
||||
rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
|
||||
0, fpr, fpr_len, keyserver);
|
||||
|
||||
free_strlist(list);
|
||||
|
||||
|
35
g10/main.h
35
g10/main.h
@ -192,10 +192,11 @@ void display_online_help( const char *keyword );
|
||||
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
||||
int encrypt_symmetric (const char *filename );
|
||||
int encrypt_store (const char *filename );
|
||||
int encrypt_crypt (int filefd, const char *filename,
|
||||
int encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
|
||||
int outputfd);
|
||||
void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr);
|
||||
void encrypt_crypt_files (ctrl_t ctrl,
|
||||
int nfiles, char **files, strlist_t remusr);
|
||||
int encrypt_filter (void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len);
|
||||
|
||||
@ -203,7 +204,7 @@ int encrypt_filter (void *opaque, int control,
|
||||
/*-- sign.c --*/
|
||||
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
|
||||
const char *cache_nonce);
|
||||
int sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
int sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
|
||||
int do_encrypt, strlist_t remusr, const char *outfile );
|
||||
int clearsign_file( const char *fname, strlist_t locusr, const char *outfile );
|
||||
int sign_symencrypt_file (const char *fname, strlist_t locusr);
|
||||
@ -221,7 +222,7 @@ int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
int delete_keys( strlist_t names, int secret, int allow_both );
|
||||
|
||||
/*-- keyedit.c --*/
|
||||
void keyedit_menu( const char *username, strlist_t locusr,
|
||||
void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
||||
strlist_t commands, int quiet, int seckey_check );
|
||||
void keyedit_passwd (const char *username);
|
||||
void show_basic_key_info (KBNODE keyblock);
|
||||
@ -280,11 +281,11 @@ int collapse_uids( KBNODE *keyblock );
|
||||
|
||||
/*-- export.c --*/
|
||||
int parse_export_options(char *str,unsigned int *options,int noisy);
|
||||
int export_pubkeys( strlist_t users, unsigned int options );
|
||||
int export_pubkeys_stream( iobuf_t out, strlist_t users,
|
||||
KBNODE *keyblock_out, unsigned int options );
|
||||
int export_seckeys( strlist_t users );
|
||||
int export_secsubkeys( strlist_t users );
|
||||
int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options );
|
||||
int export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
|
||||
kbnode_t *keyblock_out, unsigned int options );
|
||||
int export_seckeys (ctrl_t ctrl, strlist_t users);
|
||||
int export_secsubkeys (ctrl_t ctrl, strlist_t users);
|
||||
|
||||
/* dearmor.c --*/
|
||||
int dearmor_file( const char *fname );
|
||||
@ -300,8 +301,8 @@ struct revocation_reason_info *
|
||||
void release_revocation_reason_info( struct revocation_reason_info *reason );
|
||||
|
||||
/*-- keylist.c --*/
|
||||
void public_key_list( strlist_t list, int locate_mode );
|
||||
void secret_key_list( strlist_t list );
|
||||
void public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode );
|
||||
void secret_key_list (ctrl_t ctrl, strlist_t list );
|
||||
void print_subpackets_colon(PKT_signature *sig);
|
||||
void reorder_keyblock (KBNODE keyblock);
|
||||
void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
|
||||
@ -318,14 +319,14 @@ void print_card_key_info (estream_t fp, KBNODE keyblock);
|
||||
|
||||
/*-- verify.c --*/
|
||||
void print_file_status( int status, const char *name, int what );
|
||||
int verify_signatures( int nfiles, char **files );
|
||||
int verify_files( int nfiles, char **files );
|
||||
int verify_signatures (ctrl_t ctrl, int nfiles, char **files );
|
||||
int verify_files (ctrl_t ctrl, int nfiles, char **files );
|
||||
int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp);
|
||||
|
||||
/*-- decrypt.c --*/
|
||||
int decrypt_message( const char *filename );
|
||||
gpg_error_t decrypt_message_fd (int input_fd, int output_fd);
|
||||
void decrypt_messages(int nfiles, char *files[]);
|
||||
int decrypt_message (ctrl_t ctrl, const char *filename );
|
||||
gpg_error_t decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd);
|
||||
void decrypt_messages (ctrl_t ctrl, int nfiles, char *files[]);
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2,
|
||||
@ -346,7 +347,7 @@ int gpg_server (ctrl_t);
|
||||
/*-- card-util.c --*/
|
||||
void change_pin (int no, int allow_admin);
|
||||
void card_status (estream_t fp, char *serialno, size_t serialnobuflen);
|
||||
void card_edit (strlist_t commands);
|
||||
void card_edit (ctrl_t ctrl, strlist_t commands);
|
||||
int card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
|
||||
int card_store_subkey (KBNODE node, int use);
|
||||
#endif
|
||||
|
@ -26,10 +26,10 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "options.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "keydb.h"
|
||||
#include "filter.h"
|
||||
@ -56,6 +56,7 @@ struct kidlist_item {
|
||||
typedef struct mainproc_context *CTX;
|
||||
struct mainproc_context
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
struct mainproc_context *anchor; /* May be useful in the future. */
|
||||
PKT_public_key *last_pubkey;
|
||||
PKT_user_id *last_user_id;
|
||||
@ -563,8 +564,8 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
}
|
||||
else if( !c->dek )
|
||||
result = G10ERR_NO_SECKEY;
|
||||
if( !result )
|
||||
result = decrypt_data( c, pkt->pkt.encrypted, c->dek );
|
||||
if (!result)
|
||||
result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
|
||||
|
||||
if( result == -1 )
|
||||
;
|
||||
@ -757,18 +758,19 @@ proc_compressed_cb( IOBUF a, void *info )
|
||||
{
|
||||
if ( ((CTX)info)->signed_data.used
|
||||
&& ((CTX)info)->signed_data.data_fd != -1)
|
||||
return proc_signature_packets_by_fd (info, a,
|
||||
return proc_signature_packets_by_fd (((CTX)info)->ctrl, info, a,
|
||||
((CTX)info)->signed_data.data_fd);
|
||||
else
|
||||
return proc_signature_packets (info, a,
|
||||
return proc_signature_packets (((CTX)info)->ctrl, info, a,
|
||||
((CTX)info)->signed_data.data_names,
|
||||
((CTX)info)->sigfilename );
|
||||
}
|
||||
|
||||
static int
|
||||
proc_encrypt_cb( IOBUF a, void *info )
|
||||
proc_encrypt_cb (IOBUF a, void *info )
|
||||
{
|
||||
return proc_encryption_packets( info, a );
|
||||
CTX c = info;
|
||||
return proc_encryption_packets (c->ctrl, info, a );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -781,11 +783,11 @@ proc_compressed( CTX c, PACKET *pkt )
|
||||
if( !zd->algorithm )
|
||||
rc=G10ERR_COMPR_ALGO;
|
||||
else if( c->sigs_only )
|
||||
rc = handle_compressed( c, zd, proc_compressed_cb, c );
|
||||
rc = handle_compressed (c->ctrl, c, zd, proc_compressed_cb, c );
|
||||
else if( c->encrypt_only )
|
||||
rc = handle_compressed( c, zd, proc_encrypt_cb, c );
|
||||
rc = handle_compressed (c->ctrl, c, zd, proc_encrypt_cb, c );
|
||||
else
|
||||
rc = handle_compressed( c, zd, NULL, NULL );
|
||||
rc = handle_compressed (c->ctrl, c, zd, NULL, NULL );
|
||||
if( rc )
|
||||
log_error("uncompressing failed: %s\n", g10_errstr(rc));
|
||||
free_packet(pkt);
|
||||
@ -1174,11 +1176,12 @@ list_node( CTX c, KBNODE node )
|
||||
|
||||
|
||||
int
|
||||
proc_packets( void *anchor, IOBUF a )
|
||||
proc_packets (ctrl_t ctrl, void *anchor, IOBUF a )
|
||||
{
|
||||
int rc;
|
||||
CTX c = xmalloc_clear( sizeof *c );
|
||||
|
||||
c->ctrl = ctrl;
|
||||
c->anchor = anchor;
|
||||
rc = do_proc_packets( c, a );
|
||||
xfree( c );
|
||||
@ -1188,12 +1191,13 @@ proc_packets( void *anchor, IOBUF a )
|
||||
|
||||
|
||||
int
|
||||
proc_signature_packets( void *anchor, IOBUF a,
|
||||
proc_signature_packets (ctrl_t ctrl, void *anchor, IOBUF a,
|
||||
strlist_t signedfiles, const char *sigfilename )
|
||||
{
|
||||
CTX c = xmalloc_clear( sizeof *c );
|
||||
int rc;
|
||||
|
||||
c->ctrl = ctrl;
|
||||
c->anchor = anchor;
|
||||
c->sigs_only = 1;
|
||||
|
||||
@ -1228,7 +1232,8 @@ proc_signature_packets( void *anchor, IOBUF a,
|
||||
|
||||
|
||||
int
|
||||
proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
|
||||
proc_signature_packets_by_fd (ctrl_t ctrl,
|
||||
void *anchor, IOBUF a, int signed_data_fd )
|
||||
{
|
||||
int rc;
|
||||
CTX c;
|
||||
@ -1237,6 +1242,7 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
|
||||
if (!c)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
c->ctrl = ctrl;
|
||||
c->anchor = anchor;
|
||||
c->sigs_only = 1;
|
||||
|
||||
@ -1269,11 +1275,12 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
|
||||
|
||||
|
||||
int
|
||||
proc_encryption_packets( void *anchor, IOBUF a )
|
||||
proc_encryption_packets (ctrl_t ctrl, void *anchor, IOBUF a )
|
||||
{
|
||||
CTX c = xmalloc_clear( sizeof *c );
|
||||
int rc;
|
||||
|
||||
c->ctrl = ctrl;
|
||||
c->anchor = anchor;
|
||||
c->encrypt_only = 1;
|
||||
rc = do_proc_packets( c, a );
|
||||
@ -1652,7 +1659,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
int res;
|
||||
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
res=keyserver_import_keyid(sig->keyid,spec);
|
||||
res = keyserver_import_keyid (c->ctrl, sig->keyid,spec);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
if(!res)
|
||||
rc=do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
|
||||
@ -1684,7 +1691,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
if (spec)
|
||||
{
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
res = keyserver_import_keyid (sig->keyid, spec);
|
||||
res = keyserver_import_keyid (c->ctrl, sig->keyid, spec);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
free_keyserver_spec (spec);
|
||||
if (!res)
|
||||
@ -1702,7 +1709,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
int res;
|
||||
|
||||
glo_ctrl.in_auto_key_retrieve++;
|
||||
res=keyserver_import_keyid ( sig->keyid, opt.keyserver );
|
||||
res=keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver );
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
if(!res)
|
||||
rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
|
||||
|
@ -124,8 +124,6 @@ struct
|
||||
int s2k_cipher_algo;
|
||||
unsigned char s2k_count; /* This is the encoded form, not the raw
|
||||
count */
|
||||
int simple_sk_checksum; /* create the deprecated rfc2440 secret key
|
||||
protection */
|
||||
int not_dash_escaped;
|
||||
int escape_from;
|
||||
int lock_once;
|
||||
|
13
g10/packet.h
13
g10/packet.h
@ -370,11 +370,12 @@ struct notation
|
||||
|
||||
/*-- mainproc.c --*/
|
||||
void reset_literals_seen(void);
|
||||
int proc_packets( void *ctx, iobuf_t a );
|
||||
int proc_signature_packets( void *ctx, iobuf_t a,
|
||||
int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a );
|
||||
int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a,
|
||||
strlist_t signedfiles, const char *sigfile );
|
||||
int proc_signature_packets_by_fd ( void *anchor, IOBUF a, int signed_data_fd );
|
||||
int proc_encryption_packets( void *ctx, iobuf_t a );
|
||||
int proc_signature_packets_by_fd (ctrl_t ctrl,
|
||||
void *anchor, IOBUF a, int signed_data_fd );
|
||||
int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a);
|
||||
int list_packets( iobuf_t a );
|
||||
|
||||
/*-- parse-packet.c --*/
|
||||
@ -475,11 +476,11 @@ gpg_error_t get_session_key (PKT_pubkey_enc *k, DEK *dek);
|
||||
gpg_error_t get_override_session_key (DEK *dek, const char *string);
|
||||
|
||||
/*-- compress.c --*/
|
||||
int handle_compressed( void *ctx, PKT_compressed *cd,
|
||||
int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd,
|
||||
int (*callback)(iobuf_t, void *), void *passthru );
|
||||
|
||||
/*-- encr-data.c --*/
|
||||
int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek );
|
||||
int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
|
@ -25,9 +25,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "filter.h"
|
||||
#include "photoid.h"
|
||||
|
@ -29,11 +29,11 @@
|
||||
#endif
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "status.h"
|
||||
#include "exec.h"
|
||||
#include "keydb.h"
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
#include "iobuf.h"
|
||||
#include "options.h"
|
||||
|
@ -778,7 +778,7 @@ expand_group(strlist_t input)
|
||||
of the key. USE the requested usage and a set MARK_HIDDEN will mark
|
||||
the key in the updated list as a hidden recipient. */
|
||||
gpg_error_t
|
||||
find_and_check_key (const char *name, unsigned int use,
|
||||
find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
|
||||
int mark_hidden, pk_list_t *pk_list_addr)
|
||||
{
|
||||
int rc;
|
||||
@ -793,7 +793,7 @@ find_and_check_key (const char *name, unsigned int use,
|
||||
return gpg_error_from_syserror ();
|
||||
pk->req_usage = use;
|
||||
|
||||
rc = get_pubkey_byname (NULL, pk, name, NULL, NULL, 0, 0);
|
||||
rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0);
|
||||
if (rc)
|
||||
{
|
||||
/* Key not found or other error. */
|
||||
@ -883,7 +883,8 @@ find_and_check_key (const char *name, unsigned int use,
|
||||
not changed.
|
||||
*/
|
||||
int
|
||||
build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
||||
build_pk_list (ctrl_t ctrl,
|
||||
strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
||||
{
|
||||
PK_LIST pk_list = NULL;
|
||||
PKT_public_key *pk=NULL;
|
||||
@ -929,7 +930,8 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
||||
/* We explicitly allow encrypt-to to an disabled key; thus
|
||||
we pass 1for the second last argument and 1 as the last
|
||||
argument to disable AKL. */
|
||||
if ( (rc = get_pubkey_byname (NULL, pk, rov->d, NULL, NULL, 1, 1)) )
|
||||
if ( (rc = get_pubkey_byname (ctrl,
|
||||
NULL, pk, rov->d, NULL, NULL, 1, 1)) )
|
||||
{
|
||||
free_public_key ( pk ); pk = NULL;
|
||||
log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
||||
@ -1066,7 +1068,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
||||
free_public_key (pk);
|
||||
pk = xmalloc_clear( sizeof *pk );
|
||||
pk->req_usage = use;
|
||||
rc = get_pubkey_byname (NULL, pk, answer, NULL, NULL, 0, 0 );
|
||||
rc = get_pubkey_byname (ctrl, NULL, pk, answer, NULL, NULL, 0, 0 );
|
||||
if (rc)
|
||||
tty_printf(_("No such user ID.\n"));
|
||||
else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
|
||||
@ -1140,7 +1142,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
||||
|
||||
/* The default recipient is allowed to be disabled; thus pass 1
|
||||
as second last argument. We also don't want an AKL. */
|
||||
rc = get_pubkey_byname (NULL, pk, def_rec, NULL, NULL, 1, 1);
|
||||
rc = get_pubkey_byname (ctrl, NULL, pk, def_rec, NULL, NULL, 1, 1);
|
||||
if (rc)
|
||||
log_error(_("unknown default recipient \"%s\"\n"), def_rec );
|
||||
else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) )
|
||||
@ -1178,7 +1180,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
||||
if ( (remusr->flags & 1) )
|
||||
continue; /* encrypt-to keys are already handled. */
|
||||
|
||||
rc = find_and_check_key (remusr->d, use, !!(remusr->flags&2),
|
||||
rc = find_and_check_key (ctrl, remusr->d, use, !!(remusr->flags&2),
|
||||
&pk_list);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
@ -231,7 +231,7 @@ cmd_recipient (assuan_context_t ctx, char *line)
|
||||
remusr = rcpts;
|
||||
*/
|
||||
|
||||
err = find_and_check_key (line, PUBKEY_USAGE_ENC, hidden,
|
||||
err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden,
|
||||
&ctrl->server_local->recplist);
|
||||
|
||||
if (err)
|
||||
@ -324,7 +324,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
|
||||
|
||||
/* fixme: err = ctrl->audit? 0 : start_audit_session (ctrl);*/
|
||||
|
||||
err = encrypt_crypt (inp_fd, NULL, NULL, 0,
|
||||
err = encrypt_crypt (ctrl, inp_fd, NULL, NULL, 0,
|
||||
ctrl->server_local->recplist,
|
||||
out_fd);
|
||||
|
||||
@ -368,7 +368,7 @@ cmd_decrypt (assuan_context_t ctx, char *line)
|
||||
return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
|
||||
|
||||
glo_ctrl.lasterr = 0;
|
||||
err = decrypt_message_fd (inp_fd, out_fd);
|
||||
err = decrypt_message_fd (ctrl, inp_fd, out_fd);
|
||||
if (!err)
|
||||
err = glo_ctrl.lasterr;
|
||||
|
||||
|
@ -762,7 +762,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
|
||||
* uncompressed, non-armored and in binary mode.
|
||||
*/
|
||||
int
|
||||
sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
|
||||
int encryptflag, strlist_t remusr, const char *outfile )
|
||||
{
|
||||
const char *fname;
|
||||
@ -822,7 +822,8 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
||||
compliance_failure();
|
||||
}
|
||||
|
||||
if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )))
|
||||
if (encryptflag
|
||||
&& (rc=build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
|
||||
goto leave;
|
||||
|
||||
/* prepare iobufs */
|
||||
|
16
g10/verify.c
16
g10/verify.c
@ -50,7 +50,7 @@
|
||||
*/
|
||||
|
||||
int
|
||||
verify_signatures( int nfiles, char **files )
|
||||
verify_signatures (ctrl_t ctrl, int nfiles, char **files )
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t *afx = NULL;
|
||||
@ -110,7 +110,7 @@ verify_signatures( int nfiles, char **files )
|
||||
sl = NULL;
|
||||
for(i=nfiles-1 ; i > 0 ; i-- )
|
||||
add_to_strlist( &sl, files[i] );
|
||||
rc = proc_signature_packets( NULL, fp, sl, sigfile );
|
||||
rc = proc_signature_packets (ctrl, NULL, fp, sl, sigfile );
|
||||
free_strlist(sl);
|
||||
iobuf_close(fp);
|
||||
if( (afx && afx->no_openpgp_data && rc == -1) || rc == G10ERR_NO_DATA ) {
|
||||
@ -139,7 +139,7 @@ print_file_status( int status, const char *name, int what )
|
||||
|
||||
|
||||
static int
|
||||
verify_one_file( const char *name )
|
||||
verify_one_file (ctrl_t ctrl, const char *name )
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t *afx = NULL;
|
||||
@ -172,7 +172,7 @@ verify_one_file( const char *name )
|
||||
}
|
||||
}
|
||||
|
||||
rc = proc_signature_packets( NULL, fp, NULL, name );
|
||||
rc = proc_signature_packets (ctrl, NULL, fp, NULL, name );
|
||||
iobuf_close(fp);
|
||||
write_status( STATUS_FILE_DONE );
|
||||
|
||||
@ -190,7 +190,7 @@ verify_one_file( const char *name )
|
||||
* Note: This function can not handle detached signatures.
|
||||
*/
|
||||
int
|
||||
verify_files( int nfiles, char **files )
|
||||
verify_files (ctrl_t ctrl, int nfiles, char **files )
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -208,13 +208,13 @@ verify_files( int nfiles, char **files )
|
||||
* also no script languages available. We don't strip any
|
||||
* spaces, so that we can process nearly all filenames */
|
||||
line[strlen(line)-1] = 0;
|
||||
verify_one_file( line );
|
||||
verify_one_file (ctrl, line );
|
||||
}
|
||||
|
||||
}
|
||||
else { /* take filenames from the array */
|
||||
for(i=0; i < nfiles; i++ )
|
||||
verify_one_file( files[i] );
|
||||
verify_one_file (ctrl, files[i] );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -262,7 +262,7 @@ gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp)
|
||||
push_armor_filter (afx, fp);
|
||||
}
|
||||
|
||||
rc = proc_signature_packets_by_fd (NULL, fp, data_fd);
|
||||
rc = proc_signature_packets_by_fd (ctrl, NULL, fp, data_fd);
|
||||
|
||||
if ( afx && afx->no_openpgp_data
|
||||
&& (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) )
|
||||
|
@ -918,12 +918,13 @@ parse_ccid_descriptor (ccid_driver_t handle,
|
||||
|
||||
DEBUGOUT_1 (" bMaxCCIDBusySlots %5u\n", buf[53]);
|
||||
|
||||
if (buf[0] > 54) {
|
||||
DEBUGOUT (" junk ");
|
||||
for (i=54; i < buf[0]-54; i++)
|
||||
DEBUGOUT_CONT_1 (" %02X", buf[i]);
|
||||
DEBUGOUT_LF ();
|
||||
}
|
||||
if (buf[0] > 54)
|
||||
{
|
||||
DEBUGOUT (" junk ");
|
||||
for (i=54; i < buf[0]-54; i++)
|
||||
DEBUGOUT_CONT_1 (" %02X", buf[i]);
|
||||
DEBUGOUT_LF ();
|
||||
}
|
||||
|
||||
if (!have_t1 || !(have_tpdu || handle->apdu_level) || !have_auto_conf)
|
||||
{
|
||||
|
10
sm/ChangeLog
10
sm/ChangeLog
@ -1,3 +1,13 @@
|
||||
2010-09-16 Werner Koch <wk@g10code.com>
|
||||
|
||||
* certchain.c (gpgsm_walk_cert_chain): Use GPG_ERR_MISSING_ISSUER_CERT.
|
||||
(do_validate_chain): Ditto.
|
||||
(gpgsm_basic_cert_check): Ditto.
|
||||
* call-agent.c (learn_cb): Take care of new
|
||||
GPG_ERR_MISSING_ISSUER_CERT.
|
||||
* import.c (check_and_store): Ditto.
|
||||
(check_and_store): Ditto.
|
||||
|
||||
2010-08-16 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpgsm.c (main) <aGPGConfList>: Use es_printf.
|
||||
|
@ -887,7 +887,8 @@ learn_cb (void *opaque, const void *buffer, size_t length)
|
||||
because we can assume that the --learn-card command has been used
|
||||
on purpose. */
|
||||
rc = gpgsm_basic_cert_check (parm->ctrl, cert);
|
||||
if (rc && gpg_err_code (rc) != GPG_ERR_MISSING_CERT)
|
||||
if (rc && gpg_err_code (rc) != GPG_ERR_MISSING_CERT
|
||||
&& gpg_err_code (rc) != GPG_ERR_MISSING_ISSUER_CERT)
|
||||
log_error ("invalid certificate: %s\n", gpg_strerror (rc));
|
||||
else
|
||||
{
|
||||
|
@ -789,7 +789,7 @@ gpgsm_walk_cert_chain (ctrl_t ctrl, ksba_cert_t start, ksba_cert_t *r_next)
|
||||
print an error here. */
|
||||
if (rc != -1 && opt.verbose > 1)
|
||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
||||
rc = gpg_error (GPG_ERR_MISSING_CERT);
|
||||
rc = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -1496,7 +1496,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
|
||||
}
|
||||
else
|
||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
||||
rc = gpg_error (GPG_ERR_MISSING_CERT);
|
||||
rc = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -1897,7 +1897,7 @@ gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert)
|
||||
}
|
||||
else
|
||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
||||
rc = gpg_error (GPG_ERR_MISSING_CERT);
|
||||
rc = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
|
||||
ARGPARSE_s_s (oAuditLog, "audit-log",
|
||||
N_("|FILE|write an audit log to FILE")),
|
||||
ARGPARSE_s_s (oHtmlAuditLog, "html-audit-log", ""),
|
||||
ARGPARSE_s_s (oHtmlAuditLog, "html-audit-log", "@"),
|
||||
ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
|
||||
ARGPARSE_s_n (oBatch, "batch", N_("batch mode: never ask")),
|
||||
ARGPARSE_s_n (oAnswerYes, "yes", N_("assume yes on most questions")),
|
||||
|
14
sm/import.c
14
sm/import.c
@ -194,7 +194,8 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
|
||||
if (!rc && ctrl->with_validation)
|
||||
rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
|
||||
if (!rc || (!ctrl->with_validation
|
||||
&& gpg_err_code (rc) == GPG_ERR_MISSING_CERT) )
|
||||
&& (gpg_err_code (rc) == GPG_ERR_MISSING_CERT
|
||||
|| gpg_err_code (rc) == GPG_ERR_MISSING_ISSUER_CERT)))
|
||||
{
|
||||
int existed;
|
||||
|
||||
@ -253,9 +254,14 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats,
|
||||
log_error (_("basic certificate checks failed - not imported\n"));
|
||||
if (stats)
|
||||
stats->not_imported++;
|
||||
print_import_problem (ctrl, cert,
|
||||
gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
|
||||
gpg_err_code (rc) == GPG_ERR_BAD_CERT? 1 : 0);
|
||||
/* We keep the test for GPG_ERR_MISSING_CERT only in case
|
||||
GPG_ERR_MISSING_CERT has been used instead of the newer
|
||||
GPG_ERR_MISSING_ISSUER_CERT. */
|
||||
print_import_problem
|
||||
(ctrl, cert,
|
||||
gpg_err_code (rc) == GPG_ERR_MISSING_ISSUER_CERT? 2 :
|
||||
gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
|
||||
gpg_err_code (rc) == GPG_ERR_BAD_CERT? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user