Added gpg-agent OPTION "s2k-count".
authorBen Kibbey <bjk@luxsci.net>
Wed, 29 Jun 2011 00:35:13 +0000 (20:35 -0400)
committerWerner Koch <wk@gnupg.org>
Wed, 29 Jun 2011 11:17:25 +0000 (13:17 +0200)
When unset or 0, the calibrated count will be used.

agent/ChangeLog
agent/agent.h
agent/command-ssh.c
agent/command.c
agent/genkey.c
agent/protect-tool.c
agent/protect.c
agent/t-protect.c

index 156fbdb..3234aae 100644 (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>
 
        * cvt-openpgp.c (convert_to_openpgp): Change type of N to unsigned
index 9aaf264..dfc82ec 100644 (file)
@@ -181,6 +181,8 @@ struct server_control_s
                         PKSIGN command to the scdaemon.  */
   int in_passwd;     /* Hack to inhibit enforced passphrase change
                         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 char get_standard_s2k_count_rfc4880 (void);
 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,
                      gnupg_isotime_t protected_at,
                      unsigned char **result, size_t *resultlen);
index 8603a53..e3a0410 100644 (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);
   /* FIXME: guarantee?  */
 
-  err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
+  err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
 
  out:
 
index 62bf145..d1f6fb9 100644 (file)
@@ -1866,7 +1866,8 @@ cmd_import_key (assuan_context_t ctx, char *line)
 
   if (passphrase)
     {
-      err = agent_protect (key, passphrase, &finalkey, &finalkeylen);
+      err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
+             ctrl->s2k_count);
       if (!err)
         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;
     }
+  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
     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
 
index 79b99e6..e01a7bc 100644 (file)
@@ -31,7 +31,8 @@
 #include "sysutils.h"
 
 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;
   unsigned char *buf;
@@ -56,7 +57,7 @@ store_key (gcry_sexp_t private, const char *passphrase, int force)
     {
       unsigned char *p;
 
-      rc = agent_protect (buf, passphrase, &p, &len);
+      rc = agent_protect (buf, passphrase, &p, &len, s2k_count);
       if (rc)
         {
           xfree (buf);
@@ -420,7 +421,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
   /* store the secret key */
   if (DBG_CRYPTO)
     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 (!cache_nonce)
@@ -492,7 +493,8 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
   if (passphrase_addr && *passphrase_addr)
     {
       /* 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
     {
@@ -507,7 +509,7 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
                                       _("Please enter the new passphrase"),
                                       &pass);
       if (!err)
-        err = store_key (s_skey, pass, 1);
+        err = store_key (s_skey, pass, 1, ctrl->s2k_count);
       if (!err && passphrase_addr)
         *passphrase_addr = pass;
       else
index 512019b..a253143 100644 (file)
@@ -333,7 +333,7 @@ read_and_protect (const char *fname)
     return;
 
   pw = get_passphrase (1);
-  rc = agent_protect (key, pw, &result, &resultlen);
+  rc = agent_protect (key, pw, &result, &resultlen, 0);
   release_passphrase (pw);
   xfree (key);
   if (rc)
index 7df82de..64af4ed 100644 (file)
@@ -309,7 +309,8 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
 static int
 do_encryption (const unsigned char *protbegin, size_t protlen,
                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;
   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,
                                 3, iv+2*blklen,
-                                get_standard_s2k_count (), key, keylen);
+                               s2k_count ? s2k_count : get_standard_s2k_count(),
+                               key, keylen);
           if (!rc)
             rc = gcry_cipher_setkey (hd, key, keylen);
           xfree (key);
@@ -411,7 +413,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
   {
     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
       ("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)",
        (int)strlen (modestr), modestr,
@@ -443,7 +446,8 @@ do_encryption (const unsigned char *protbegin, size_t protlen,
    a valid S-Exp here. */
 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 rc;
   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,
                       passphrase,  hashvalue,
-                      &protected, &protectedlen);
+                      &protected, &protectedlen, s2k_count);
   if (rc)
     return rc;
 
index a14e5e1..4b6e0b4 100644 (file)
@@ -174,7 +174,7 @@ test_agent_protect (void)
     {
       ret = agent_protect ((const unsigned char*)specs[i].key,
                            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)
        {
          printf ("agent_protect() returned `%i/%s'; expected `%i/%s'\n",