Added gpg-agent OPTION "s2k-count".

When unset or 0, the calibrated count will be used.
This commit is contained in:
Ben Kibbey 2011-06-28 20:35:13 -04:00 committed by Werner Koch
parent c9e473618f
commit 137e3a0fbc
8 changed files with 41 additions and 15 deletions

View File

@ -1,3 +1,11 @@
2011-06-28 Ben Kibbey <bjk@luxsci.net>
* command.c (option_handler): Add option s2k-count.
* agent.h (server_control_s): Add member s2k_count.
* genkey.c (store_key): Add parameter s2k_count.
* protect.c (agent_protect): Add parameter s2k_count.
* protect.c (do_encryption): Add parameter s2k_count.
2011-06-01 Marcus Brinkmann <mb@g10code.com> 2011-06-01 Marcus Brinkmann <mb@g10code.com>
* cvt-openpgp.c (convert_to_openpgp): Change type of N to unsigned * cvt-openpgp.c (convert_to_openpgp): Change type of N to unsigned

View File

@ -181,6 +181,8 @@ struct server_control_s
PKSIGN command to the scdaemon. */ PKSIGN command to the scdaemon. */
int in_passwd; /* Hack to inhibit enforced passphrase change int in_passwd; /* Hack to inhibit enforced passphrase change
during an explicit passwd command. */ during an explicit passwd command. */
unsigned long s2k_count; /* Other than the calibrated count. */
}; };
@ -332,7 +334,8 @@ gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
unsigned long get_standard_s2k_count (void); unsigned long get_standard_s2k_count (void);
unsigned char get_standard_s2k_count_rfc4880 (void); unsigned char get_standard_s2k_count_rfc4880 (void);
int agent_protect (const unsigned char *plainkey, const char *passphrase, int agent_protect (const unsigned char *plainkey, const char *passphrase,
unsigned char **result, size_t *resultlen); unsigned char **result, size_t *resultlen,
unsigned long s2k_count);
int agent_unprotect (const unsigned char *protectedkey, const char *passphrase, int agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
gnupg_isotime_t protected_at, gnupg_isotime_t protected_at,
unsigned char **result, size_t *resultlen); unsigned char **result, size_t *resultlen);

View File

@ -2341,7 +2341,7 @@ ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n); gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
/* FIXME: guarantee? */ /* FIXME: guarantee? */
err = agent_protect (buffer_new, passphrase, buffer, buffer_n); err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
out: out:

View File

@ -1866,7 +1866,8 @@ cmd_import_key (assuan_context_t ctx, char *line)
if (passphrase) if (passphrase)
{ {
err = agent_protect (key, passphrase, &finalkey, &finalkeylen); err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
ctrl->s2k_count);
if (!err) if (!err)
err = agent_write_private_key (grip, finalkey, finalkeylen, 0); err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
} }
@ -2474,6 +2475,14 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
{ {
ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0; ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
} }
else if (!strcmp (key, "s2k-count"))
{
ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
if (ctrl->s2k_count && ctrl->s2k_count < 65536) {
ctrl->s2k_count = 0;
err = gpg_error (GPG_ERR_INV_VALUE);
}
}
else else
err = gpg_error (GPG_ERR_UNKNOWN_OPTION); err = gpg_error (GPG_ERR_UNKNOWN_OPTION);

View File

