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.
|
by default.
|
||||||
|
|
||||||
* Dirmngr is now a part of this package. Dirmngr is now also
|
* Dirmngr is now a part of this package. Dirmngr is now also
|
||||||
expected to run as a system service and the configuraion
|
expected to run as a system service and the configuration
|
||||||
directories are changed to the gnupg name space.
|
directories are changed to the GnuPG name space.
|
||||||
|
|
||||||
* Given sufficient permissions Dirmngr is started automagically.
|
* 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.
|
* 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)
|
Noteworthy changes in version 2.0.13 (2009-09-04)
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
@ -23,6 +23,7 @@ Release process:
|
|||||||
(Mainly config.guess and config.sub).
|
(Mainly config.guess and config.sub).
|
||||||
* [1.4 only] Update gpg.texi and gpgv.texi from the trunk:
|
* [1.4 only] Update gpg.texi and gpgv.texi from the trunk:
|
||||||
make -C doc update-source-from-gnupg-2
|
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".
|
* Run "make -C po update-po".
|
||||||
* Write NEWS entries and set the release date in NEWS.
|
* Write NEWS entries and set the release date in NEWS.
|
||||||
* In configure.ac set "my_issvn" to "no".
|
* 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>
|
2010-09-02 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* cache.c (new_data): Change arg and callers to use a string and
|
* cache.c (new_data): Change arg and callers to use a string and
|
||||||
|
@ -182,7 +182,8 @@ enum
|
|||||||
PRIVATE_KEY_UNKNOWN = 0,
|
PRIVATE_KEY_UNKNOWN = 0,
|
||||||
PRIVATE_KEY_CLEAR = 1,
|
PRIVATE_KEY_CLEAR = 1,
|
||||||
PRIVATE_KEY_PROTECTED = 2,
|
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,
|
unsigned char **shadow_info,
|
||||||
cache_mode_t cache_mode,
|
cache_mode_t cache_mode,
|
||||||
lookup_ttl_t lookup_ttl,
|
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,
|
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
|
||||||
const unsigned char *grip,
|
const unsigned char *grip,
|
||||||
gcry_sexp_t *result);
|
gcry_sexp_t *result);
|
||||||
@ -251,7 +253,7 @@ int pinentry_active_p (ctrl_t ctrl, int waitseconds);
|
|||||||
int agent_askpin (ctrl_t ctrl,
|
int agent_askpin (ctrl_t ctrl,
|
||||||
const char *desc_text, const char *prompt_text,
|
const char *desc_text, const char *prompt_text,
|
||||||
const char *inital_errtext,
|
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,
|
int agent_get_passphrase (ctrl_t ctrl, char **retpass,
|
||||||
const char *desc, const char *prompt,
|
const char *desc, const char *prompt,
|
||||||
const char *errtext, int with_qualitybar);
|
const char *errtext, int with_qualitybar);
|
||||||
@ -289,7 +291,7 @@ int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
|||||||
/*-- genkey.c --*/
|
/*-- genkey.c --*/
|
||||||
int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent);
|
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,
|
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,
|
int agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
||||||
const char *keyparam, size_t keyparmlen, membuf_t *outbuf);
|
const char *keyparam, size_t keyparmlen, membuf_t *outbuf);
|
||||||
int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
|
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
|
/* 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
|
number here and repeat it as long as we have invalid formed
|
||||||
@ -704,7 +727,7 @@ int
|
|||||||
agent_askpin (ctrl_t ctrl,
|
agent_askpin (ctrl_t ctrl,
|
||||||
const char *desc_text, const char *prompt_text,
|
const char *desc_text, const char *prompt_text,
|
||||||
const char *initial_errtext,
|
const char *initial_errtext,
|
||||||
struct pin_entry_info_s *pininfo)
|
struct pin_entry_info_s *pininfo, int *r_cancel_all)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
@ -712,6 +735,10 @@ agent_askpin (ctrl_t ctrl,
|
|||||||
const char *errtext = NULL;
|
const char *errtext = NULL;
|
||||||
int is_pin = 0;
|
int is_pin = 0;
|
||||||
int saveflag;
|
int saveflag;
|
||||||
|
int close_button;
|
||||||
|
|
||||||
|
if (r_cancel_all)
|
||||||
|
*r_cancel_all = 0;
|
||||||
|
|
||||||
if (opt.batch)
|
if (opt.batch)
|
||||||
return 0; /* fixme: we should return BAD PIN */
|
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);
|
saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
|
||||||
assuan_begin_confidential (entry_ctx);
|
assuan_begin_confidential (entry_ctx);
|
||||||
|
close_button = 0;
|
||||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
|
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);
|
assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
|
||||||
/* Most pinentries out in the wild return the old Assuan error code
|
/* Most pinentries out in the wild return the old Assuan error code
|
||||||
for canceled which gets translated to an assuan Cancel error and
|
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)
|
&& gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
|
||||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_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)
|
if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
|
||||||
errtext = is_pin? _("PIN too long")
|
errtext = is_pin? _("PIN too long")
|
||||||
: _("Passphrase 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;
|
pi2->check_cb_arg = pi->pin;
|
||||||
|
|
||||||
next_try:
|
next_try:
|
||||||
err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
|
err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL);
|
||||||
initial_errtext = NULL;
|
initial_errtext = NULL;
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
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. */
|
/* Unless the passphrase is empty, ask to confirm it. */
|
||||||
if (pi->pin && *pi->pin)
|
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)
|
if (err == -1)
|
||||||
{ /* The re-entered one did not match and the user did not
|
{ /* The re-entered one did not match and the user did not
|
||||||
hit cancel. */
|
hit cancel. */
|
||||||
|
151
agent/command.c
151
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 */
|
/* Check whether the option NAME appears in LINE */
|
||||||
static int
|
static int
|
||||||
has_option (const char *line, const char *name)
|
has_option (const char *line, const char *name)
|
||||||
@ -177,6 +194,8 @@ has_option (const char *line, const char *name)
|
|||||||
int n = strlen (name);
|
int n = strlen (name);
|
||||||
|
|
||||||
s = strstr (line, 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)));
|
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);
|
int n = strlen (name);
|
||||||
|
|
||||||
s = strstr (line, name);
|
s = strstr (line, name);
|
||||||
|
if (s && s >= skip_options (line))
|
||||||
|
return 0;
|
||||||
return (s && (s == line || spacep (s-1))
|
return (s && (s == line || spacep (s-1))
|
||||||
&& (!s[n] || spacep (s+n) || s[n] == '='));
|
&& (!s[n] || spacep (s+n) || s[n] == '='));
|
||||||
}
|
}
|
||||||
@ -203,6 +224,8 @@ option_value (const char *line, const char *name)
|
|||||||
int n = strlen (name);
|
int n = strlen (name);
|
||||||
|
|
||||||
s = strstr (line, name);
|
s = strstr (line, name);
|
||||||
|
if (s && s >= skip_options (line))
|
||||||
|
return NULL;
|
||||||
if (s && (s == line || spacep (s-1))
|
if (s && (s == line || spacep (s-1))
|
||||||
&& s[n] && (spacep (s+n) || s[n] == '='))
|
&& 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. */
|
/* Replace all '+' by a blank. */
|
||||||
static void
|
static void
|
||||||
plus_to_blank (char *s)
|
plus_to_blank (char *s)
|
||||||
@ -530,23 +536,35 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_havekey[] =
|
static const char hlp_havekey[] =
|
||||||
"HAVEKEY <hexstring_with_keygrip>\n"
|
"HAVEKEY <hexstrings_with_keygrips>\n"
|
||||||
"\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
|
static gpg_error_t
|
||||||
cmd_havekey (assuan_context_t ctx, char *line)
|
cmd_havekey (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
int rc;
|
gpg_error_t err;
|
||||||
unsigned char buf[20];
|
unsigned char buf[20];
|
||||||
|
|
||||||
rc = parse_keygrip (ctx, line, buf);
|
do
|
||||||
if (rc)
|
{
|
||||||
return rc;
|
err = parse_keygrip (ctx, line, buf);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (!agent_key_available (buf))
|
||||||
|
return 0; /* Found. */
|
||||||
|
|
||||||
if (agent_key_available (buf))
|
while (*line && *line != ' ' && *line != '\t')
|
||||||
return gpg_error (GPG_ERR_NO_SECKEY);
|
line++;
|
||||||
|
while (*line == ' ' || *line == '\t')
|
||||||
return 0;
|
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++;
|
ctrl->in_passwd++;
|
||||||
rc = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc,
|
rc = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc,
|
||||||
grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
|
grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
|
||||||
&s_skey);
|
&s_skey, NULL);
|
||||||
if (rc)
|
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)
|
else if (!s_skey)
|
||||||
{
|
{
|
||||||
log_error ("changing a smartcard PIN is not yet supported\n");
|
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
|
used to protect the key using the same code as for regular
|
||||||
key import. */
|
key import. */
|
||||||
|
|
||||||
err = convert_openpgp (ctrl, openpgp_sexp, grip,
|
err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
|
||||||
ctrl->server_local->keydesc, cache_nonce,
|
ctrl->server_local->keydesc, cache_nonce,
|
||||||
&key, &passphrase);
|
&key, &passphrase);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
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
|
err = agent_ask_new_passphrase
|
||||||
(ctrl, _("Please enter the passphrase to protect the "
|
(ctrl, _("Please enter the passphrase to protect the "
|
||||||
"imported object within the GnuPG system."),
|
"imported object within the GnuPG system."),
|
||||||
&passphrase);
|
&passphrase, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1650,7 +1673,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_export_key[] =
|
static const char hlp_export_key[] =
|
||||||
"EXPORT_KEY <hexstring_with_keygrip>\n"
|
"EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Export a secret key from the key store. The key will be encrypted\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"
|
"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;
|
gcry_cipher_hd_t cipherhd = NULL;
|
||||||
unsigned char *wrappedkey = NULL;
|
unsigned char *wrappedkey = NULL;
|
||||||
size_t wrappedkeylen;
|
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)
|
if (!ctrl->server_local->export_key)
|
||||||
{
|
{
|
||||||
@ -1685,8 +1728,11 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
|||||||
goto leave;
|
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,
|
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)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
if (!s_skey)
|
if (!s_skey)
|
||||||
@ -1697,8 +1743,33 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
|||||||
err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
|
err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
|
||||||
goto leave;
|
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)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
gcry_sexp_release (s_skey);
|
gcry_sexp_release (s_skey);
|
||||||
@ -1735,12 +1806,18 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
xfree (passphrase);
|
||||||
xfree (wrappedkey);
|
xfree (wrappedkey);
|
||||||
gcry_cipher_close (cipherhd);
|
gcry_cipher_close (cipherhd);
|
||||||
xfree (key);
|
xfree (key);
|
||||||
gcry_sexp_release (s_skey);
|
gcry_sexp_release (s_skey);
|
||||||
xfree (ctrl->server_local->keydesc);
|
xfree (ctrl->server_local->keydesc);
|
||||||
ctrl->server_local->keydesc = NULL;
|
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);
|
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
|
pointed to by GRIP. On error NULL is stored at all return
|
||||||
arguments. */
|
arguments. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||||
unsigned char *grip, const char *prompt,
|
unsigned char *grip, const char *prompt,
|
||||||
const char *cache_nonce,
|
const char *cache_nonce,
|
||||||
unsigned char **r_key, char **r_passphrase)
|
unsigned char **r_key, char **r_passphrase)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
gcry_sexp_t top_list;
|
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);
|
err = try_do_unprotect_cb (pi);
|
||||||
}
|
}
|
||||||
if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
|
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;
|
skeyidx = pi_arg.skeyidx;
|
||||||
if (!err)
|
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
|
#ifndef GNUPG_AGENT_CVT_OPENPGP_H
|
||||||
#define GNUPG_AGENT_CVT_OPENPGP_H
|
#define GNUPG_AGENT_CVT_OPENPGP_H
|
||||||
|
|
||||||
gpg_error_t convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
gpg_error_t convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||||
unsigned char *grip, const char *prompt,
|
unsigned char *grip, const char *prompt,
|
||||||
const char *cache_nonce,
|
const char *cache_nonce,
|
||||||
unsigned char **r_key, char **r_passphrase);
|
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*/
|
#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)
|
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;
|
again_text = NULL;
|
||||||
if (!rc && newpin)
|
if (!rc && newpin)
|
||||||
{
|
{
|
||||||
@ -288,7 +288,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
|||||||
is_puk?
|
is_puk?
|
||||||
_("Repeat this PUK"):
|
_("Repeat this PUK"):
|
||||||
_("Repeat this PIN")),
|
_("Repeat this PIN")),
|
||||||
prompt, NULL, pi2);
|
prompt, NULL, pi2, NULL);
|
||||||
if (!rc && strcmp (pi->pin, pi2->pin))
|
if (!rc && strcmp (pi->pin, pi2->pin))
|
||||||
{
|
{
|
||||||
again_text = (resetcode?
|
again_text = (resetcode?
|
||||||
@ -312,7 +312,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
|
|||||||
info? info:"",
|
info? info:"",
|
||||||
info? "')":"") < 0)
|
info? "')":"") < 0)
|
||||||
desc = NULL;
|
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);
|
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. */
|
code. */
|
||||||
static int
|
static int
|
||||||
try_unprotect_cb (struct pin_entry_info_s *pi)
|
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
|
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
|
caching mechanism. DESC_TEXT may be set to override the default
|
||||||
description used for the pinentry. If LOOKUP_TTL is given this
|
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
|
static int
|
||||||
unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
||||||
unsigned char **keybuf, const unsigned char *grip,
|
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 pin_entry_info_s *pi;
|
||||||
struct try_unprotect_arg_s arg;
|
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;
|
unsigned char *result;
|
||||||
size_t resultlen;
|
size_t resultlen;
|
||||||
char hexgrip[40+1];
|
char hexgrip[40+1];
|
||||||
|
int fully_canceled;
|
||||||
|
|
||||||
|
if (r_passphrase)
|
||||||
|
*r_passphrase = NULL;
|
||||||
|
|
||||||
bin2hex (grip, 20, hexgrip);
|
bin2hex (grip, 20, hexgrip);
|
||||||
|
|
||||||
@ -297,13 +306,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||||||
if (pw)
|
if (pw)
|
||||||
{
|
{
|
||||||
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
|
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
|
||||||
xfree (pw);
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
|
if (r_passphrase)
|
||||||
|
*r_passphrase = pw;
|
||||||
|
else
|
||||||
|
xfree (pw);
|
||||||
xfree (*keybuf);
|
xfree (*keybuf);
|
||||||
*keybuf = result;
|
*keybuf = result;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
xfree (pw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,13 +331,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||||||
if (pw)
|
if (pw)
|
||||||
{
|
{
|
||||||
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
|
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
|
||||||
xfree (pw);
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
|
if (r_passphrase)
|
||||||
|
*r_passphrase = pw;
|
||||||
|
else
|
||||||
|
xfree (pw);
|
||||||
xfree (*keybuf);
|
xfree (*keybuf);
|
||||||
*keybuf = result;
|
*keybuf = result;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
xfree (pw);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +383,9 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||||||
arg.change_required = 0;
|
arg.change_required = 0;
|
||||||
pi->check_cb_arg = &arg;
|
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)
|
if (!rc)
|
||||||
{
|
{
|
||||||
assert (arg.unprotected_key);
|
assert (arg.unprotected_key);
|
||||||
@ -400,8 +419,13 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
agent_put_cache (hexgrip, cache_mode, pi->pin,
|
else
|
||||||
lookup_ttl? lookup_ttl (hexgrip) : 0);
|
{
|
||||||
|
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);
|
xfree (*keybuf);
|
||||||
*keybuf = arg.unprotected_key;
|
*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
|
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
|
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
|
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
|
gpg_error_t
|
||||||
agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
||||||
const char *desc_text,
|
const char *desc_text,
|
||||||
const unsigned char *grip, unsigned char **shadow_info,
|
const unsigned char *grip, unsigned char **shadow_info,
|
||||||
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
|
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
|
||||||
gcry_sexp_t *result)
|
gcry_sexp_t *result, char **r_passphrase)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
@ -518,6 +546,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
*result = NULL;
|
*result = NULL;
|
||||||
if (shadow_info)
|
if (shadow_info)
|
||||||
*shadow_info = NULL;
|
*shadow_info = NULL;
|
||||||
|
if (r_passphrase)
|
||||||
|
*r_passphrase = NULL;
|
||||||
|
|
||||||
rc = read_key_file (grip, &s_skey);
|
rc = read_key_file (grip, &s_skey);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -579,7 +609,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
|
rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
|
||||||
cache_mode, lookup_ttl);
|
cache_mode, lookup_ttl, r_passphrase);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error ("failed to unprotect the secret key: %s\n",
|
log_error ("failed to unprotect the secret key: %s\n",
|
||||||
gpg_strerror (rc));
|
gpg_strerror (rc));
|
||||||
@ -626,6 +656,11 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
if (rc || got_shadow_info)
|
if (rc || got_shadow_info)
|
||||||
{
|
{
|
||||||
xfree (buf);
|
xfree (buf);
|
||||||
|
if (r_passphrase)
|
||||||
|
{
|
||||||
|
xfree (*r_passphrase);
|
||||||
|
*r_passphrase = NULL;
|
||||||
|
}
|
||||||
return rc;
|
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",
|
log_error ("failed to build S-Exp (off=%u): %s\n",
|
||||||
(unsigned int)erroff, gpg_strerror (rc));
|
(unsigned int)erroff, gpg_strerror (rc));
|
||||||
|
if (r_passphrase)
|
||||||
|
{
|
||||||
|
xfree (*r_passphrase);
|
||||||
|
*r_passphrase = NULL;
|
||||||
|
}
|
||||||
return rc;
|
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
|
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 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
|
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
|
gpg_error_t
|
||||||
agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
||||||
char **r_passphrase)
|
char **r_passphrase, int *r_cancel_all)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
const char *text1 = prompt;
|
const char *text1 = prompt;
|
||||||
@ -314,7 +316,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
|
|||||||
pi2->check_cb_arg = pi->pin;
|
pi2->check_cb_arg = pi->pin;
|
||||||
|
|
||||||
next_try:
|
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;
|
initial_errtext = NULL;
|
||||||
if (!err)
|
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. */
|
/* Unless the passphrase is empty, ask to confirm it. */
|
||||||
if (pi->pin && *pi->pin)
|
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)
|
if (err == -1)
|
||||||
{ /* The re-entered one did not match and the user did not
|
{ /* The re-entered one did not match and the user did not
|
||||||
hit cancel. */
|
hit cancel. */
|
||||||
@ -379,7 +381,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
rc = agent_ask_new_passphrase (ctrl,
|
rc = agent_ask_new_passphrase (ctrl,
|
||||||
_("Please enter the passphrase to%0A"
|
_("Please enter the passphrase to%0A"
|
||||||
"to protect your new key"),
|
"to protect your new key"),
|
||||||
&passphrase);
|
&passphrase, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
return 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,
|
rc = agent_ask_new_passphrase (ctrl,
|
||||||
_("Please enter the new passphrase"),
|
_("Please enter the new passphrase"),
|
||||||
&passphrase);
|
&passphrase, NULL);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
rc = store_key (s_skey, passphrase, 1);
|
rc = store_key (s_skey, passphrase, 1);
|
||||||
|
@ -440,6 +440,11 @@ remove_socket (char *name)
|
|||||||
static void
|
static void
|
||||||
cleanup (void)
|
cleanup (void)
|
||||||
{
|
{
|
||||||
|
static int done;
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
return;
|
||||||
|
done = 1;
|
||||||
deinitialize_module_cache ();
|
deinitialize_module_cache ();
|
||||||
remove_socket (socket_name);
|
remove_socket (socket_name);
|
||||||
remove_socket (socket_name_ssh);
|
remove_socket (socket_name_ssh);
|
||||||
@ -724,6 +729,12 @@ main (int argc, char **argv )
|
|||||||
if( parse_debug )
|
if( parse_debug )
|
||||||
log_info (_("NOTE: no default option file `%s'\n"),
|
log_info (_("NOTE: no default option file `%s'\n"),
|
||||||
configname );
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -811,10 +822,15 @@ main (int argc, char **argv )
|
|||||||
fclose( configfp );
|
fclose( configfp );
|
||||||
configfp = NULL;
|
configfp = NULL;
|
||||||
/* Keep a copy of the name so that it can be read on SIGHUP. */
|
/* 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;
|
configname = NULL;
|
||||||
goto next_pass;
|
goto next_pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (configname);
|
xfree (configname);
|
||||||
configname = NULL;
|
configname = NULL;
|
||||||
if (log_get_errorcount(0))
|
if (log_get_errorcount(0))
|
||||||
@ -1262,6 +1278,12 @@ void
|
|||||||
agent_exit (int rc)
|
agent_exit (int rc)
|
||||||
{
|
{
|
||||||
/*FIXME: update_random_seed_file();*/
|
/*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
|
#if 1
|
||||||
/* at this time a bit annoying */
|
/* at this time a bit annoying */
|
||||||
if (opt.debug & DBG_MEMSTAT_VALUE)
|
if (opt.debug & DBG_MEMSTAT_VALUE)
|
||||||
@ -1337,8 +1359,8 @@ reread_configuration (void)
|
|||||||
fp = fopen (config_filename, "r");
|
fp = fopen (config_filename, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
log_error (_("option file `%s': %s\n"),
|
log_info (_("option file `%s': %s\n"),
|
||||||
config_filename, strerror(errno) );
|
config_filename, strerror(errno) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,8 @@ the ~/.gnupg home directory. This directory is named
|
|||||||
and should have permissions 700.
|
and should have permissions 700.
|
||||||
|
|
||||||
The secret keys are stored in files with a name matching the
|
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
|
Unprotected Private Key Format
|
||||||
==============================
|
==============================
|
||||||
@ -166,21 +167,23 @@ This format is used to transfer keys between gpg and gpg-agent.
|
|||||||
|
|
||||||
(openpgp-private-key
|
(openpgp-private-key
|
||||||
(version V)
|
(version V)
|
||||||
(protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT)
|
|
||||||
(algo PUBKEYALGO)
|
(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).
|
* V is the packet version number (3 or 4).
|
||||||
* PUBKEYALGO is a Libgcrypt algo name
|
* 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
|
* P1 .. PN are the parameters; the public parameters are never encrypted
|
||||||
the secrect key parameters are encrypted if the "protection" list is
|
the secrect key parameters are encrypted if the "protection" list is
|
||||||
given. To make this more explicit each parameter is preceded by a
|
given. To make this more explicit each parameter is preceded by a
|
||||||
flag "_" for cleartext or "e" for encrypted text.
|
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"
|
* 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
|
the old 16 bit checksum (above) is used and if it is "none" no
|
||||||
all is used.
|
protection at all is used.
|
||||||
* PROTALGO is a Libgcrypt style cipher algorithm name
|
* PROTALGO is a Libgcrypt style cipher algorithm name
|
||||||
* IV is the initialization verctor.
|
* IV is the initialization verctor.
|
||||||
* S2KMODE is the value from RFC-4880.
|
* 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.
|
* 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:
|
Notes:
|
||||||
======
|
======
|
||||||
|
@ -66,7 +66,9 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
|||||||
}
|
}
|
||||||
rc = agent_key_from_file (ctrl, NULL, desc_text,
|
rc = agent_key_from_file (ctrl, NULL, desc_text,
|
||||||
ctrl->keygrip, &shadow_info,
|
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 (rc)
|
||||||
{
|
{
|
||||||
if (gpg_err_code (rc) == GPG_ERR_ENOENT)
|
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,
|
rc = agent_key_from_file (ctrl, cache_nonce, desc_text, ctrl->keygrip,
|
||||||
&shadow_info, cache_mode, lookup_ttl,
|
&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)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("failed to read the secret key\n");
|
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
|
/* Calculate the MIC for a private key or shared secret S-expression.
|
||||||
a 20 byte buffer. This function is suitable for any algorithms. */
|
SHA1HASH should point to a 20 byte buffer. This function is
|
||||||
|
suitable for all algorithms. */
|
||||||
static int
|
static int
|
||||||
calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
|
calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
|
||||||
{
|
{
|
||||||
const unsigned char *hash_begin, *hash_end;
|
const unsigned char *hash_begin, *hash_end;
|
||||||
const unsigned char *s;
|
const unsigned char *s;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
int is_shared_secret;
|
||||||
|
|
||||||
s = plainkey;
|
s = plainkey;
|
||||||
if (*s != '(')
|
if (*s != '(')
|
||||||
@ -207,16 +209,23 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
|
|||||||
n = snext (&s);
|
n = snext (&s);
|
||||||
if (!n)
|
if (!n)
|
||||||
return gpg_error (GPG_ERR_INV_SEXP);
|
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);
|
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||||
if (*s != '(')
|
if (*s != '(')
|
||||||
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
||||||
hash_begin = s;
|
hash_begin = s;
|
||||||
s++;
|
if (!is_shared_secret)
|
||||||
n = snext (&s);
|
{
|
||||||
if (!n)
|
s++;
|
||||||
return gpg_error (GPG_ERR_INV_SEXP);
|
n = snext (&s);
|
||||||
s += n; /* skip over the algorithm name */
|
if (!n)
|
||||||
|
return gpg_error (GPG_ERR_INV_SEXP);
|
||||||
|
s += n; /* Skip the algorithm name. */
|
||||||
|
}
|
||||||
|
|
||||||
while (*s == '(')
|
while (*s == '(')
|
||||||
{
|
{
|
||||||
@ -955,7 +964,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
|
|||||||
xfree (final);
|
xfree (final);
|
||||||
return rc;
|
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. */
|
go into the final thing. */
|
||||||
if (cutlen)
|
if (cutlen)
|
||||||
{
|
{
|
||||||
|
@ -289,6 +289,13 @@ test_agent_get_shadow_info (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_agent_protect_shared_secret (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -305,6 +312,7 @@ main (int argc, char **argv)
|
|||||||
test_make_shadow_info ();
|
test_make_shadow_info ();
|
||||||
test_agent_shadow_key ();
|
test_agent_shadow_key ();
|
||||||
test_agent_get_shadow_info ();
|
test_agent_get_shadow_info ();
|
||||||
|
test_agent_protect_shared_secret ();
|
||||||
|
|
||||||
return 0;
|
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>
|
2010-09-13 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* homedir.c (gnupg_bindir) [W32CE]: Change to bin/.
|
* homedir.c (gnupg_bindir) [W32CE]: Change to bin/.
|
||||||
|
@ -114,6 +114,9 @@ struct srventry
|
|||||||
#ifndef EAGAIN
|
#ifndef EAGAIN
|
||||||
#define EAGAIN EWOULDBLOCK
|
#define EAGAIN EWOULDBLOCK
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef INADDR_NONE /* Slowaris is missing that. */
|
||||||
|
#define INADDR_NONE ((unsigned long)(-1))
|
||||||
|
#endif /*INADDR_NONE*/
|
||||||
|
|
||||||
#define HTTP_PROXY_ENV "http_proxy"
|
#define HTTP_PROXY_ENV "http_proxy"
|
||||||
#define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
|
#define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
|
||||||
|
@ -68,6 +68,9 @@
|
|||||||
#ifndef EAFNOSUPPORT
|
#ifndef EAFNOSUPPORT
|
||||||
# define EAFNOSUPPORT EINVAL
|
# define EAFNOSUPPORT EINVAL
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef INADDR_NONE /* Slowaris is missing that. */
|
||||||
|
#define INADDR_NONE ((unsigned long)(-1))
|
||||||
|
#endif /*INADDR_NONE*/
|
||||||
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
#define sock_close(a) closesocket(a)
|
#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
|
/* 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
|
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. */
|
match. */
|
||||||
static inline int
|
static inline int
|
||||||
smatch (unsigned char const **buf, size_t buflen, const char *token)
|
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_NOT_TRUSTED: errstr = "10"; break;
|
||||||
case GPG_ERR_MISSING_CERT: errstr = "11"; break;
|
case GPG_ERR_MISSING_CERT: errstr = "11"; break;
|
||||||
|
case GPG_ERR_MISSING_ISSUER_CERT: errstr = "12"; break;
|
||||||
default: errstr = "0"; break;
|
default: errstr = "0"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@
|
|||||||
#ifndef GPG_ERR_NOT_INITIALIZED
|
#ifndef GPG_ERR_NOT_INITIALIZED
|
||||||
#define GPG_ERR_NOT_INITIALIZED 184
|
#define GPG_ERR_NOT_INITIALIZED 184
|
||||||
#endif
|
#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. */
|
/* Hash function used with libksba. */
|
||||||
|
@ -396,7 +396,7 @@ AH_BOTTOM([
|
|||||||
# define GNUPG_DEFAULT_HOMEDIR "/gnupg"
|
# define GNUPG_DEFAULT_HOMEDIR "/gnupg"
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__VMS)
|
#elif defined(__VMS)
|
||||||
#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg"
|
#define GNUPG_DEFAULT_HOMEDIR "/SYS$LOGIN/gnupg"
|
||||||
#else
|
#else
|
||||||
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg"
|
||||||
#endif
|
#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>
|
2010-08-13 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* Makefile.am (dirmngr_SOURCES): Add w32-ldap-help.h.
|
* 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"),
|
log_error (_("issuer certificate not found: %s\n"),
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
/* Use a better understandable error code. */
|
/* Use a better understandable error code. */
|
||||||
err = gpg_error (GPG_ERR_MISSING_CERT);
|
err = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
|
||||||
goto leave;
|
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>
|
2010-09-28 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* gpg.texi (OpenPGP Options): Clarify that --force-v3-sigs
|
* gpg.texi (OpenPGP Options): Clarify that --force-v3-sigs
|
||||||
|
@ -586,7 +586,8 @@ more arguments in future versions.
|
|||||||
8 := "Policy mismatch"
|
8 := "Policy mismatch"
|
||||||
9 := "Not a secret key"
|
9 := "Not a secret key"
|
||||||
10 := "Key not trusted"
|
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
|
Note that for historical reasons the INV_RECP status is also
|
||||||
used for gpgsm's SIGNER command where it relates to signer's
|
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
|
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"
|
--release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard"
|
||||||
|
|
||||||
myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
|
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
|
@item A root certificate does not verify
|
||||||
|
|
||||||
A common problem is that the root certificate misses the required
|
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
|
certificate. An error message indicating ``no value'' is a sign for
|
||||||
such a certificate. You may use the @code{relax} flag in
|
such a certificate. You may use the @code{relax} flag in
|
||||||
@file{trustlist.txt} to accept the certificate anyway. Note that the
|
@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}
|
@item --log-file @var{file}
|
||||||
@opindex log-file
|
@opindex log-file
|
||||||
Append all logging output to @var{file}. This is very helpful in
|
Append all logging output to @var{file}. This is very helpful in seeing
|
||||||
seeing what the agent actually does.
|
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}
|
@anchor{option --allow-mark-trusted}
|
||||||
@item --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.
|
not return any information on whether the key is somehow protected.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
HAVEKEY @var{keygrip}
|
HAVEKEY @var{keygrips}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The Agent answers either with OK or @code{No_Secret_Key} (208). The
|
The agent answers either with OK or @code{No_Secret_Key} (208). The
|
||||||
caller may want to check for other error codes as well.
|
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
|
@node Agent LEARN
|
||||||
|
32
doc/gpg.texi
32
doc/gpg.texi
@ -3,6 +3,11 @@
|
|||||||
@c This is part of the GnuPG manual.
|
@c This is part of the GnuPG manual.
|
||||||
@c For copying conditions, see the file gnupg.texi.
|
@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
|
@node Invoking GPG
|
||||||
@chapter Invoking GPG
|
@chapter Invoking GPG
|
||||||
@cindex GPG command options
|
@cindex GPG command options
|
||||||
@ -68,18 +73,19 @@ implementation.
|
|||||||
|
|
||||||
@ifset gpgone
|
@ifset gpgone
|
||||||
This is the standalone version of @command{gpg}. For desktop use you
|
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
|
@end ifset
|
||||||
|
|
||||||
@ifclear gpgone
|
@ifclear gpgone
|
||||||
In contrast to the standalone version @command{gpg}, which is more
|
In contrast to the standalone version @command{gpg}, which is more
|
||||||
suited for server and embedded platforms, this version is installed
|
suited for server and embedded platforms, this version is commonly
|
||||||
under the name @command{gpg2} and more targeted to the desktop as it
|
installed under the name @command{gpg2} and more targeted to the desktop
|
||||||
requires several other modules to be installed. The standalone version
|
as it requires several other modules to be installed. The standalone
|
||||||
will be kept maintained and it is possible to install both versions on
|
version will be kept maintained and it is possible to install both
|
||||||
the same system. If you need to use different configuration files, you
|
versions on the same system. If you need to use different configuration
|
||||||
should make use of something like @file{gpg.conf-2} instead of just
|
files, you should make use of something like @file{gpg.conf-2} instead
|
||||||
@file{gpg.conf}.
|
of just @file{gpg.conf}.
|
||||||
@end ifclear
|
@end ifclear
|
||||||
|
|
||||||
@manpause
|
@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
|
command has the special property to render the secret part of the
|
||||||
primary key useless; this is a GNU extension to OpenPGP and other
|
primary key useless; this is a GNU extension to OpenPGP and other
|
||||||
implementations can not be expected to successfully import such a key.
|
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
|
See the option @option{--simple-sk-checksum} if you want to import such
|
||||||
an exported key with an older OpenPGP implementation.
|
an exported key with an older OpenPGP implementation.
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
@item --import
|
@item --import
|
||||||
@itemx --fast-import
|
@itemx --fast-import
|
||||||
@ -1550,6 +1558,7 @@ key signer (defaults to 3)
|
|||||||
@item --max-cert-depth @code{n}
|
@item --max-cert-depth @code{n}
|
||||||
Maximum depth of a certification chain (default is 5).
|
Maximum depth of a certification chain (default is 5).
|
||||||
|
|
||||||
|
@ifclear gpgtwoone
|
||||||
@item --simple-sk-checksum
|
@item --simple-sk-checksum
|
||||||
Secret keys are integrity protected by using a SHA-1 checksum. This
|
Secret keys are integrity protected by using a SHA-1 checksum. This
|
||||||
method is part of the upcoming enhanced OpenPGP specification but
|
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
|
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
|
to change the passphrase on the key (even changing it to the same
|
||||||
value is acceptable).
|
value is acceptable).
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
@item --no-sig-cache
|
@item --no-sig-cache
|
||||||
Do not cache the verification status of key signatures.
|
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
|
Include designated revoker information that was marked as
|
||||||
"sensitive". Defaults to no.
|
"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
|
@item export-reset-subkey-passwd
|
||||||
When using the @option{--export-secret-subkeys} command, this option resets
|
When using the @option{--export-secret-subkeys} command, this option resets
|
||||||
the passphrases for all exported subkeys to empty. This is useful
|
the passphrases for all exported subkeys to empty. This is useful
|
||||||
when the exported subkey is to be used on an unattended machine where
|
when the exported subkey is to be used on an unattended machine where
|
||||||
a passphrase doesn't necessarily make sense. Defaults to no.
|
a passphrase doesn't necessarily make sense. Defaults to no.
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
@item export-clean
|
@item export-clean
|
||||||
Compact (remove all signatures from) user IDs on the key being
|
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
|
@command{gpgsm} is a tool similar to @command{gpg} to provide digital
|
||||||
encryption and signing services on X.509 certificates and the CMS
|
encryption and signing services on X.509 certificates and the CMS
|
||||||
protocol. It is mainly used as a backend for S/MIME mail processing.
|
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.
|
complies with all rules defined for the German Sphinx project.
|
||||||
|
|
||||||
@manpause
|
@manpause
|
||||||
@ -286,7 +286,7 @@ smartcard is not yet supported.
|
|||||||
@node GPGSM Options
|
@node GPGSM Options
|
||||||
@section Option Summary
|
@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.
|
and to change the default configuration.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
@ -566,10 +566,9 @@ certificate.
|
|||||||
@item --include-certs @var{n}
|
@item --include-certs @var{n}
|
||||||
@opindex include-certs
|
@opindex include-certs
|
||||||
Using @var{n} of -2 includes all certificate except for the root cert,
|
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
|
-1 includes all certs, 0 does not include any certs, 1 includes only the
|
||||||
the signers cert (this is the default) and all other positive
|
signers cert and all other positive values include up to @var{n}
|
||||||
values include up to @var{n} certificates starting with the signer cert.
|
certificates starting with the signer cert. The default is -2.
|
||||||
The default is -2.
|
|
||||||
|
|
||||||
@item --cipher-algo @var{oid}
|
@item --cipher-algo @var{oid}
|
||||||
@opindex cipher-algo
|
@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>
|
2010-09-28 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* options.skel: Make the example for force-v3-sigs match
|
* options.skel: Make the example for force-v3-sigs match
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "util.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "iobuf.h"
|
#include "iobuf.h"
|
||||||
#include "util.h"
|
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
@ -71,8 +71,16 @@ build_packet( IOBUF out, PACKET *pkt )
|
|||||||
log_debug("build_packet() type=%d\n", pkt->pkttype );
|
log_debug("build_packet() type=%d\n", pkt->pkttype );
|
||||||
assert( pkt->pkt.generic );
|
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_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
|
||||||
case PKT_ENCRYPTED:
|
case PKT_ENCRYPTED:
|
||||||
case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
|
case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
|
||||||
|
142
g10/call-agent.c
142
g10/call-agent.c
@ -901,7 +901,27 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
|
|||||||
put_membuf (data, buffer, length);
|
put_membuf (data, buffer, length);
|
||||||
return 0;
|
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
|
/* Send a sign command to the scdaemon via gpg-agent's pass thru
|
||||||
mechanism. */
|
mechanism. */
|
||||||
int
|
int
|
||||||
@ -942,14 +962,11 @@ agent_scd_pksign (const char *serialno, int hashalgo,
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
init_membuf (&data, 1024);
|
init_membuf (&data, 1024);
|
||||||
#if 0
|
/* if (!hashalgo) /\* Temporary test hack. *\/ */
|
||||||
if (!hashalgo) /* Temporary test hack. */
|
/* snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); */
|
||||||
snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
|
/* else */
|
||||||
else
|
snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s",
|
||||||
#endif
|
hash_algo_option (hashalgo), serialno);
|
||||||
snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
|
|
||||||
hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
|
|
||||||
serialno);
|
|
||||||
line[DIM(line)-1] = 0;
|
line[DIM(line)-1] = 0;
|
||||||
rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
|
rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
|
||||||
default_inq_cb, NULL, NULL, NULL);
|
default_inq_cb, NULL, NULL, NULL);
|
||||||
@ -1325,6 +1342,57 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
|
|||||||
return err;
|
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
|
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
|
static gpg_error_t
|
||||||
cache_nonce_status_cb (void *opaque, const char *line)
|
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. */
|
0 if the secret key is available. */
|
||||||
gpg_error_t agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk);
|
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. */
|
/* Return infos about the secret key with HEXKEYGRIP. */
|
||||||
gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
|
gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
|
||||||
char **r_serialno);
|
char **r_serialno);
|
||||||
@ -174,6 +179,11 @@ gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
|
|||||||
char **cache_nonce_addr,
|
char **cache_nonce_addr,
|
||||||
const void *key, size_t keylen);
|
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*/
|
#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
|
/* Fetch the key from the URL given on the card or try to get it from
|
||||||
the default keyserver. */
|
the default keyserver. */
|
||||||
static int
|
static int
|
||||||
fetch_url(void)
|
fetch_url (ctrl_t ctrl)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct agent_card_info_s info;
|
struct agent_card_info_s info;
|
||||||
@ -751,13 +751,13 @@ fetch_url(void)
|
|||||||
event, the fpr/keyid is not meaningful for straight
|
event, the fpr/keyid is not meaningful for straight
|
||||||
HTTP fetches, but using it allows the card to point
|
HTTP fetches, but using it allows the card to point
|
||||||
to HKP and LDAP servers as well. */
|
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);
|
free_keyserver_spec(spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (info.fpr1valid)
|
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
|
/* Menu to edit all user changeable values on an OpenPGP card. Only
|
||||||
Key creation is not handled here. */
|
Key creation is not handled here. */
|
||||||
void
|
void
|
||||||
card_edit (strlist_t commands)
|
card_edit (ctrl_t ctrl, strlist_t commands)
|
||||||
{
|
{
|
||||||
enum cmdids cmd = cmdNOP;
|
enum cmdids cmd = cmdNOP;
|
||||||
int have_commands = !!commands;
|
int have_commands = !!commands;
|
||||||
@ -1924,7 +1924,7 @@ card_edit (strlist_t commands)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdFETCH:
|
case cmdFETCH:
|
||||||
fetch_url();
|
fetch_url (ctrl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdLOGIN:
|
case cmdLOGIN:
|
||||||
|
@ -300,7 +300,7 @@ release_context (compress_filter_context_t *ctx)
|
|||||||
* Handle a compressed packet
|
* Handle a compressed packet
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
handle_compressed( void *procctx, PKT_compressed *cd,
|
handle_compressed (ctrl_t ctrl, void *procctx, PKT_compressed *cd,
|
||||||
int (*callback)(IOBUF, void *), void *passthru )
|
int (*callback)(IOBUF, void *), void *passthru )
|
||||||
{
|
{
|
||||||
compress_filter_context_t *cfx;
|
compress_filter_context_t *cfx;
|
||||||
@ -315,7 +315,7 @@ handle_compressed( void *procctx, PKT_compressed *cd,
|
|||||||
if( callback )
|
if( callback )
|
||||||
rc = callback(cd->buf, passthru );
|
rc = callback(cd->buf, passthru );
|
||||||
else
|
else
|
||||||
rc = proc_packets(procctx, cd->buf);
|
rc = proc_packets (ctrl,procctx, cd->buf);
|
||||||
cd->buf = NULL;
|
cd->buf = NULL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ release_dfx_context (decode_filter_ctx_t dfx)
|
|||||||
* Decrypt the data, specified by ED with the key DEK.
|
* Decrypt the data, specified by ED with the key DEK.
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
decode_filter_ctx_t dfx;
|
||||||
byte *p;
|
byte *p;
|
||||||
@ -191,7 +191,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
|||||||
else
|
else
|
||||||
iobuf_push_filter ( ed->buf, decode_filter, dfx );
|
iobuf_push_filter ( ed->buf, decode_filter, dfx );
|
||||||
|
|
||||||
proc_packets ( procctx, ed->buf );
|
proc_packets (ctrl, procctx, ed->buf );
|
||||||
ed->buf = NULL;
|
ed->buf = NULL;
|
||||||
if (dfx->eof_seen > 1 )
|
if (dfx->eof_seen > 1 )
|
||||||
rc = gpg_error (GPG_ERR_INV_PACKET);
|
rc = gpg_error (GPG_ERR_INV_PACKET);
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
* rejects files which don't begin with an encrypted message.
|
* rejects files which don't begin with an encrypted message.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
decrypt_message (const char *filename)
|
decrypt_message (ctrl_t ctrl, const char *filename)
|
||||||
{
|
{
|
||||||
IOBUF fp;
|
IOBUF fp;
|
||||||
armor_filter_context_t *afx = NULL;
|
armor_filter_context_t *afx = NULL;
|
||||||
@ -86,7 +86,7 @@ decrypt_message (const char *filename)
|
|||||||
no_out = 1;
|
no_out = 1;
|
||||||
opt.outfile = "-";
|
opt.outfile = "-";
|
||||||
}
|
}
|
||||||
rc = proc_encryption_packets ( NULL, fp );
|
rc = proc_encryption_packets (ctrl, NULL, fp );
|
||||||
if (no_out)
|
if (no_out)
|
||||||
opt.outfile = NULL;
|
opt.outfile = NULL;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ decrypt_message (const char *filename)
|
|||||||
/* Same as decrypt_message but takes a file descriptor for input and
|
/* Same as decrypt_message but takes a file descriptor for input and
|
||||||
output. */
|
output. */
|
||||||
gpg_error_t
|
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;
|
gpg_error_t err;
|
||||||
IOBUF fp;
|
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);
|
iobuf_close (fp);
|
||||||
fclose (opt.outfp);
|
fclose (opt.outfp);
|
||||||
@ -170,7 +170,7 @@ decrypt_message_fd (int input_fd, int output_fd)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
decrypt_messages (int nfiles, char *files[])
|
decrypt_messages (ctrl_t ctrl, int nfiles, char *files[])
|
||||||
{
|
{
|
||||||
IOBUF fp;
|
IOBUF fp;
|
||||||
armor_filter_context_t *afx = NULL;
|
armor_filter_context_t *afx = NULL;
|
||||||
@ -251,7 +251,7 @@ decrypt_messages (int nfiles, char *files[])
|
|||||||
push_armor_filter ( afx, fp );
|
push_armor_filter ( afx, fp );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = proc_packets(NULL, fp);
|
rc = proc_packets (ctrl,NULL, fp);
|
||||||
iobuf_close(fp);
|
iobuf_close(fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error("%s: decryption failed: %s\n", print_fname_stdin(filename),
|
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.
|
* PROVIDED_PKS; if not the function builds a list of keys on its own.
|
||||||
*/
|
*/
|
||||||
int
|
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,
|
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
|
||||||
int outputfd)
|
int outputfd)
|
||||||
{
|
{
|
||||||
@ -503,7 +503,7 @@ encrypt_crypt (int filefd, const char *filename,
|
|||||||
pk_list = provided_keys;
|
pk_list = provided_keys;
|
||||||
else
|
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);
|
release_progress_context (pfx);
|
||||||
return rc;
|
return rc;
|
||||||
@ -939,7 +939,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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;
|
int rc = 0;
|
||||||
|
|
||||||
@ -963,7 +963,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
|||||||
}
|
}
|
||||||
line[strlen(line)-1] = '\0';
|
line[strlen(line)-1] = '\0';
|
||||||
print_file_status(STATUS_FILE_START, line, 2);
|
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)
|
if (rc)
|
||||||
log_error ("encryption of `%s' failed: %s\n",
|
log_error ("encryption of `%s' failed: %s\n",
|
||||||
print_fname_stdin(line), g10_errstr(rc) );
|
print_fname_stdin(line), g10_errstr(rc) );
|
||||||
@ -975,7 +975,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
|||||||
while (nfiles--)
|
while (nfiles--)
|
||||||
{
|
{
|
||||||
print_file_status(STATUS_FILE_START, *files, 2);
|
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",
|
log_error("encryption of `%s' failed: %s\n",
|
||||||
print_fname_stdin(*files), g10_errstr(rc) );
|
print_fname_stdin(*files), g10_errstr(rc) );
|
||||||
write_status( STATUS_FILE_DONE );
|
write_status( STATUS_FILE_DONE );
|
||||||
|
745
g10/export.c
745
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,
|
* 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.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -34,7 +34,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "trustdb.h"
|
#include "trustdb.h"
|
||||||
|
#include "call-agent.h"
|
||||||
|
|
||||||
/* An object to keep track of subkeys. */
|
/* An object to keep track of subkeys. */
|
||||||
struct subkey_list_s
|
struct subkey_list_s
|
||||||
@ -45,10 +45,12 @@ struct subkey_list_s
|
|||||||
typedef struct subkey_list_s *subkey_list_t;
|
typedef struct subkey_list_s *subkey_list_t;
|
||||||
|
|
||||||
|
|
||||||
static int do_export( strlist_t users, int secret, unsigned int options );
|
static int do_export (ctrl_t ctrl,
|
||||||
static int do_export_stream( IOBUF out, strlist_t users, int secret,
|
strlist_t users, int secret, unsigned int options );
|
||||||
KBNODE *keyblock_out, unsigned int options,
|
static int do_export_stream (ctrl_t ctrl, iobuf_t out,
|
||||||
int *any );
|
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);
|
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)")},
|
N_("export attribute user IDs (generally photo IDs)")},
|
||||||
{"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
|
{"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
|
||||||
N_("export revocation keys marked as \"sensitive\"")},
|
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,
|
{"export-clean",EXPORT_CLEAN,NULL,
|
||||||
N_("remove unusable parts from key during export")},
|
N_("remove unusable parts from key during export")},
|
||||||
{"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
|
{"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.
|
* options are defined in main.h.
|
||||||
* If USERS is NULL, the complete ring will be exported. */
|
* If USERS is NULL, the complete ring will be exported. */
|
||||||
int
|
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
|
* been exported
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
export_pubkeys_stream( IOBUF out, strlist_t users,
|
export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
|
||||||
KBNODE *keyblock_out, unsigned int options )
|
kbnode_t *keyblock_out, unsigned int options )
|
||||||
{
|
{
|
||||||
int any, rc;
|
int any, rc;
|
||||||
|
|
||||||
rc = do_export_stream( out, users, 0, keyblock_out, options, &any );
|
rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any);
|
||||||
if( !rc && !any )
|
if (!rc && !any)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
export_seckeys( strlist_t users )
|
export_seckeys (ctrl_t ctrl, strlist_t users )
|
||||||
{
|
{
|
||||||
/* Use only relevant options for the secret key. */
|
/* Use only relevant options for the secret key. */
|
||||||
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
||||||
return do_export( users, 1, options );
|
return do_export (ctrl, users, 1, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
export_secsubkeys( strlist_t users )
|
export_secsubkeys (ctrl_t ctrl, strlist_t users )
|
||||||
{
|
{
|
||||||
/* Use only relevant options for the secret key. */
|
/* Use only relevant options for the secret key. */
|
||||||
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
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
|
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;
|
IOBUF out = NULL;
|
||||||
int any, rc;
|
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());
|
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 )
|
if ( rc || !any )
|
||||||
iobuf_cancel (out);
|
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
|
/* Return a canonicalized public key algoithms. This is used to
|
||||||
contains a pointer to the first keyblock found and exported. No
|
compare different flavors of algorithms (e.g. ELG and ELG_E are
|
||||||
other keyblocks are exported. The caller must free it. */
|
considered the same). */
|
||||||
static int
|
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)
|
kbnode_t *keyblock_out, unsigned int options, int *any)
|
||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
@ -292,6 +611,7 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
KEYDB_HANDLE kdbhd;
|
KEYDB_HANDLE kdbhd;
|
||||||
strlist_t sl;
|
strlist_t sl;
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
|
gcry_cipher_hd_t cipherhd = NULL;
|
||||||
|
|
||||||
*any = 0;
|
*any = 0;
|
||||||
init_packet (&pkt);
|
init_packet (&pkt);
|
||||||
@ -330,21 +650,51 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
if (secret)
|
if (secret)
|
||||||
{
|
{
|
||||||
log_error (_("exporting secret keys not allowed\n"));
|
log_error (_("exporting secret keys not allowed\n"));
|
||||||
err = G10ERR_GENERAL;
|
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
#endif
|
#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)))
|
while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex)))
|
||||||
{
|
{
|
||||||
int sha1_warned = 0;
|
|
||||||
int skip_until_subkey = 0;
|
int skip_until_subkey = 0;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
|
PKT_public_key *pk;
|
||||||
|
|
||||||
if (!users)
|
if (!users)
|
||||||
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
||||||
|
|
||||||
/* Read the keyblock. */
|
/* Read the keyblock. */
|
||||||
|
release_kbnode (keyblock);
|
||||||
|
keyblock = NULL;
|
||||||
err = keydb_get_keyblock (kdbhd, &keyblock);
|
err = keydb_get_keyblock (kdbhd, &keyblock);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -352,60 +702,57 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
goto leave;
|
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. */
|
/* No v3 keys with GNU mode 1001. */
|
||||||
if( secret == 2
|
if (secret == 2 && pk->version == 3)
|
||||||
&& pk->seckey_info && !pk->seckey_info->is_protected )
|
|
||||||
{
|
{
|
||||||
log_info (_("key %s: not protected - skipped\n"),
|
log_info (_("key %s: PGP 2.x style key - skipped\n"),
|
||||||
keystr (keyid));
|
keystr (keyid));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No v3 keys with GNU mode 1001. */
|
/* The agent does not yet allow to export v3 packets. It is
|
||||||
if( secret == 2 && pk->version == 3 )
|
actually questionable whether we should allow them at
|
||||||
|
all. */
|
||||||
|
if (pk->version == 3)
|
||||||
{
|
{
|
||||||
log_info(_("key %s: PGP 2.x style key - skipped\n"),
|
log_info ("key %s: PGP 2.x style key (v3) export "
|
||||||
keystr (keyid));
|
"not yet supported - skipped\n", keystr (keyid));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* It does not make sense to export a key with a primary
|
/* Always do the cleaning on the public key part if requested.
|
||||||
key on card using a non-key stub. We simply skip those
|
Note that we don't yet set this option if we are exporting
|
||||||
keys when used with --export-secret-subkeys. */
|
secret keys. Note that both export-clean and export-minimal
|
||||||
if (secret == 2
|
only apply to UID sigs (0x10, 0x11, 0x12, and 0x13). A
|
||||||
&& pk->seckey_info && pk->seckey_info->is_protected
|
designated revocation is never stripped, even with
|
||||||
&& pk->seckey_info->s2k.mode == 1002 )
|
export-minimal set. */
|
||||||
{
|
if ((options & EXPORT_CLEAN))
|
||||||
log_info(_("key %s: key material on-card - skipped\n"),
|
clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And write it. */
|
/* And write it. */
|
||||||
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
|
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
|
||||||
{
|
{
|
||||||
if (skip_until_subkey)
|
if (skip_until_subkey)
|
||||||
{
|
{
|
||||||
if (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
|
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
|| node->pkt->pkttype==PKT_SECRET_SUBKEY)
|
|
||||||
skip_until_subkey = 0;
|
skip_until_subkey = 0;
|
||||||
else
|
else
|
||||||
continue;
|
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
|
(plus the primary key, if the user didn't specifically
|
||||||
request it). */
|
request it). */
|
||||||
if (desc[descindex].exact
|
if (desc[descindex].exact
|
||||||
&& (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
&& node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY))
|
|
||||||
{
|
{
|
||||||
if (!exact_subkey_match_p (desc+descindex, node))
|
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.
|
skip in any case if the key is in that list.
|
||||||
|
|
||||||
We need this whole mess because the import
|
We need this whole mess because the import
|
||||||
function is not able to merge secret keys and
|
function of GnuPG < 2.1 is not able to merge
|
||||||
thus it is useless to output them as two separate
|
secret keys and thus it is useless to output them
|
||||||
keys and have import merge them. */
|
as two separate keys and have import merge them. */
|
||||||
if (subkey_in_list_p (subkey_list, node))
|
if (subkey_in_list_p (subkey_list, node))
|
||||||
skip_until_subkey = 1; /* Already processed this one. */
|
skip_until_subkey = 1; /* Already processed this one. */
|
||||||
else
|
else
|
||||||
@ -508,88 +854,181 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
continue;
|
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
|
u32 subkidbuf[2], *subkid;
|
||||||
* primary key, this is done by temporary switching to
|
char *hexgrip, *serialno;
|
||||||
* GNU protection mode 1001. */
|
|
||||||
int save_mode = node->pkt->pkt.public_key->seckey_info->s2k.mode;
|
pk = node->pkt->pkt.public_key;
|
||||||
node->pkt->pkt.public_key->seckey_info->s2k.mode = 1001;
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||||
if ((options&EXPORT_SEXP_FORMAT))
|
subkid = NULL;
|
||||||
err = build_sexp (out, node->pkt, &indent);
|
|
||||||
else
|
else
|
||||||
err = build_packet (out, node->pkt);
|
{
|
||||||
node->pkt->pkt.public_key->seckey_info->s2k.mode = save_mode;
|
keyid_from_pk (pk, subkidbuf);
|
||||||
}
|
subkid = subkidbuf;
|
||||||
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; */
|
|
||||||
|
|
||||||
/* sk_save = node->pkt->pkt.secret_key; */
|
if (pk->seckey_info)
|
||||||
/* sk = copy_secret_key (NULL, sk_save); */
|
{
|
||||||
/* node->pkt->pkt.secret_key = sk; */
|
log_error ("key %s: oops: seckey_info already set"
|
||||||
|
" - skipped\n", keystr_with_sub (keyid, subkid));
|
||||||
|
skip_until_subkey = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* log_info (_("about to export an unprotected subkey\n")); */
|
if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||||
/* switch (is_secret_key_protected (sk)) */
|
{
|
||||||
/* { */
|
/* We are asked not to export the secret parts of
|
||||||
/* case -1: */
|
the primary key. Make up an error code to create
|
||||||
/* err = gpg_error (GPG_ERR_PUBKEY_ALGO); */
|
the stub. */
|
||||||
/* break; */
|
err = GPG_ERR_NOT_FOUND;
|
||||||
/* case 0: */
|
serialno = NULL;
|
||||||
/* break; */
|
}
|
||||||
/* default: */
|
else
|
||||||
/* if (sk->protect.s2k.mode == 1001) */
|
err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
|
||||||
/* ; /\* 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; */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* if ((options&EXPORT_SEXP_FORMAT)) */
|
if ((!err && serialno)
|
||||||
/* err = build_sexp (out, node->pkt, &indent); */
|
&& secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||||
/* else */
|
{
|
||||||
/* err = build_packet (out, node->pkt); */
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
/* node->pkt->pkt.secret_key = sk_save; */
|
ski->is_protected = 1;
|
||||||
/* free_secret_key (sk); */
|
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
|
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))
|
if ((options&EXPORT_SEXP_FORMAT))
|
||||||
err = build_sexp (out, node->pkt, &indent);
|
err = build_sexp (out, node->pkt, &indent);
|
||||||
else
|
else
|
||||||
@ -602,6 +1041,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
node->pkt->pkttype, gpg_strerror (err));
|
node->pkt->pkttype, gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!skip_until_subkey)
|
||||||
|
*any = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((options&EXPORT_SEXP_FORMAT) && indent)
|
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');
|
iobuf_put (out, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
++*any;
|
if (keyblock_out)
|
||||||
if(keyblock_out)
|
|
||||||
{
|
{
|
||||||
*keyblock_out=keyblock;
|
*keyblock_out = keyblock;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -624,10 +1065,11 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
iobuf_put (out, ')');
|
iobuf_put (out, ')');
|
||||||
iobuf_put (out, '\n');
|
iobuf_put (out, '\n');
|
||||||
}
|
}
|
||||||
if( err == -1 )
|
if (err == -1)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
gcry_cipher_close (cipherhd);
|
||||||
release_subkey_list (subkey_list);
|
release_subkey_list (subkey_list);
|
||||||
xfree(desc);
|
xfree(desc);
|
||||||
keydb_release (kdbhd);
|
keydb_release (kdbhd);
|
||||||
@ -672,6 +1114,10 @@ do_export_stream (iobuf_t out, strlist_t users, int secret,
|
|||||||
static int
|
static int
|
||||||
build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
|
build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
|
||||||
{
|
{
|
||||||
|
(void)out;
|
||||||
|
(void)pkt;
|
||||||
|
(void)indent;
|
||||||
|
|
||||||
/* FIXME: Not yet implemented. */
|
/* FIXME: Not yet implemented. */
|
||||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
/* PKT_secret_key *sk = pkt->pkt.secret_key; */
|
/* PKT_secret_key *sk = pkt->pkt.secret_key; */
|
||||||
@ -759,4 +1205,3 @@ build_sexp (iobuf_t out, PACKET *pkt, int *indent)
|
|||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "util.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "../common/iobuf.h"
|
#include "../common/iobuf.h"
|
||||||
#include "util.h"
|
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "options.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
|
to import the key via the online mechanisms defined by
|
||||||
--auto-key-locate. */
|
--auto-key-locate. */
|
||||||
int
|
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,
|
const char *name, KBNODE * ret_keyblock,
|
||||||
KEYDB_HANDLE * ret_kdbhd, int include_unusable, int no_akl)
|
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:
|
case AKL_CERT:
|
||||||
mechanism = "DNS CERT";
|
mechanism = "DNS CERT";
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AKL_PKA:
|
case AKL_PKA:
|
||||||
mechanism = "PKA";
|
mechanism = "PKA";
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AKL_LDAP:
|
case AKL_LDAP:
|
||||||
mechanism = "LDAP";
|
mechanism = "LDAP";
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -797,9 +797,8 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
{
|
{
|
||||||
mechanism = opt.keyserver->uri;
|
mechanism = opt.keyserver->uri;
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
glo_ctrl.in_auto_key_retrieve++;
|
||||||
rc =
|
rc = keyserver_import_name (ctrl, name, &fpr, &fpr_len,
|
||||||
keyserver_import_name (name, &fpr, &fpr_len,
|
opt.keyserver);
|
||||||
opt.keyserver);
|
|
||||||
glo_ctrl.in_auto_key_retrieve--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -816,7 +815,8 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
mechanism = akl->spec->uri;
|
mechanism = akl->spec->uri;
|
||||||
keyserver = keyserver_match (akl->spec);
|
keyserver = keyserver_match (akl->spec);
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
78
g10/gpg.c
78
g10/gpg.c
@ -37,9 +37,9 @@
|
|||||||
#define INCLUDED_BY_MAIN_MODULE 1
|
#define INCLUDED_BY_MAIN_MODULE 1
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
#include <assuan.h>
|
#include <assuan.h>
|
||||||
#include "packet.h"
|
|
||||||
#include "../common/iobuf.h"
|
#include "../common/iobuf.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "packet.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
@ -273,7 +273,6 @@ enum cmd_and_opt_values
|
|||||||
oS2KDigest,
|
oS2KDigest,
|
||||||
oS2KCipher,
|
oS2KCipher,
|
||||||
oS2KCount,
|
oS2KCount,
|
||||||
oSimpleSKChecksum,
|
|
||||||
oDisplayCharset,
|
oDisplayCharset,
|
||||||
oNotDashEscaped,
|
oNotDashEscaped,
|
||||||
oEscapeFrom,
|
oEscapeFrom,
|
||||||
@ -565,7 +564,6 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"),
|
ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"),
|
||||||
ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
|
ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
|
||||||
ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
|
ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
|
||||||
ARGPARSE_s_n (oSimpleSKChecksum, "simple-sk-checksum", "@"),
|
|
||||||
ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
|
ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
|
||||||
ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
|
ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
|
||||||
ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
|
ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
|
||||||
@ -2504,7 +2502,6 @@ main (int argc, char **argv)
|
|||||||
else
|
else
|
||||||
opt.s2k_count = 0; /* Auto-calibrate when needed. */
|
opt.s2k_count = 0; /* Auto-calibrate when needed. */
|
||||||
break;
|
break;
|
||||||
case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
|
|
||||||
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
|
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
|
||||||
case oEncryptTo: /* store the recipient in the second list */
|
case oEncryptTo: /* store the recipient in the second list */
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
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 );
|
fclose( configfp );
|
||||||
configfp = NULL;
|
configfp = NULL;
|
||||||
/* Remember the first config file name. */
|
/* Remember the first config file name. */
|
||||||
@ -2977,10 +2974,10 @@ main (int argc, char **argv)
|
|||||||
xfree(configname);
|
xfree(configname);
|
||||||
configname = NULL;
|
configname = NULL;
|
||||||
goto next_pass;
|
goto next_pass;
|
||||||
}
|
}
|
||||||
xfree( configname ); configname = NULL;
|
xfree(configname); configname = NULL;
|
||||||
if( log_get_errorcount(0) )
|
if (log_get_errorcount (0))
|
||||||
g10_exit(2);
|
g10_exit(2);
|
||||||
|
|
||||||
/* The command --gpgconf-list is pretty simple and may be called
|
/* The command --gpgconf-list is pretty simple and may be called
|
||||||
directly after the option parsing. */
|
directly after the option parsing. */
|
||||||
@ -3405,7 +3402,7 @@ main (int argc, char **argv)
|
|||||||
if(fname && utf8_strings)
|
if(fname && utf8_strings)
|
||||||
opt.flags.utf8_filename=1;
|
opt.flags.utf8_filename=1;
|
||||||
|
|
||||||
ctrl = xtrycalloc (1, sizeof *ctrl);
|
ctrl = xcalloc (1, sizeof *ctrl);
|
||||||
gpg_init_default_ctrl (ctrl);
|
gpg_init_default_ctrl (ctrl);
|
||||||
|
|
||||||
switch( cmd ) {
|
switch( cmd ) {
|
||||||
@ -3463,12 +3460,12 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
case aEncr: /* encrypt the given file */
|
case aEncr: /* encrypt the given file */
|
||||||
if(multifile)
|
if(multifile)
|
||||||
encrypt_crypt_files(argc, argv, remusr);
|
encrypt_crypt_files (ctrl, argc, argv, remusr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
wrong_args(_("--encrypt [filename]"));
|
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",
|
log_error("%s: encryption failed: %s\n",
|
||||||
print_fname_stdin(fname), g10_errstr(rc) );
|
print_fname_stdin(fname), g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
@ -3489,7 +3486,7 @@ main (int argc, char **argv)
|
|||||||
" while in %s mode\n"),compliance_option_string());
|
" while in %s mode\n"),compliance_option_string());
|
||||||
else
|
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",
|
log_error("%s: encryption failed: %s\n",
|
||||||
print_fname_stdin(fname), g10_errstr(rc) );
|
print_fname_stdin(fname), g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
@ -3509,7 +3506,7 @@ main (int argc, char **argv)
|
|||||||
strcpy(sl->d, fname);
|
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) );
|
log_error("signing failed: %s\n", g10_errstr(rc) );
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
@ -3523,7 +3520,7 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
sl = NULL;
|
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",
|
log_error("%s: sign+encrypt failed: %s\n",
|
||||||
print_fname_stdin(fname), g10_errstr(rc) );
|
print_fname_stdin(fname), g10_errstr(rc) );
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
@ -3547,7 +3544,8 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
sl = NULL;
|
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",
|
log_error("%s: symmetric+sign+encrypt failed: %s\n",
|
||||||
print_fname_stdin(fname), g10_errstr(rc) );
|
print_fname_stdin(fname), g10_errstr(rc) );
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
@ -3572,26 +3570,26 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case aVerify:
|
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) );
|
log_error("verify files failed: %s\n", g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( (rc = verify_signatures( argc, argv ) ))
|
if ((rc = verify_signatures (ctrl, argc, argv)))
|
||||||
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aDecrypt:
|
case aDecrypt:
|
||||||
if(multifile)
|
if (multifile)
|
||||||
decrypt_messages(argc, argv);
|
decrypt_messages (ctrl, argc, argv);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
wrong_args(_("--decrypt [filename]"));
|
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) );
|
log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3616,7 +3614,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
append_to_strlist( &sl, "save" );
|
append_to_strlist( &sl, "save" );
|
||||||
username = make_username( fname );
|
username = make_username( fname );
|
||||||
keyedit_menu (username, locusr, sl, 0, 0 );
|
keyedit_menu (ctrl, username, locusr, sl, 0, 0 );
|
||||||
xfree(username);
|
xfree(username);
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
@ -3629,11 +3627,11 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( argc--, argv++ ; argc; argc--, argv++ )
|
for( argc--, argv++ ; argc; argc--, argv++ )
|
||||||
append_to_strlist( &sl, *argv );
|
append_to_strlist( &sl, *argv );
|
||||||
keyedit_menu( username, locusr, sl, 0, 1 );
|
keyedit_menu (ctrl, username, locusr, sl, 0, 1 );
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
keyedit_menu(username, locusr, NULL, 0, 1 );
|
keyedit_menu (ctrl, username, locusr, NULL, 0, 1 );
|
||||||
xfree(username);
|
xfree(username);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3669,21 +3667,21 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
public_key_list( sl, 0 );
|
public_key_list (ctrl, sl, 0);
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
case aListSecretKeys:
|
case aListSecretKeys:
|
||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
secret_key_list( sl );
|
secret_key_list (ctrl, sl);
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
case aLocateKeys:
|
case aLocateKeys:
|
||||||
sl = NULL;
|
sl = NULL;
|
||||||
for (; argc; argc--, argv++)
|
for (; argc; argc--, argv++)
|
||||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
public_key_list (sl, 1);
|
public_key_list (ctrl, sl, 1);
|
||||||
free_strlist (sl);
|
free_strlist (sl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3718,11 +3716,11 @@ main (int argc, char **argv)
|
|||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
if( cmd == aSendKeys )
|
if( cmd == aSendKeys )
|
||||||
rc=keyserver_export( sl );
|
rc = keyserver_export (ctrl, sl );
|
||||||
else if( cmd == aRecvKeys )
|
else if( cmd == aRecvKeys )
|
||||||
rc=keyserver_import( sl );
|
rc = keyserver_import (ctrl, sl );
|
||||||
else
|
else
|
||||||
rc=export_pubkeys( sl, opt.export_options );
|
rc = export_pubkeys (ctrl, sl, opt.export_options);
|
||||||
if(rc)
|
if(rc)
|
||||||
{
|
{
|
||||||
if(cmd==aSendKeys)
|
if(cmd==aSendKeys)
|
||||||
@ -3739,7 +3737,7 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
rc=keyserver_search( sl );
|
rc = keyserver_search (ctrl, sl);
|
||||||
if(rc)
|
if(rc)
|
||||||
log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
|
log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
@ -3749,7 +3747,7 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
rc=keyserver_refresh(sl);
|
rc = keyserver_refresh (ctrl, sl);
|
||||||
if(rc)
|
if(rc)
|
||||||
log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
|
log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
@ -3759,7 +3757,7 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
append_to_strlist2( &sl, *argv, utf8_strings );
|
append_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
rc=keyserver_fetch(sl);
|
rc = keyserver_fetch (ctrl, sl);
|
||||||
if(rc)
|
if(rc)
|
||||||
log_error("key fetch failed: %s\n",g10_errstr(rc));
|
log_error("key fetch failed: %s\n",g10_errstr(rc));
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
@ -3769,7 +3767,7 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
export_seckeys( sl );
|
export_seckeys (ctrl, sl);
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3777,7 +3775,7 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for( ; argc; argc--, argv++ )
|
for( ; argc; argc--, argv++ )
|
||||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
export_secsubkeys( sl );
|
export_secsubkeys (ctrl, sl);
|
||||||
free_strlist(sl);
|
free_strlist(sl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3987,11 +3985,11 @@ main (int argc, char **argv)
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for (argc--, argv++ ; argc; argc--, argv++)
|
for (argc--, argv++ ; argc; argc--, argv++)
|
||||||
append_to_strlist (&sl, *argv);
|
append_to_strlist (&sl, *argv);
|
||||||
card_edit (sl);
|
card_edit (ctrl, sl);
|
||||||
free_strlist (sl);
|
free_strlist (sl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
card_edit (NULL);
|
card_edit (ctrl, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aChangePIN:
|
case aChangePIN:
|
||||||
@ -4045,7 +4043,7 @@ main (int argc, char **argv)
|
|||||||
set_packet_list_mode(1);
|
set_packet_list_mode(1);
|
||||||
opt.list_packets=1;
|
opt.list_packets=1;
|
||||||
}
|
}
|
||||||
rc = proc_packets(NULL, a );
|
rc = proc_packets (ctrl, NULL, a );
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error("processing message failed: %s\n", g10_errstr(rc) );
|
log_error("processing message failed: %s\n", g10_errstr(rc) );
|
||||||
iobuf_close(a);
|
iobuf_close(a);
|
||||||
|
14
g10/gpgv.c
14
g10/gpgv.c
@ -35,9 +35,9 @@
|
|||||||
|
|
||||||
#define INCLUDED_BY_MAIN_MODULE 1
|
#define INCLUDED_BY_MAIN_MODULE 1
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "util.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "iobuf.h"
|
#include "iobuf.h"
|
||||||
#include "util.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
@ -140,8 +140,9 @@ main( int argc, char **argv )
|
|||||||
ARGPARSE_ARGS pargs;
|
ARGPARSE_ARGS pargs;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
strlist_t sl;
|
strlist_t sl;
|
||||||
strlist_t nrings=NULL;
|
strlist_t nrings = NULL;
|
||||||
unsigned configlineno;
|
unsigned configlineno;
|
||||||
|
ctrl_t ctrl;
|
||||||
|
|
||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
log_set_prefix ("gpgv", 1);
|
log_set_prefix ("gpgv", 1);
|
||||||
@ -201,10 +202,14 @@ main( int argc, char **argv )
|
|||||||
keydb_add_resource (sl->d, 8);
|
keydb_add_resource (sl->d, 8);
|
||||||
|
|
||||||
FREE_STRLIST (nrings);
|
FREE_STRLIST (nrings);
|
||||||
|
|
||||||
|
ctrl = xcalloc (1, sizeof *ctrl);
|
||||||
|
|
||||||
if ( (rc = verify_signatures( argc, argv ) ))
|
if ((rc = verify_signatures (ctrl, argc, argv)))
|
||||||
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
||||||
|
|
||||||
|
xfree (ctrl);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
g10_exit (0);
|
g10_exit (0);
|
||||||
return 8; /*NOTREACHED*/
|
return 8; /*NOTREACHED*/
|
||||||
@ -377,8 +382,9 @@ get_override_session_key (DEK *dek, const char *string)
|
|||||||
|
|
||||||
/* Stub: */
|
/* Stub: */
|
||||||
int
|
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)procctx;
|
||||||
(void)ed;
|
(void)ed;
|
||||||
(void)dek;
|
(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,
|
IOBUF inp, const char* fname, struct stats_s *stats,
|
||||||
unsigned char **fpr, size_t *fpr_len, unsigned int options);
|
unsigned char **fpr, size_t *fpr_len, unsigned int options);
|
||||||
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
|
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
|
||||||
static void revocation_present(KBNODE keyblock);
|
static void revocation_present (ctrl_t ctrl, kbnode_t keyblock);
|
||||||
static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
|
static int import_one (ctrl_t ctrl,
|
||||||
unsigned char **fpr,size_t *fpr_len,
|
const char *fname, KBNODE keyblock,struct stats_s *stats,
|
||||||
unsigned int options,int from_sk);
|
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,
|
static int import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||||
struct stats_s *stats, unsigned int options);
|
struct stats_s *stats, unsigned int options);
|
||||||
static int import_revoke_cert( const char *fname, KBNODE node,
|
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) )) {
|
while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
|
||||||
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
|
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 )
|
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
|
||||||
rc = import_secret_one (ctrl, fname, keyblock, stats, options);
|
rc = import_secret_one (ctrl, fname, keyblock, stats, options);
|
||||||
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
|
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
|
||||||
@ -614,9 +616,9 @@ check_prefs_warning(PKT_public_key *pk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_prefs(KBNODE keyblock)
|
check_prefs (ctrl_t ctrl, kbnode_t keyblock)
|
||||||
{
|
{
|
||||||
KBNODE node;
|
kbnode_t node;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
int problem=0;
|
int problem=0;
|
||||||
|
|
||||||
@ -711,7 +713,7 @@ check_prefs(KBNODE keyblock)
|
|||||||
append_to_strlist(&sl,"updpref");
|
append_to_strlist(&sl,"updpref");
|
||||||
append_to_strlist(&sl,"save");
|
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(sl);
|
||||||
free_strlist(locusr);
|
free_strlist(locusr);
|
||||||
}
|
}
|
||||||
@ -728,7 +730,8 @@ check_prefs(KBNODE keyblock)
|
|||||||
* which called gpg.
|
* which called gpg.
|
||||||
*/
|
*/
|
||||||
static int
|
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,
|
unsigned char **fpr,size_t *fpr_len,unsigned int options,
|
||||||
int from_sk )
|
int from_sk )
|
||||||
{
|
{
|
||||||
@ -1060,15 +1063,15 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
|||||||
|
|
||||||
if (mod_key)
|
if (mod_key)
|
||||||
{
|
{
|
||||||
revocation_present (keyblock_orig);
|
revocation_present (ctrl, keyblock_orig);
|
||||||
if (!from_sk && have_secret_key_with_kid (keyid))
|
if (!from_sk && have_secret_key_with_kid (keyid))
|
||||||
check_prefs (keyblock_orig);
|
check_prefs (ctrl, keyblock_orig);
|
||||||
}
|
}
|
||||||
else if (new_key)
|
else if (new_key)
|
||||||
{
|
{
|
||||||
revocation_present (keyblock);
|
revocation_present (ctrl, keyblock);
|
||||||
if (!from_sk && have_secret_key_with_kid (keyid))
|
if (!from_sk && have_secret_key_with_kid (keyid))
|
||||||
check_prefs (keyblock);
|
check_prefs (ctrl, keyblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_kbnode( keyblock_orig );
|
release_kbnode( keyblock_orig );
|
||||||
@ -1425,7 +1428,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
keystr_from_pk (pk));
|
keystr_from_pk (pk));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
import_one (fname, pub_keyblock, stats,
|
import_one (ctrl, fname, pub_keyblock, stats,
|
||||||
NULL, NULL, opt.import_options, 1);
|
NULL, NULL, opt.import_options, 1);
|
||||||
/* Fixme: We should check for an invalid keyblock and
|
/* Fixme: We should check for an invalid keyblock and
|
||||||
cancel the secret key import in this case. */
|
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));
|
keystr_from_pk (pk));
|
||||||
if (is_status_enabled ())
|
if (is_status_enabled ())
|
||||||
print_import_ok (pk, 1|16);
|
print_import_ok (pk, 1|16);
|
||||||
check_prefs (node);
|
check_prefs (ctrl, node);
|
||||||
}
|
}
|
||||||
release_kbnode (node);
|
release_kbnode (node);
|
||||||
}
|
}
|
||||||
@ -2051,10 +2054,10 @@ collapse_uids( KBNODE *keyblock )
|
|||||||
present. This may be called without the benefit of merge_xxxx so
|
present. This may be called without the benefit of merge_xxxx so
|
||||||
you can't rely on pk->revkey and friends. */
|
you can't rely on pk->revkey and friends. */
|
||||||
static void
|
static void
|
||||||
revocation_present(KBNODE keyblock)
|
revocation_present (ctrl_t ctrl, kbnode_t keyblock)
|
||||||
{
|
{
|
||||||
KBNODE onode,inode;
|
kbnode_t onode, inode;
|
||||||
PKT_public_key *pk=keyblock->pkt->pkt.public_key;
|
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
|
||||||
|
|
||||||
for(onode=keyblock->next;onode;onode=onode->next)
|
for(onode=keyblock->next;onode;onode=onode->next)
|
||||||
{
|
{
|
||||||
@ -2106,9 +2109,10 @@ revocation_present(KBNODE keyblock)
|
|||||||
log_info(_("WARNING: key %s may be revoked:"
|
log_info(_("WARNING: key %s may be revoked:"
|
||||||
" fetching revocation key %s\n"),
|
" fetching revocation key %s\n"),
|
||||||
tempkeystr,keystr(keyid));
|
tempkeystr,keystr(keyid));
|
||||||
keyserver_import_fprint(sig->revkey[idx]->fpr,
|
keyserver_import_fprint (ctrl,
|
||||||
MAX_FINGERPRINT_LEN,
|
sig->revkey[idx]->fpr,
|
||||||
opt.keyserver);
|
MAX_FINGERPRINT_LEN,
|
||||||
|
opt.keyserver);
|
||||||
|
|
||||||
/* Do we have it now? */
|
/* Do we have it now? */
|
||||||
rc=get_pubkey_byfprint_fast (NULL,
|
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 );
|
int check_signatures_trust( PKT_signature *sig );
|
||||||
|
|
||||||
void release_pk_list (PK_LIST pk_list);
|
void release_pk_list (PK_LIST pk_list);
|
||||||
int build_pk_list (strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use);
|
int build_pk_list (ctrl_t ctrl,
|
||||||
gpg_error_t find_and_check_key (const char *name, unsigned int use,
|
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 mark_hidden, pk_list_t *pk_list_addr);
|
||||||
|
|
||||||
int algo_available( preftype_t preftype, int algo,
|
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( PKT_public_key *pk, u32 *keyid );
|
||||||
int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
|
int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
|
||||||
KBNODE get_pubkeyblock( 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,
|
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
||||||
int include_unusable, int no_akl );
|
int include_unusable, int no_akl );
|
||||||
int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
|
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_delsig (KBNODE pub_keyblock);
|
||||||
static int menu_clean (KBNODE keyblock, int self_only);
|
static int menu_clean (KBNODE keyblock, int self_only);
|
||||||
static void menu_delkey (KBNODE pub_keyblock);
|
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_expire (KBNODE pub_keyblock);
|
||||||
static int menu_backsign (KBNODE pub_keyblock);
|
static int menu_backsign (KBNODE pub_keyblock);
|
||||||
static int menu_set_primary_uid (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. */
|
/* Main function of the menu driven key editor. */
|
||||||
void
|
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)
|
strlist_t commands, int quiet, int seckey_check)
|
||||||
{
|
{
|
||||||
enum cmdids cmd = 0;
|
enum cmdids cmd = 0;
|
||||||
@ -1599,7 +1599,6 @@ keyedit_menu (const char *username, strlist_t locusr,
|
|||||||
int modified = 0;
|
int modified = 0;
|
||||||
int toggle;
|
int toggle;
|
||||||
int have_commands = !!commands;
|
int have_commands = !!commands;
|
||||||
ctrl_t ctrl = NULL; /* Dummy for now. */
|
|
||||||
|
|
||||||
if (opt.command_fd != -1)
|
if (opt.command_fd != -1)
|
||||||
;
|
;
|
||||||
@ -1623,7 +1622,7 @@ keyedit_menu (const char *username, strlist_t locusr,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get the public key */
|
/* 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)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
if (fix_keyblock (keyblock))
|
if (fix_keyblock (keyblock))
|
||||||
@ -2095,7 +2094,7 @@ keyedit_menu (const char *username, strlist_t locusr,
|
|||||||
|
|
||||||
if (ascii_strcasecmp (arg_string, "sensitive") == 0)
|
if (ascii_strcasecmp (arg_string, "sensitive") == 0)
|
||||||
sensitive = 1;
|
sensitive = 1;
|
||||||
if (menu_addrevoker (keyblock, sensitive))
|
if (menu_addrevoker (ctrl, keyblock, sensitive))
|
||||||
{
|
{
|
||||||
redisplay = 1;
|
redisplay = 1;
|
||||||
modified = 1;
|
modified = 1;
|
||||||
@ -2886,9 +2885,10 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
|
|||||||
if (pk->is_revoked)
|
if (pk->is_revoked)
|
||||||
{
|
{
|
||||||
char *user = get_user_id_string_native (pk->revoked.keyid);
|
char *user = get_user_id_string_native (pk->revoked.keyid);
|
||||||
const char *algo = gcry_pk_algo_name (pk->revoked.algo);
|
tty_printf (_("The following key was revoked on"
|
||||||
tty_printf (_("This key was revoked on %s by %s key %s\n"),
|
" %s by %s key %s\n"),
|
||||||
revokestr_from_pk (pk), algo ? algo : "?", user);
|
revokestr_from_pk (pk),
|
||||||
|
gcry_pk_algo_name (pk->revoked.algo), user);
|
||||||
xfree (user);
|
xfree (user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3444,7 +3444,7 @@ menu_delkey (KBNODE pub_keyblock)
|
|||||||
* the keyblock. Returns true if there is a new revoker.
|
* the keyblock. Returns true if there is a new revoker.
|
||||||
*/
|
*/
|
||||||
static int
|
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 *pk = NULL;
|
||||||
PKT_public_key *revoker_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
|
primary keys only, but some casual testing shows that PGP and
|
||||||
GnuPG both can handle a designated revocation from a subkey. */
|
GnuPG both can handle a designated revocation from a subkey. */
|
||||||
revoker_pk->req_usage = PUBKEY_USAGE_CERT;
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error (_("key \"%s\" not found: %s\n"), answer,
|
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++)
|
for (i=0; i<idx; i++)
|
||||||
{
|
{
|
||||||
xfree (array[i]);
|
gcry_mpi_release (array[i]);
|
||||||
array[i] = NULL;
|
array[i] = NULL;
|
||||||
}
|
}
|
||||||
gcry_sexp_release (list);
|
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;
|
char *p;
|
||||||
|
|
||||||
mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
|
mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
|
||||||
p = buffer + strlen (buffer);
|
if (sub_kid)
|
||||||
*p++ = '/';
|
{
|
||||||
mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
|
p = buffer + strlen (buffer);
|
||||||
|
*p++ = '/';
|
||||||
|
mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
|
||||||
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,9 +265,10 @@ const char *
|
|||||||
keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
|
keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
|
||||||
{
|
{
|
||||||
keyid_from_pk (main_pk, NULL);
|
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_all (int);
|
||||||
static void list_one (strlist_t names, int secret);
|
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);
|
static void print_card_serialno (PKT_public_key *sk);
|
||||||
|
|
||||||
struct sig_stats
|
struct sig_stats
|
||||||
@ -61,7 +61,7 @@ static estream_t attrib_fp;
|
|||||||
With LOCATE_MODE set the locate algorithm is used to find a
|
With LOCATE_MODE set the locate algorithm is used to find a
|
||||||
key. */
|
key. */
|
||||||
void
|
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)
|
if (opt.with_colons)
|
||||||
{
|
{
|
||||||
@ -107,7 +107,7 @@ public_key_list (strlist_t list, int locate_mode)
|
|||||||
check_trustdb_stale ();
|
check_trustdb_stale ();
|
||||||
|
|
||||||
if (locate_mode)
|
if (locate_mode)
|
||||||
locate_one (list);
|
locate_one (ctrl, list);
|
||||||
else if (!list)
|
else if (!list)
|
||||||
list_all (0);
|
list_all (0);
|
||||||
else
|
else
|
||||||
@ -116,8 +116,10 @@ public_key_list (strlist_t list, int locate_mode)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
secret_key_list (strlist_t list)
|
secret_key_list (ctrl_t ctrl, strlist_t list)
|
||||||
{
|
{
|
||||||
|
(void)ctrl;
|
||||||
|
|
||||||
check_trustdb_stale ();
|
check_trustdb_stale ();
|
||||||
|
|
||||||
if (!list)
|
if (!list)
|
||||||
@ -533,7 +535,7 @@ list_one (strlist_t names, int secret)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
locate_one (strlist_t names)
|
locate_one (ctrl_t ctrl, strlist_t names)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
strlist_t sl;
|
strlist_t sl;
|
||||||
@ -545,7 +547,7 @@ locate_one (strlist_t names)
|
|||||||
|
|
||||||
for (sl = names; sl; sl = sl->next)
|
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 (rc)
|
||||||
{
|
{
|
||||||
if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
|
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,
|
const char *configname,
|
||||||
unsigned int configlineno);
|
unsigned int configlineno);
|
||||||
struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig);
|
struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig);
|
||||||
int keyserver_export(strlist_t users);
|
int keyserver_export (ctrl_t ctrl, strlist_t users);
|
||||||
int keyserver_import(strlist_t users);
|
int keyserver_import (ctrl_t ctrl, strlist_t users);
|
||||||
int keyserver_import_fprint(const byte *fprint,size_t fprint_len,
|
int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
|
||||||
struct keyserver_spec *keyserver);
|
struct keyserver_spec *keyserver);
|
||||||
int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver);
|
int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid,
|
||||||
int keyserver_refresh(strlist_t users);
|
struct keyserver_spec *keyserver);
|
||||||
int keyserver_search(strlist_t tokens);
|
int keyserver_refresh (ctrl_t ctrl, strlist_t users);
|
||||||
int keyserver_fetch(strlist_t urilist);
|
int keyserver_search (ctrl_t ctrl, strlist_t tokens);
|
||||||
int keyserver_import_cert(const char *name,
|
int keyserver_fetch (ctrl_t ctrl, strlist_t urilist);
|
||||||
unsigned char **fpr,size_t *fpr_len);
|
int keyserver_import_cert (ctrl_t ctrl, const char *name,
|
||||||
int keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len);
|
unsigned char **fpr,size_t *fpr_len);
|
||||||
int keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
|
int keyserver_import_pka (ctrl_t ctrl,
|
||||||
struct keyserver_spec *keyserver);
|
const char *name,unsigned char **fpr,size_t *fpr_len);
|
||||||
int keyserver_import_ldap(const char *name,
|
int keyserver_import_name (ctrl_t ctrl,
|
||||||
unsigned char **fpr,size_t *fpr_len);
|
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_ */
|
#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}
|
{NULL,0,NULL,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int keyserver_work(enum ks_action action,strlist_t list,
|
static int keyserver_work (ctrl_t ctrl, enum ks_action action,strlist_t list,
|
||||||
KEYDB_SEARCH_DESC *desc,int count,
|
KEYDB_SEARCH_DESC *desc,int count,
|
||||||
unsigned char **fpr,size_t *fpr_len,
|
unsigned char **fpr,size_t *fpr_len,
|
||||||
struct keyserver_spec *keyserver);
|
struct keyserver_spec *keyserver);
|
||||||
|
|
||||||
/* Reasonable guess */
|
/* Reasonable guess */
|
||||||
#define DEFAULT_MAX_CERT_SIZE 16384
|
#define DEFAULT_MAX_CERT_SIZE 16384
|
||||||
@ -732,7 +732,8 @@ parse_keyrec(char *keystring)
|
|||||||
(cosmetics, really) and to better take advantage of the keyservers
|
(cosmetics, really) and to better take advantage of the keyservers
|
||||||
that can do multiple fetches in one go (LDAP). */
|
that can do multiple fetches in one go (LDAP). */
|
||||||
static int
|
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;
|
char *answer;
|
||||||
|
|
||||||
@ -765,8 +766,8 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
|
|||||||
|
|
||||||
while((num=strsep(&split," ,"))!=NULL)
|
while((num=strsep(&split," ,"))!=NULL)
|
||||||
if(atoi(num)>=1 && atoi(num)<=numdesc)
|
if(atoi(num)>=1 && atoi(num)<=numdesc)
|
||||||
keyserver_work(KS_GET,NULL,&desc[atoi(num)-1],1,
|
keyserver_work (ctrl, KS_GET,NULL,&desc[atoi(num)-1],1,
|
||||||
NULL,NULL,opt.keyserver);
|
NULL,NULL,opt.keyserver);
|
||||||
|
|
||||||
xfree(answer);
|
xfree(answer);
|
||||||
return 1;
|
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
|
small, it will grow safely. If negative it disables the "Key x-y
|
||||||
of z" messages. searchstr should be UTF-8 (rather than native). */
|
of z" messages. searchstr should be UTF-8 (rather than native). */
|
||||||
static void
|
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;
|
int i=0,validcount=0,started=0,header=0,count=1;
|
||||||
unsigned int maxlen,buflen,numlines=0;
|
unsigned int maxlen,buflen,numlines=0;
|
||||||
@ -872,7 +873,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
|||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(show_prompt(desc,i,validcount?count:0,localstr))
|
if (show_prompt (ctrl, desc, i, validcount?count:0, localstr))
|
||||||
break;
|
break;
|
||||||
validcount=0;
|
validcount=0;
|
||||||
}
|
}
|
||||||
@ -901,7 +902,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr)
|
|||||||
/* screen_lines - 1 for the prompt. */
|
/* screen_lines - 1 for the prompt. */
|
||||||
if(numlines+keyrec->lines>opt.screen_lines-1)
|
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;
|
break;
|
||||||
else
|
else
|
||||||
numlines=0;
|
numlines=0;
|
||||||
@ -977,9 +978,10 @@ direct_uri_map(const char *scheme,unsigned int is_direct)
|
|||||||
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
|
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
keyserver_spawn (ctrl_t ctrl,
|
||||||
int count,int *prog,unsigned char **fpr,size_t *fpr_len,
|
enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||||
struct keyserver_spec *keyserver)
|
int count,int *prog,unsigned char **fpr,size_t *fpr_len,
|
||||||
|
struct keyserver_spec *keyserver)
|
||||||
{
|
{
|
||||||
int ret=0,i,gotversion=0,outofband=0;
|
int ret=0,i,gotversion=0,outofband=0;
|
||||||
strlist_t temp;
|
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
|
/* TODO: Remove Comment: lines from keys exported this
|
||||||
way? */
|
way? */
|
||||||
|
|
||||||
if(export_pubkeys_stream(buffer,temp,&block,
|
if(export_pubkeys_stream (ctrl, buffer,temp,&block,
|
||||||
opt.keyserver_options.export_options)==-1)
|
opt.keyserver_options.export_options)==-1)
|
||||||
iobuf_close(buffer);
|
iobuf_close(buffer);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1510,7 +1512,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KS_SEARCH:
|
case KS_SEARCH:
|
||||||
keyserver_search_prompt(spawn->fromchild,searchstr);
|
keyserver_search_prompt (ctrl, spawn->fromchild,searchstr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1529,9 +1531,10 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
keyserver_work (ctrl_t ctrl,
|
||||||
int count,unsigned char **fpr,size_t *fpr_len,
|
enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
||||||
struct keyserver_spec *keyserver)
|
int count,unsigned char **fpr,size_t *fpr_len,
|
||||||
|
struct keyserver_spec *keyserver)
|
||||||
{
|
{
|
||||||
int rc=0,ret=0;
|
int rc=0,ret=0;
|
||||||
|
|
||||||
@ -1549,7 +1552,8 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
|||||||
#else
|
#else
|
||||||
/* Spawn a handler */
|
/* 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)
|
if(ret)
|
||||||
{
|
{
|
||||||
switch(ret)
|
switch(ret)
|
||||||
@ -1599,7 +1603,7 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
keyserver_export(strlist_t users)
|
keyserver_export (ctrl_t ctrl, strlist_t users)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
strlist_t sl=NULL;
|
strlist_t sl=NULL;
|
||||||
@ -1624,7 +1628,7 @@ keyserver_export(strlist_t users)
|
|||||||
|
|
||||||
if(sl)
|
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);
|
free_strlist(sl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1632,7 +1636,7 @@ keyserver_export(strlist_t users)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
keyserver_import(strlist_t users)
|
keyserver_import (ctrl_t ctrl, strlist_t users)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
KEYDB_SEARCH_DESC *desc;
|
KEYDB_SEARCH_DESC *desc;
|
||||||
@ -1663,7 +1667,8 @@ keyserver_import(strlist_t users)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(count>0)
|
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);
|
xfree(desc);
|
||||||
|
|
||||||
@ -1671,8 +1676,8 @@ keyserver_import(strlist_t users)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
keyserver_import_fprint(const byte *fprint,size_t fprint_len,
|
keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
|
||||||
struct keyserver_spec *keyserver)
|
struct keyserver_spec *keyserver)
|
||||||
{
|
{
|
||||||
KEYDB_SEARCH_DESC desc;
|
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
|
/* TODO: Warn here if the fingerprint we got doesn't match the one
|
||||||
we asked for? */
|
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
|
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;
|
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[0]=keyid[0];
|
||||||
desc.u.kid[1]=keyid[1];
|
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 */
|
/* 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. */
|
usernames to refresh only part of the keyring. */
|
||||||
|
|
||||||
int
|
int
|
||||||
keyserver_refresh(strlist_t users)
|
keyserver_refresh (ctrl_t ctrl, strlist_t users)
|
||||||
{
|
{
|
||||||
int rc,count,numdesc,fakev3=0;
|
int rc,count,numdesc,fakev3=0;
|
||||||
KEYDB_SEARCH_DESC *desc;
|
KEYDB_SEARCH_DESC *desc;
|
||||||
@ -1908,7 +1914,8 @@ keyserver_refresh(strlist_t users)
|
|||||||
Note that a preferred keyserver without a scheme://
|
Note that a preferred keyserver without a scheme://
|
||||||
will be interpreted as hkp:// */
|
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)
|
if(rc)
|
||||||
log_info(_("WARNING: unable to refresh key %s"
|
log_info(_("WARNING: unable to refresh key %s"
|
||||||
" via %s: %s\n"),keystr_from_desc(&desc[i]),
|
" via %s: %s\n"),keystr_from_desc(&desc[i]),
|
||||||
@ -1938,7 +1945,8 @@ keyserver_refresh(strlist_t users)
|
|||||||
count,opt.keyserver->uri);
|
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);
|
xfree(desc);
|
||||||
@ -1954,16 +1962,16 @@ keyserver_refresh(strlist_t users)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
keyserver_search(strlist_t tokens)
|
keyserver_search (ctrl_t ctrl, strlist_t tokens)
|
||||||
{
|
{
|
||||||
if(tokens)
|
if (tokens)
|
||||||
return keyserver_work(KS_SEARCH,tokens,NULL,0,NULL,NULL,opt.keyserver);
|
return keyserver_work (ctrl, KS_SEARCH, tokens, NULL, 0,
|
||||||
else
|
NULL, NULL, opt.keyserver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
keyserver_fetch(strlist_t urilist)
|
keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
|
||||||
{
|
{
|
||||||
KEYDB_SEARCH_DESC desc;
|
KEYDB_SEARCH_DESC desc;
|
||||||
strlist_t sl;
|
strlist_t sl;
|
||||||
@ -1988,7 +1996,7 @@ keyserver_fetch(strlist_t urilist)
|
|||||||
{
|
{
|
||||||
int rc;
|
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)
|
if(rc)
|
||||||
log_info (_("WARNING: unable to fetch URI %s: %s\n"),
|
log_info (_("WARNING: unable to fetch URI %s: %s\n"),
|
||||||
sl->d,g10_errstr(rc));
|
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 */
|
/* Import key in a CERT or pointed to by a CERT */
|
||||||
int
|
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;
|
char *domain,*look,*url;
|
||||||
IOBUF key;
|
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);
|
spec=parse_keyserver_uri(url,1,NULL,0);
|
||||||
if(spec)
|
if(spec)
|
||||||
{
|
{
|
||||||
rc=keyserver_import_fprint(*fpr,*fpr_len,spec);
|
rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec);
|
||||||
free_keyserver_spec(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
|
/* If only a fingerprint is provided, try and fetch it from
|
||||||
our --keyserver */
|
our --keyserver */
|
||||||
|
|
||||||
rc=keyserver_import_fprint(*fpr,*fpr_len,opt.keyserver);
|
rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_info(_("no keyserver known (use option --keyserver)\n"));
|
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
|
/* Import key pointed to by a PKA record. Return the requested
|
||||||
fingerprint in fpr. */
|
fingerprint in fpr. */
|
||||||
int
|
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;
|
char *uri;
|
||||||
int rc = G10ERR_NO_PUBKEY;
|
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);
|
spec = parse_keyserver_uri (uri, 1, NULL, 0);
|
||||||
if (spec)
|
if (spec)
|
||||||
{
|
{
|
||||||
rc = keyserver_import_fprint (*fpr, 20, spec);
|
rc = keyserver_import_fprint (ctrl, *fpr, 20, spec);
|
||||||
free_keyserver_spec (spec);
|
free_keyserver_spec (spec);
|
||||||
}
|
}
|
||||||
xfree (uri);
|
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 */
|
/* Import all keys that match name */
|
||||||
int
|
int
|
||||||
keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
|
keyserver_import_name (ctrl_t ctrl, const char *name,
|
||||||
struct keyserver_spec *keyserver)
|
unsigned char **fpr, size_t *fpr_len,
|
||||||
|
struct keyserver_spec *keyserver)
|
||||||
{
|
{
|
||||||
strlist_t list=NULL;
|
strlist_t list=NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
append_to_strlist(&list,name);
|
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);
|
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 */
|
/* Import a key by name using LDAP */
|
||||||
int
|
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;
|
char *domain;
|
||||||
struct keyserver_spec *keyserver;
|
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);
|
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);
|
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 setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
||||||
int encrypt_symmetric (const char *filename );
|
int encrypt_symmetric (const char *filename );
|
||||||
int encrypt_store (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,
|
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
|
||||||
int outputfd);
|
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,
|
int encrypt_filter (void *opaque, int control,
|
||||||
iobuf_t a, byte *buf, size_t *ret_len);
|
iobuf_t a, byte *buf, size_t *ret_len);
|
||||||
|
|
||||||
@ -203,7 +204,7 @@ int encrypt_filter (void *opaque, int control,
|
|||||||
/*-- sign.c --*/
|
/*-- sign.c --*/
|
||||||
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
|
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
|
||||||
const char *cache_nonce);
|
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 do_encrypt, strlist_t remusr, const char *outfile );
|
||||||
int clearsign_file( const char *fname, strlist_t locusr, 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);
|
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 );
|
int delete_keys( strlist_t names, int secret, int allow_both );
|
||||||
|
|
||||||
/*-- keyedit.c --*/
|
/*-- 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 );
|
strlist_t commands, int quiet, int seckey_check );
|
||||||
void keyedit_passwd (const char *username);
|
void keyedit_passwd (const char *username);
|
||||||
void show_basic_key_info (KBNODE keyblock);
|
void show_basic_key_info (KBNODE keyblock);
|
||||||
@ -280,11 +281,11 @@ int collapse_uids( KBNODE *keyblock );
|
|||||||
|
|
||||||
/*-- export.c --*/
|
/*-- export.c --*/
|
||||||
int parse_export_options(char *str,unsigned int *options,int noisy);
|
int parse_export_options(char *str,unsigned int *options,int noisy);
|
||||||
int export_pubkeys( strlist_t users, unsigned int options );
|
int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options );
|
||||||
int export_pubkeys_stream( iobuf_t out, strlist_t users,
|
int export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
|
||||||
KBNODE *keyblock_out, unsigned int options );
|
kbnode_t *keyblock_out, unsigned int options );
|
||||||
int export_seckeys( strlist_t users );
|
int export_seckeys (ctrl_t ctrl, strlist_t users);
|
||||||
int export_secsubkeys( strlist_t users );
|
int export_secsubkeys (ctrl_t ctrl, strlist_t users);
|
||||||
|
|
||||||
/* dearmor.c --*/
|
/* dearmor.c --*/
|
||||||
int dearmor_file( const char *fname );
|
int dearmor_file( const char *fname );
|
||||||
@ -300,8 +301,8 @@ struct revocation_reason_info *
|
|||||||
void release_revocation_reason_info( struct revocation_reason_info *reason );
|
void release_revocation_reason_info( struct revocation_reason_info *reason );
|
||||||
|
|
||||||
/*-- keylist.c --*/
|
/*-- keylist.c --*/
|
||||||
void public_key_list( strlist_t list, int locate_mode );
|
void public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode );
|
||||||
void secret_key_list( strlist_t list );
|
void secret_key_list (ctrl_t ctrl, strlist_t list );
|
||||||
void print_subpackets_colon(PKT_signature *sig);
|
void print_subpackets_colon(PKT_signature *sig);
|
||||||
void reorder_keyblock (KBNODE keyblock);
|
void reorder_keyblock (KBNODE keyblock);
|
||||||
void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
|
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 --*/
|
/*-- verify.c --*/
|
||||||
void print_file_status( int status, const char *name, int what );
|
void print_file_status( int status, const char *name, int what );
|
||||||
int verify_signatures( int nfiles, char **files );
|
int verify_signatures (ctrl_t ctrl, int nfiles, char **files );
|
||||||
int verify_files( 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);
|
int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp);
|
||||||
|
|
||||||
/*-- decrypt.c --*/
|
/*-- decrypt.c --*/
|
||||||
int decrypt_message( const char *filename );
|
int decrypt_message (ctrl_t ctrl, const char *filename );
|
||||||
gpg_error_t decrypt_message_fd (int input_fd, int output_fd);
|
gpg_error_t decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd);
|
||||||
void decrypt_messages(int nfiles, char *files[]);
|
void decrypt_messages (ctrl_t ctrl, int nfiles, char *files[]);
|
||||||
|
|
||||||
/*-- plaintext.c --*/
|
/*-- plaintext.c --*/
|
||||||
int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2,
|
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 --*/
|
/*-- card-util.c --*/
|
||||||
void change_pin (int no, int allow_admin);
|
void change_pin (int no, int allow_admin);
|
||||||
void card_status (estream_t fp, char *serialno, size_t serialnobuflen);
|
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_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
|
||||||
int card_store_subkey (KBNODE node, int use);
|
int card_store_subkey (KBNODE node, int use);
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "util.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "iobuf.h"
|
#include "iobuf.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "util.h"
|
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@ -56,6 +56,7 @@ struct kidlist_item {
|
|||||||
typedef struct mainproc_context *CTX;
|
typedef struct mainproc_context *CTX;
|
||||||
struct mainproc_context
|
struct mainproc_context
|
||||||
{
|
{
|
||||||
|
ctrl_t ctrl;
|
||||||
struct mainproc_context *anchor; /* May be useful in the future. */
|
struct mainproc_context *anchor; /* May be useful in the future. */
|
||||||
PKT_public_key *last_pubkey;
|
PKT_public_key *last_pubkey;
|
||||||
PKT_user_id *last_user_id;
|
PKT_user_id *last_user_id;
|
||||||
@ -563,8 +564,8 @@ proc_encrypted( CTX c, PACKET *pkt )
|
|||||||
}
|
}
|
||||||
else if( !c->dek )
|
else if( !c->dek )
|
||||||
result = G10ERR_NO_SECKEY;
|
result = G10ERR_NO_SECKEY;
|
||||||
if( !result )
|
if (!result)
|
||||||
result = decrypt_data( c, pkt->pkt.encrypted, c->dek );
|
result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
|
||||||
|
|
||||||
if( result == -1 )
|
if( result == -1 )
|
||||||
;
|
;
|
||||||
@ -757,18 +758,19 @@ proc_compressed_cb( IOBUF a, void *info )
|
|||||||
{
|
{
|
||||||
if ( ((CTX)info)->signed_data.used
|
if ( ((CTX)info)->signed_data.used
|
||||||
&& ((CTX)info)->signed_data.data_fd != -1)
|
&& ((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);
|
((CTX)info)->signed_data.data_fd);
|
||||||
else
|
else
|
||||||
return proc_signature_packets (info, a,
|
return proc_signature_packets (((CTX)info)->ctrl, info, a,
|
||||||
((CTX)info)->signed_data.data_names,
|
((CTX)info)->signed_data.data_names,
|
||||||
((CTX)info)->sigfilename );
|
((CTX)info)->sigfilename );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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
|
static void
|
||||||
@ -781,11 +783,11 @@ proc_compressed( CTX c, PACKET *pkt )
|
|||||||
if( !zd->algorithm )
|
if( !zd->algorithm )
|
||||||
rc=G10ERR_COMPR_ALGO;
|
rc=G10ERR_COMPR_ALGO;
|
||||||
else if( c->sigs_only )
|
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 )
|
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
|
else
|
||||||
rc = handle_compressed( c, zd, NULL, NULL );
|
rc = handle_compressed (c->ctrl, c, zd, NULL, NULL );
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error("uncompressing failed: %s\n", g10_errstr(rc));
|
log_error("uncompressing failed: %s\n", g10_errstr(rc));
|
||||||
free_packet(pkt);
|
free_packet(pkt);
|
||||||
@ -1174,11 +1176,12 @@ list_node( CTX c, KBNODE node )
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
proc_packets( void *anchor, IOBUF a )
|
proc_packets (ctrl_t ctrl, void *anchor, IOBUF a )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
CTX c = xmalloc_clear( sizeof *c );
|
CTX c = xmalloc_clear( sizeof *c );
|
||||||
|
|
||||||
|
c->ctrl = ctrl;
|
||||||
c->anchor = anchor;
|
c->anchor = anchor;
|
||||||
rc = do_proc_packets( c, a );
|
rc = do_proc_packets( c, a );
|
||||||
xfree( c );
|
xfree( c );
|
||||||
@ -1188,12 +1191,13 @@ proc_packets( void *anchor, IOBUF a )
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
proc_signature_packets( void *anchor, IOBUF a,
|
proc_signature_packets (ctrl_t ctrl, void *anchor, IOBUF a,
|
||||||
strlist_t signedfiles, const char *sigfilename )
|
strlist_t signedfiles, const char *sigfilename )
|
||||||
{
|
{
|
||||||
CTX c = xmalloc_clear( sizeof *c );
|
CTX c = xmalloc_clear( sizeof *c );
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
c->ctrl = ctrl;
|
||||||
c->anchor = anchor;
|
c->anchor = anchor;
|
||||||
c->sigs_only = 1;
|
c->sigs_only = 1;
|
||||||
|
|
||||||
@ -1228,7 +1232,8 @@ proc_signature_packets( void *anchor, IOBUF a,
|
|||||||
|
|
||||||
|
|
||||||
int
|
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;
|
int rc;
|
||||||
CTX c;
|
CTX c;
|
||||||
@ -1237,6 +1242,7 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
|
|||||||
if (!c)
|
if (!c)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
|
c->ctrl = ctrl;
|
||||||
c->anchor = anchor;
|
c->anchor = anchor;
|
||||||
c->sigs_only = 1;
|
c->sigs_only = 1;
|
||||||
|
|
||||||
@ -1269,11 +1275,12 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd )
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
proc_encryption_packets( void *anchor, IOBUF a )
|
proc_encryption_packets (ctrl_t ctrl, void *anchor, IOBUF a )
|
||||||
{
|
{
|
||||||
CTX c = xmalloc_clear( sizeof *c );
|
CTX c = xmalloc_clear( sizeof *c );
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
c->ctrl = ctrl;
|
||||||
c->anchor = anchor;
|
c->anchor = anchor;
|
||||||
c->encrypt_only = 1;
|
c->encrypt_only = 1;
|
||||||
rc = do_proc_packets( c, a );
|
rc = do_proc_packets( c, a );
|
||||||
@ -1652,7 +1659,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
if(!res)
|
if(!res)
|
||||||
rc=do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
|
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)
|
if (spec)
|
||||||
{
|
{
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
free_keyserver_spec (spec);
|
free_keyserver_spec (spec);
|
||||||
if (!res)
|
if (!res)
|
||||||
@ -1702,7 +1709,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
glo_ctrl.in_auto_key_retrieve++;
|
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--;
|
glo_ctrl.in_auto_key_retrieve--;
|
||||||
if(!res)
|
if(!res)
|
||||||
rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
|
rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
|
||||||
|
@ -124,8 +124,6 @@ struct
|
|||||||
int s2k_cipher_algo;
|
int s2k_cipher_algo;
|
||||||
unsigned char s2k_count; /* This is the encoded form, not the raw
|
unsigned char s2k_count; /* This is the encoded form, not the raw
|
||||||
count */
|
count */
|
||||||
int simple_sk_checksum; /* create the deprecated rfc2440 secret key
|
|
||||||
protection */
|
|
||||||
int not_dash_escaped;
|
int not_dash_escaped;
|
||||||
int escape_from;
|
int escape_from;
|
||||||
int lock_once;
|
int lock_once;
|
||||||
|
13
g10/packet.h
13
g10/packet.h
@ -370,11 +370,12 @@ struct notation
|
|||||||
|
|
||||||
/*-- mainproc.c --*/
|
/*-- mainproc.c --*/
|
||||||
void reset_literals_seen(void);
|
void reset_literals_seen(void);
|
||||||
int proc_packets( void *ctx, iobuf_t a );
|
int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a );
|
||||||
int proc_signature_packets( void *ctx, iobuf_t a,
|
int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a,
|
||||||
strlist_t signedfiles, const char *sigfile );
|
strlist_t signedfiles, const char *sigfile );
|
||||||
int proc_signature_packets_by_fd ( void *anchor, IOBUF a, int signed_data_fd );
|
int proc_signature_packets_by_fd (ctrl_t ctrl,
|
||||||
int proc_encryption_packets( void *ctx, iobuf_t a );
|
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 );
|
int list_packets( iobuf_t a );
|
||||||
|
|
||||||
/*-- parse-packet.c --*/
|
/*-- 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);
|
gpg_error_t get_override_session_key (DEK *dek, const char *string);
|
||||||
|
|
||||||
/*-- compress.c --*/
|
/*-- 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 );
|
int (*callback)(iobuf_t, void *), void *passthru );
|
||||||
|
|
||||||
/*-- encr-data.c --*/
|
/*-- 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 --*/
|
/*-- plaintext.c --*/
|
||||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "util.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "iobuf.h"
|
#include "iobuf.h"
|
||||||
#include "util.h"
|
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "photoid.h"
|
#include "photoid.h"
|
||||||
|
@ -29,11 +29,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "util.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
#include "util.h"
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "iobuf.h"
|
#include "iobuf.h"
|
||||||
#include "options.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
|
of the key. USE the requested usage and a set MARK_HIDDEN will mark
|
||||||
the key in the updated list as a hidden recipient. */
|
the key in the updated list as a hidden recipient. */
|
||||||
gpg_error_t
|
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 mark_hidden, pk_list_t *pk_list_addr)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@ -793,7 +793,7 @@ find_and_check_key (const char *name, unsigned int use,
|
|||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
pk->req_usage = use;
|
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)
|
if (rc)
|
||||||
{
|
{
|
||||||
/* Key not found or other error. */
|
/* Key not found or other error. */
|
||||||
@ -883,7 +883,8 @@ find_and_check_key (const char *name, unsigned int use,
|
|||||||
not changed.
|
not changed.
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
PK_LIST pk_list = NULL;
|
||||||
PKT_public_key *pk=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 explicitly allow encrypt-to to an disabled key; thus
|
||||||
we pass 1for the second last argument and 1 as the last
|
we pass 1for the second last argument and 1 as the last
|
||||||
argument to disable AKL. */
|
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;
|
free_public_key ( pk ); pk = NULL;
|
||||||
log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
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);
|
free_public_key (pk);
|
||||||
pk = xmalloc_clear( sizeof *pk );
|
pk = xmalloc_clear( sizeof *pk );
|
||||||
pk->req_usage = use;
|
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)
|
if (rc)
|
||||||
tty_printf(_("No such user ID.\n"));
|
tty_printf(_("No such user ID.\n"));
|
||||||
else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
|
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
|
/* The default recipient is allowed to be disabled; thus pass 1
|
||||||
as second last argument. We also don't want an AKL. */
|
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)
|
if (rc)
|
||||||
log_error(_("unknown default recipient \"%s\"\n"), def_rec );
|
log_error(_("unknown default recipient \"%s\"\n"), def_rec );
|
||||||
else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) )
|
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) )
|
if ( (remusr->flags & 1) )
|
||||||
continue; /* encrypt-to keys are already handled. */
|
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);
|
&pk_list);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -231,7 +231,7 @@ cmd_recipient (assuan_context_t ctx, char *line)
|
|||||||
remusr = rcpts;
|
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);
|
&ctrl->server_local->recplist);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -324,7 +324,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
/* fixme: err = ctrl->audit? 0 : start_audit_session (ctrl);*/
|
/* 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,
|
ctrl->server_local->recplist,
|
||||||
out_fd);
|
out_fd);
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ cmd_decrypt (assuan_context_t ctx, char *line)
|
|||||||
return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
|
return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
|
||||||
|
|
||||||
glo_ctrl.lasterr = 0;
|
glo_ctrl.lasterr = 0;
|
||||||
err = decrypt_message_fd (inp_fd, out_fd);
|
err = decrypt_message_fd (ctrl, inp_fd, out_fd);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = glo_ctrl.lasterr;
|
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.
|
* uncompressed, non-armored and in binary mode.
|
||||||
*/
|
*/
|
||||||
int
|
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 )
|
int encryptflag, strlist_t remusr, const char *outfile )
|
||||||
{
|
{
|
||||||
const char *fname;
|
const char *fname;
|
||||||
@ -822,7 +822,8 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
|||||||
compliance_failure();
|
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;
|
goto leave;
|
||||||
|
|
||||||
/* prepare iobufs */
|
/* prepare iobufs */
|
||||||
|
16
g10/verify.c
16
g10/verify.c
@ -50,7 +50,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
verify_signatures( int nfiles, char **files )
|
verify_signatures (ctrl_t ctrl, int nfiles, char **files )
|
||||||
{
|
{
|
||||||
IOBUF fp;
|
IOBUF fp;
|
||||||
armor_filter_context_t *afx = NULL;
|
armor_filter_context_t *afx = NULL;
|
||||||
@ -110,7 +110,7 @@ verify_signatures( int nfiles, char **files )
|
|||||||
sl = NULL;
|
sl = NULL;
|
||||||
for(i=nfiles-1 ; i > 0 ; i-- )
|
for(i=nfiles-1 ; i > 0 ; i-- )
|
||||||
add_to_strlist( &sl, files[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);
|
free_strlist(sl);
|
||||||
iobuf_close(fp);
|
iobuf_close(fp);
|
||||||
if( (afx && afx->no_openpgp_data && rc == -1) || rc == G10ERR_NO_DATA ) {
|
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
|
static int
|
||||||
verify_one_file( const char *name )
|
verify_one_file (ctrl_t ctrl, const char *name )
|
||||||
{
|
{
|
||||||
IOBUF fp;
|
IOBUF fp;
|
||||||
armor_filter_context_t *afx = NULL;
|
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);
|
iobuf_close(fp);
|
||||||
write_status( STATUS_FILE_DONE );
|
write_status( STATUS_FILE_DONE );
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ verify_one_file( const char *name )
|
|||||||
* Note: This function can not handle detached signatures.
|
* Note: This function can not handle detached signatures.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
verify_files( int nfiles, char **files )
|
verify_files (ctrl_t ctrl, int nfiles, char **files )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -208,13 +208,13 @@ verify_files( int nfiles, char **files )
|
|||||||
* also no script languages available. We don't strip any
|
* also no script languages available. We don't strip any
|
||||||
* spaces, so that we can process nearly all filenames */
|
* spaces, so that we can process nearly all filenames */
|
||||||
line[strlen(line)-1] = 0;
|
line[strlen(line)-1] = 0;
|
||||||
verify_one_file( line );
|
verify_one_file (ctrl, line );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else { /* take filenames from the array */
|
else { /* take filenames from the array */
|
||||||
for(i=0; i < nfiles; i++ )
|
for(i=0; i < nfiles; i++ )
|
||||||
verify_one_file( files[i] );
|
verify_one_file (ctrl, files[i] );
|
||||||
}
|
}
|
||||||
return 0;
|
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);
|
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
|
if ( afx && afx->no_openpgp_data
|
||||||
&& (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) )
|
&& (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]);
|
DEBUGOUT_1 (" bMaxCCIDBusySlots %5u\n", buf[53]);
|
||||||
|
|
||||||
if (buf[0] > 54) {
|
if (buf[0] > 54)
|
||||||
DEBUGOUT (" junk ");
|
{
|
||||||
for (i=54; i < buf[0]-54; i++)
|
DEBUGOUT (" junk ");
|
||||||
DEBUGOUT_CONT_1 (" %02X", buf[i]);
|
for (i=54; i < buf[0]-54; i++)
|
||||||
DEBUGOUT_LF ();
|
DEBUGOUT_CONT_1 (" %02X", buf[i]);
|
||||||
}
|
DEBUGOUT_LF ();
|
||||||
|
}
|
||||||
|
|
||||||
if (!have_t1 || !(have_tpdu || handle->apdu_level) || !have_auto_conf)
|
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>
|
2010-08-16 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpgsm.c (main) <aGPGConfList>: Use es_printf.
|
* 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
|
because we can assume that the --learn-card command has been used
|
||||||
on purpose. */
|
on purpose. */
|
||||||
rc = gpgsm_basic_cert_check (parm->ctrl, cert);
|
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));
|
log_error ("invalid certificate: %s\n", gpg_strerror (rc));
|
||||||
else
|
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. */
|
print an error here. */
|
||||||
if (rc != -1 && opt.verbose > 1)
|
if (rc != -1 && opt.verbose > 1)
|
||||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
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;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,7 +1496,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
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;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1897,7 +1897,7 @@ gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_error ("failed to find issuer's certificate: rc=%d\n", rc);
|
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;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
|
|
||||||
ARGPARSE_s_s (oAuditLog, "audit-log",
|
ARGPARSE_s_s (oAuditLog, "audit-log",
|
||||||
N_("|FILE|write an audit log to FILE")),
|
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 (oDryRun, "dry-run", N_("do not make any changes")),
|
||||||
ARGPARSE_s_n (oBatch, "batch", N_("batch mode: never ask")),
|
ARGPARSE_s_n (oBatch, "batch", N_("batch mode: never ask")),
|
||||||
ARGPARSE_s_n (oAnswerYes, "yes", N_("assume yes on most questions")),
|
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)
|
if (!rc && ctrl->with_validation)
|
||||||
rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
|
rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL);
|
||||||
if (!rc || (!ctrl->with_validation
|
if (!rc || (!ctrl->with_validation
|
||||||
&& 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;
|
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"));
|
log_error (_("basic certificate checks failed - not imported\n"));
|
||||||
if (stats)
|
if (stats)
|
||||||
stats->not_imported++;
|
stats->not_imported++;
|
||||||
print_import_problem (ctrl, cert,
|
/* We keep the test for GPG_ERR_MISSING_CERT only in case
|
||||||
gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 :
|
GPG_ERR_MISSING_CERT has been used instead of the newer
|
||||||
gpg_err_code (rc) == GPG_ERR_BAD_CERT? 1 : 0);
|
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