gpg: Improve usability of --quick-gen-key.
authorWerner Koch <wk@gnupg.org>
Tue, 13 Sep 2016 09:30:54 +0000 (11:30 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 13 Sep 2016 09:30:54 +0000 (11:30 +0200)
* g10/keygen.c (FUTURE_STD_): New constants.
(parse_expire_string): Handle special keywords.
(parse_algo_usage_expire): Allow "future-default".  Simplify call to
parse_expire_string.
(quick_generate_keypair): Always allow an expiration date.  Replace
former "test-default" by "future-default".
--

Using an expiration date is pretty common, thus we now allow the
creation of a standard key with expiration date.

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/gpg.texi
g10/keyedit.c
g10/keygen.c

index 5889c2f..8107100 100644 (file)
@@ -615,12 +615,14 @@ answer to a ``Continue?'' style confirmation prompt is required.  In
 case the user id already exists in the key ring a second prompt to
 force the creation of the key will show up.
 
-If any of the optional arguments are given, only the primary key is
-created and no prompts are shown.  For a description of these optional
-arguments see the command @code{--quick-addkey}.  The @code{usage}
-accepts also the value ``cert'' which can be used to create a
-certification only primary key; the default is to a create
-certification and signing key.
+If @code{algo} or @code{usage} are given, only the primary key is
+created and no prompts are shown.  To specify an expiration date but
+still create a primary and subkey use ``default'' or
+``future-default'' for @code{algo} and ``default'' for @code{usage}.
+For a description of these optional arguments see the command
+@code{--quick-addkey}.  The @code{usage} accepts also the value
+``cert'' which can be used to create a certification only primary key;
+the default is to a create certification and signing key.
 
 If this command is used with @option{--batch},
 @option{--pinentry-mode} has been set to @code{loopback}, and one of
@@ -637,13 +639,15 @@ Directly add a subkey to the key identified by the fingerprint
 added.  If any of the arguments are given a more specific subkey is
 added.
 
-@code{algo} may be any of the supported algorithms or curve names given
-in the format as used by key listings.  To use the default algorithm
-the string ``default'' or ``-'' can be used. Supported algorithms are
-``rsa'', ``dsa'', ``elg'', ``ed25519'', ``cv25519'', and other ECC
-curves.  For example the string ``rsa'' adds an RSA key with the
-default key length; a string ``rsa4096'' requests that the key length
-is 4096 bits.
+@code{algo} may be any of the supported algorithms or curve names
+given in the format as used by key listings.  To use the default
+algorithm the string ``default'' or ``-'' can be used.  Supported
+algorithms are ``rsa'', ``dsa'', ``elg'', ``ed25519'', ``cv25519'',
+and other ECC curves.  For example the string ``rsa'' adds an RSA key
+with the default key length; a string ``rsa4096'' requests that the
+key length is 4096 bits.  The string ``future-default'' is an alias
+for the algorithm which will likely be used as default algorithm in
+future versions of gpg.
 
 Depending on the given @code{algo} the subkey may either be an
 encryption subkey or a signing subkey.  If an algorithm is capable of
index 4c833f8..baee180 100644 (file)
@@ -3304,7 +3304,7 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
       goto leave;
     }
 
-  /* Create the subkey.  Noet that the called function already prints
+  /* Create the subkey.  Note that the called function already prints
    * an error message. */
   if (!generate_subkeypair (ctrl, keyblock, algostr, usagestr, expirestr))
     modified = 1;
index 2b3d328..e897075 100644 (file)
 #define DEFAULT_STD_SUBKEYUSE  PUBKEY_USAGE_ENC
 #define DEFAULT_STD_SUBCURVE   NULL
 
+#define FUTURE_STD_ALGO        PUBKEY_ALGO_EDDSA
+#define FUTURE_STD_KEYSIZE     0
+#define FUTURE_STD_KEYUSE      (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG)
+#define FUTURE_STD_CURVE       "Ed25519"
+#define FUTURE_STD_SUBALGO     PUBKEY_ALGO_ECDH
+#define FUTURE_STD_SUBKEYSIZE  0
+#define FUTURE_STD_SUBKEYUSE   PUBKEY_USAGE_ENC
+#define FUTURE_STD_SUBCURVE    "Curve25519"
+
 /* Flag bits used during key generation.  */
 #define KEYGEN_FLAG_NO_PROTECTION 1
 #define KEYGEN_FLAG_TRANSIENT_KEY 2
@@ -2330,7 +2339,8 @@ parse_expire_string( const char *string )
   u32 curtime = make_timestamp ();
   time_t tt;
 
-  if (!*string)
+  if (!string || !*string || !strcmp (string, "none")
+      || !strcmp (string, "never") || !strcmp (string, "-"))
     seconds = 0;
   else if (!strncmp (string, "seconds=", 8))
     seconds = atoi (string+8);