@ -31,7 +31,8 @@
#include "sysutils.h" #include "sysutils.h"
static int static int
store_key (gcry_sexp_t private, const char *passphrase, int force) store_key (gcry_sexp_t private, const char *passphrase, int force,
unsigned long s2k_count)
{ {
int rc; int rc;
unsigned char *buf; unsigned char *buf;
@ -56,7 +57,7 @@ store_key (gcry_sexp_t private, const char *passphrase, int force)
{ {
unsigned char *p; unsigned char *p;
rc = agent_protect (buf, passphrase, &p, &len); rc = agent_protect (buf, passphrase, &p, &len, s2k_count);
if (rc) if (rc)
{ {
xfree (buf); xfree (buf);
@ -420,7 +421,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
/* store the secret key */ /* store the secret key */
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_debug ("storing private key\n"); log_debug ("storing private key\n");
rc = store_key (s_private, passphrase, 0); rc = store_key (s_private, passphrase, 0, ctrl->s2k_count);
if (!rc) if (!rc)
{ {
if (!cache_nonce) if (!cache_nonce)
@ -492,7 +493,8 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
if (passphrase_addr && *passphrase_addr) if (passphrase_addr && *passphrase_addr)
{ {
/* Take an empty string as request not to protect the key. */ /* Take an empty string as request not to protect the key. */
err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1); err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1,
ctrl->s2k_count);
} }
else else
{ {
@ -507,7 +509,7 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
_("Please enter the new passphrase"), _("Please enter the new passphrase"),
&pass); &pass);
if (!err) if (!err)
err = store_key (s_skey, pass, 1); err = store_key (s_skey, pass, 1, ctrl->s2k_count);
if (!err && passphrase_addr) if (!err && passphrase_addr)
*passphrase_addr = pass; *passphrase_addr = pass;
else else

View File

@ -333,7 +333,7 @@ read_and_protect (const char *fname)
return; return;
pw = get_passphrase (1); pw = get_passphrase (1);
rc = agent_protect (key, pw, &result, &resultlen); rc = agent_protect (key, pw, &result, &resultlen, 0);
release_passphrase (pw); release_passphrase (pw);
xfree (key); xfree (key);
if (rc) if (rc)

View File

@ -309,7 +309,8 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
static int static int
do_encryption (const unsigned char *protbegin, size_t protlen, do_encryption (const unsigned char *protbegin, size_t protlen,
const char *passphrase, const unsigned char *sha1hash, const char *passphrase, const unsigned char *sha1hash,
unsigned char **result, size_t *resultlen) unsigned char **result, size_t *resultlen,
unsigned long s2k_count)
{ {
gcry_cipher_hd_t hd; gcry_cipher_hd_t hd;
const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"; const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc";
@ -368,7 +369,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
{ {
rc = hash_passphrase (passphrase, GCRY_MD_SHA1, rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
3, iv+2*blklen, 3, iv+2*blklen,
get_standard_s2k_count (), key, keylen); s2k_count ? s2k_count : get_standard_s2k_count(),
key, keylen);
if (!rc) if (!rc)
rc = gcry_cipher_setkey (hd, key, keylen); rc = gcry_cipher_setkey (hd, key, keylen);
xfree (key); xfree (key);
@ -411,7 +413,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
{ {
char countbuf[35]; char countbuf[35];
snprintf (countbuf, sizeof countbuf, "%lu", get_standard_s2k_count ()); snprintf (countbuf, sizeof countbuf, "%lu",
s2k_count ? s2k_count : get_standard_s2k_count ());
p = xtryasprintf p = xtryasprintf
("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)", ("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)",
(int)strlen (modestr), modestr, (int)strlen (modestr), modestr,
@ -443,7 +446,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
a valid S-Exp here. */ a valid S-Exp here. */
int int
agent_protect (const unsigned char *plainkey, const char *passphrase, agent_protect (const unsigned char *plainkey, const char *passphrase,
unsigned char **result, size_t *resultlen) unsigned char **result, size_t *resultlen,
unsigned long s2k_count)
{ {
int rc; int rc;
const unsigned char *s; const unsigned char *s;
@ -544,7 +548,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
rc = do_encryption (prot_begin, prot_end - prot_begin + 1, rc = do_encryption (prot_begin, prot_end - prot_begin + 1,
passphrase, hashvalue, passphrase, hashvalue,
&protected, &protectedlen); &protected, &protectedlen, s2k_count);
if (rc) if (rc)
return rc; return rc;

View File

@ -174,7 +174,7 @@ test_agent_protect (void)
{ {
ret = agent_protect ((const unsigned char*)specs[i].key, ret = agent_protect ((const unsigned char*)specs[i].key,
specs[i].passphrase, specs[i].passphrase,
&specs[i].result, &specs[i].resultlen); &specs[i].result, &specs[i].resultlen, 0);
if (gpg_err_code (ret) != specs[i].ret_expected) if (gpg_err_code (ret) != specs[i].ret_expected)
{ {
printf ("agent_protect() returned `%i/%s'; expected `%i/%s'\n", printf ("agent_protect() returned `%i/%s'; expected `%i/%s'\n",