gpg: Add new compliance mode "de-vs".
authorWerner Koch <wk@gnupg.org>
Tue, 15 Nov 2016 16:50:03 +0000 (17:50 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 15 Nov 2016 16:50:03 +0000 (17:50 +0100)
* g10/options.h (CO_DE_VS): New.
(GNUPG): Also allow CO_DE_VS.
* g10/gpg.c (oDE_VS): New.
(parse_compliance_option): Add "de-vs".
(set_compliance_option): Set "de-vs".
* g10/misc.c (compliance_option_string): Return a description string.
(compliance_failure): Ditto.
* g10/keygen.c (ask_algo): Take care of CO_DE_VS.
(get_keysize_range): Ditto.
(ask_curve): Add new field to CURVES and trun flags into bit flags.
Allow only Brainpool curves in CO_DE_VS mode.
--

As of now this compliance mode only restricts the set of algorithms
and curves which can be created.

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/gpg.c
g10/keygen.c
g10/misc.c
g10/options.h

index b5fe490..495356c 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -233,6 +233,7 @@ enum cmd_and_opt_values
     oPGP6,
     oPGP7,
     oPGP8,
+    oDE_VS,
     oRFC2440Text,
     oNoRFC2440Text,
     oCipherAlgo,
@@ -2042,7 +2043,8 @@ parse_compliance_option (const char *string)
     { "rfc2440",    oRFC2440 },
     { "pgp6",       oPGP6 },
     { "pgp7",       oPGP7 },
-    { "pgp8",       oPGP8 }
+    { "pgp8",       oPGP8 },
+    { "de-vs",      oDE_VS }
   };
   int i;
 
@@ -2118,6 +2120,13 @@ set_compliance_option (enum cmd_and_opt_values option)
     case oPGP7:  opt.compliance = CO_PGP7;  break;
     case oPGP8:  opt.compliance = CO_PGP8;  break;
     case oGnuPG: opt.compliance = CO_GNUPG; break;
+
+    case oDE_VS:
+      set_compliance_option (oOpenPGP);
+      opt.compliance = CO_DE_VS;
+      /* Fixme: Change other options.  */
+      break;
+
     default:
       BUG ();
     }
index b424c98..d249556 100644 (file)
@@ -1885,24 +1885,27 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
     tty_printf (_("   (%d) RSA and RSA (default)\n"), 1 );
 #endif
 
-  if (!addmode)
+  if (!addmode && opt.compliance != CO_DE_VS)
     tty_printf (_("   (%d) DSA and Elgamal\n"), 2 );
 