@@ -2347,7 +2357,7 @@ parse_expire_string( const char *string )
   return seconds;
 }
 
-/* Parsean Creation-Date string which is either "1986-04-26" or
+/* Parse a Creation-Date string which is either "1986-04-26" or
    "19860426T042640".  Returns 0 on error. */
 static u32
 parse_creation_string (const char *string)
@@ -3612,12 +3622,49 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
   }
 
 
-  if (!strcmp (algostr, "test-default"))
+  if ((!*algostr || !strcmp (algostr, "default")
+       || !strcmp (algostr, "future-default"))
+      && (!*usagestr || !strcmp (usagestr, "default")
+          || !strcmp (usagestr, "-")))
     {
-      para = quickgen_set_para (para, 0, PUBKEY_ALGO_EDDSA, 0, "Ed25519", 0);
-      para = quickgen_set_para (para, 1, PUBKEY_ALGO_ECDH,  0, "Curve25519", 0);
+      if (!strcmp (algostr, "future-default"))
+        {
+          para = quickgen_set_para (para, 0,
+                                    FUTURE_STD_ALGO, FUTURE_STD_KEYSIZE,
+                                    FUTURE_STD_CURVE, 0);
+          para = quickgen_set_para (para, 1,
+                                    FUTURE_STD_SUBALGO,  FUTURE_STD_SUBKEYSIZE,
+                                    FUTURE_STD_SUBCURVE, 0);
+        }
+      else
+        {
+          para = quickgen_set_para (para, 0,
+                                    DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
+                                    DEFAULT_STD_CURVE, 0);
+          para = quickgen_set_para (para, 1,
+                                    DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
+                                    DEFAULT_STD_SUBCURVE, 0);
+        }
+
+      if (*expirestr)
+        {
+          u32 expire;
+
+          expire = parse_expire_string (expirestr);
+          if (expire == (u32)-1 )
+            {
+              err = gpg_error (GPG_ERR_INV_VALUE);
+              log_error (_("Key generation failed: %s\n"), gpg_strerror (err));
+              goto leave;
+            }
+          r = xmalloc_clear (sizeof *r + 20);
+          r->key = pKEYEXPIRE;
+          r->u.expire = expire;
+          r->next = para;
+          para = r;
+        }
     }
-  else if (*algostr || *usagestr || *expirestr)
+  else
     {
       /* Extended unattended mode.  Creates only the primary key. */
       int algo;
@@ -3641,15 +3688,6 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid, const char *algostr,
       r->next = para;
       para = r;
     }
-  else
-    {
-      para = quickgen_set_para (para, 0,
-                                DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE,
-                                DEFAULT_STD_CURVE, 0);
-      para = quickgen_set_para (para, 1,
-                                DEFAULT_STD_SUBALGO, DEFAULT_STD_SUBKEYSIZE,
-                                DEFAULT_STD_SUBCURVE, 0);
-    }
 
   /* If the pinentry loopback mode is not and we have a static
      passphrase (i.e. set with --passphrase{,-fd,-file} while in batch
@@ -4416,9 +4454,15 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
   if (!algostr || !*algostr
       || !strcmp (algostr, "default") || !strcmp (algostr, "-"))
     {
-      algo = for_subkey? DEFAULT_STD_SUBALGO : DEFAULT_STD_ALGO;
-      use = for_subkey?  DEFAULT_STD_SUBKEYUSE : DEFAULT_STD_KEYUSE;
-      nbits = for_subkey?DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
+      algo  = for_subkey? DEFAULT_STD_SUBALGO    : DEFAULT_STD_ALGO;
+      use   = for_subkey? DEFAULT_STD_SUBKEYUSE  : DEFAULT_STD_KEYUSE;
+      nbits = for_subkey? DEFAULT_STD_SUBKEYSIZE : DEFAULT_STD_KEYSIZE;
+    }
+  else if (!strcmp (algostr, "future-default"))
+    {
+      algo  = for_subkey? FUTURE_STD_SUBALGO    : FUTURE_STD_ALGO;
+      use   = for_subkey? FUTURE_STD_SUBKEYUSE  : FUTURE_STD_KEYUSE;
+      nbits = for_subkey? FUTURE_STD_SUBKEYSIZE : FUTURE_STD_KEYSIZE;
     }
   else if (*algostr == '&' && strlen (algostr) == 41)
     {
@@ -4490,11 +4534,7 @@ parse_algo_usage_expire (ctrl_t ctrl, int for_subkey,
     return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
 
   /* Parse the expire string.  */
-  if (!expirestr || !*expirestr || !strcmp (expirestr, "none")
-      || !strcmp (expirestr, "never") || !strcmp (expirestr, "-"))
-    expire = 0;
-  else
-    expire = parse_expire_string (expirestr);
+  expire = parse_expire_string (expirestr);
   if (expire == (u32)-1 )
     return gpg_error (GPG_ERR_INV_VALUE);