-  tty_printf (_("   (%d) DSA (sign only)\n"), 3 );
+  if (opt.compliance != CO_DE_VS)
+    tty_printf (_("   (%d) DSA (sign only)\n"), 3 );
 #if GPG_USE_RSA
   tty_printf (_("   (%d) RSA (sign only)\n"), 4 );
 #endif
 
   if (addmode)
     {
-      tty_printf (_("   (%d) Elgamal (encrypt only)\n"), 5 );
+      if (opt.compliance != CO_DE_VS)
+        tty_printf (_("   (%d) Elgamal (encrypt only)\n"), 5 );
 #if GPG_USE_RSA
       tty_printf (_("   (%d) RSA (encrypt only)\n"), 6 );
 #endif
     }
   if (opt.expert)
     {
-      tty_printf (_("   (%d) DSA (set your own capabilities)\n"), 7 );
+      if (opt.compliance != CO_DE_VS)
+        tty_printf (_("   (%d) DSA (set your own capabilities)\n"), 7 );
 #if GPG_USE_RSA
       tty_printf (_("   (%d) RSA (set your own capabilities)\n"), 8 );
 #endif
@@ -1930,7 +1933,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
       answer = cpr_get ("keygen.algo", _("Your selection? "));
       cpr_kill_prompt ();
       algo = *answer? atoi (answer) : 1;
-      if ((algo == 1 || !strcmp (answer, "rsa+rsa")) && !addmode)
+
+      if (opt.compliance == CO_DE_VS
+          && (algo == 2 || algo == 3 || algo == 5 || algo == 7))
+        {
+          tty_printf (_("Invalid selection.\n"));
+        }
+      else if ((algo == 1 || !strcmp (answer, "rsa+rsa")) && !addmode)
         {
           algo = PUBKEY_ALGO_RSA;
           *r_subkey_algo = PUBKEY_ALGO_RSA;
@@ -2051,7 +2060,7 @@ static void
 get_keysize_range (int algo,
                    unsigned int *min, unsigned int *def, unsigned int *max)
 {
-  *min = 1024;
+  *min = opt.compliance == CO_DE_VS ? 2048: 1024;
   *def = DEFAULT_STD_KEYSIZE;
   *max = 4096;
 
@@ -2197,26 +2206,27 @@ ask_curve (int *algo, int *subkey_algo)
      numbers in the menu regardless on how Gpg was configured.  */
   struct {
     const char *name;
-    int available;   /* Available in Libycrypt (runtime checked) */
-    int expert_only;
     const char* eddsa_curve; /* Corresponding EdDSA curve.  */
     const char *pretty_name;
-    int supported;   /* Supported by gpg.  */
+    unsigned int supported : 1;   /* Supported by gpg.     */
+    unsigned int de_vs : 1;       /* Allowed in CO_DE_VS.  */
+    unsigned int expert_only : 1; /* Only with --expert    */
+    unsigned int available : 1;   /* Available in Libycrypt (runtime checked) */
   } curves[] = {
 #if GPG_USE_ECDSA || GPG_USE_ECDH
 # define MY_USE_ECDSADH 1
 #else
 # define MY_USE_ECDSADH 0
 #endif
-    { "Curve25519",      0, 0, "Ed25519", "Curve 25519", GPG_USE_EDDSA  },
-    { "Curve448",        0, 1, "Ed448",   "Curve 448",   0/*reserved*/  },
-    { "NIST P-256",      0, 1, NULL, NULL,               MY_USE_ECDSADH },
-    { "NIST P-384",      0, 0, NULL, NULL,               MY_USE_ECDSADH },
-    { "NIST P-521",      0, 1, NULL, NULL,               MY_USE_ECDSADH },
-    { "brainpoolP256r1", 0, 1, NULL, "Brainpool P-256",  MY_USE_ECDSADH },
-    { "brainpoolP384r1", 0, 1, NULL, "Brainpool P-384",  MY_USE_ECDSADH },
-    { "brainpoolP512r1", 0, 1, NULL, "Brainpool P-512",  MY_USE_ECDSADH },
-    { "secp256k1",       0, 1, NULL, NULL,               MY_USE_ECDSADH },
+    { "Curve25519",      "Ed25519", "Curve 25519", !!GPG_USE_EDDSA, 0, 0, 0 },
+    { "Curve448",        "Ed448",   "Curve 448",   0/*reserved*/  , 0, 1, 0 },
+    { "NIST P-256",      NULL, NULL,               MY_USE_ECDSADH,  0, 1, 0 },
+    { "NIST P-384",      NULL, NULL,               MY_USE_ECDSADH,  0, 0, 0 },
+    { "NIST P-521",      NULL, NULL,               MY_USE_ECDSADH,  0, 1, 0 },
+    { "brainpoolP256r1", NULL, "Brainpool P-256",  MY_USE_ECDSADH,  1, 1, 0 },
+    { "brainpoolP384r1", NULL, "Brainpool P-384",  MY_USE_ECDSADH,  1, 1, 0 },
+    { "brainpoolP512r1", NULL, "Brainpool P-512",  MY_USE_ECDSADH,  1, 1, 0 },
+    { "secp256k1",       NULL, NULL,               MY_USE_ECDSADH,  0, 1, 0 },
   };
 #undef MY_USE_ECDSADH
   int idx;
@@ -2234,7 +2244,13 @@ ask_curve (int *algo, int *subkey_algo)
       curves[idx].available = 0;
       if (!curves[idx].supported)
         continue;
-      if (!opt.expert && curves[idx].expert_only)
+
+      if (opt.compliance==CO_DE_VS)
+        {
+          if (!curves[idx].de_vs)
+            continue; /* Not allowed.  */
+        }
+      else if (!opt.expert && curves[idx].expert_only)
         continue;
 
       /* We need to switch from the ECDH name of the curve to the
index 4f9ece3..4b9ad99 100644 (file)
@@ -1252,6 +1252,7 @@ compliance_option_string(void)
     case CO_PGP6:    return "--pgp6";
     case CO_PGP7:    return "--pgp7";
     case CO_PGP8:    return "--pgp8";
+    case CO_DE_VS:   return "--compliance=de-vs";
     }
 
   return ver;
@@ -1287,6 +1288,10 @@ compliance_failure(void)
     case CO_PGP8:
       ver="PGP 8.x";
       break;
+
+    case CO_DE_VS:
+      ver="DE-VS applications";
+      break;
     }
 
   log_info(_("this message may not be usable by %s\n"),ver);
index 19b855a..8ed2cdb 100644 (file)
@@ -140,7 +140,7 @@ struct
   enum
     {
       CO_GNUPG, CO_RFC4880, CO_RFC2440,
-      CO_PGP6, CO_PGP7, CO_PGP8
+      CO_PGP6, CO_PGP7, CO_PGP8, CO_DE_VS
     } compliance;
   enum
     {
@@ -327,7 +327,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
 
 
 /* Compatibility flags.  */
-#define GNUPG   (opt.compliance==CO_GNUPG)
+#define GNUPG   (opt.compliance==CO_GNUPG || opt.compliance==CO_DE_VS)
 #define RFC2440 (opt.compliance==CO_RFC2440)
 #define RFC4880 (opt.compliance==CO_RFC4880)
 #define PGP6    (opt.compliance==CO_PGP6)