sm: Do not expect X.509 keyids to be unique
[gnupg.git] / sm / gpgsm.c
index a2ec441..0feda90 100644 (file)
 #include "passphrase.h"
 #include "../common/shareddefs.h"
 #include "../kbx/keybox.h" /* malloc hooks */
-#include "i18n.h"
+#include "../common/i18n.h"
 #include "keydb.h"
-#include "sysutils.h"
-#include "gc-opt-flags.h"
-#include "asshelp.h"
+#include "../common/sysutils.h"
+#include "../common/gc-opt-flags.h"
+#include "../common/asshelp.h"
 #include "../common/init.h"
+#include "../common/compliance.h"
 
 
 #ifndef O_BINARY
@@ -231,7 +232,8 @@ static ARGPARSE_OPTS opts[] = {
               N_("pass a command to the dirmngr")),
   ARGPARSE_c (aCallProtectTool, "call-protect-tool",
               N_("invoke gpg-protect-tool")),
-  ARGPARSE_c (aPasswd, "passwd", N_("change a passphrase")),
+  ARGPARSE_c (aPasswd, "change-passphrase", N_("change a passphrase")),
+  ARGPARSE_c (aPasswd, "passwd", "@"),
   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
 
@@ -356,12 +358,6 @@ static ARGPARSE_OPTS opts[] = {
   "@\n(See the man page for a complete listing of all commands and options)\n"
   )),
 
-  ARGPARSE_group (303, N_("@\nExamples:\n\n"
-    " -se -r Bob [file]          sign and encrypt for user Bob\n"
-    " --clearsign [file]         make a clear text signature\n"
-    " --detach-sign [file]       make a detached signature\n"
-    " --list-keys [names]        show keys\n"
-    " --fingerprint [names]      show fingerprints\n"  )),
 
   /* Hidden options. */
   ARGPARSE_s_s (oCompliance, "compliance",   "@"),
@@ -951,6 +947,9 @@ main ( int argc, char **argv)
 
   dotlock_create (NULL, 0); /* Register lockfile cleanup.  */
 
+  /* Tell the compliance module who we are.  */
+  gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPGSM);
+
   opt.autostart = 1;
   opt.session_env = session_env_new ();
   if (!opt.session_env)
@@ -1448,7 +1447,19 @@ main ( int argc, char **argv)
         case oNoAutostart: opt.autostart = 0; break;
 
         case oCompliance:
-          /* Dummy option for now.  */
+          {
+            struct gnupg_compliance_option compliance_options[] =
+              {
+                { "de-vs", CO_DE_VS }
+              };
+            int compliance = gnupg_parse_compliance_option (pargs.r.ret_str,
+                                                            compliance_options,
+                                                            DIM (compliance_options),
+                                                            opt.quiet);
+            if (compliance < 0)
+              gpgsm_exit (1);
+            opt.compliance = compliance;
+          }
           break;
 
         default:
@@ -1603,6 +1614,44 @@ main ( int argc, char **argv)
         }
     }
 
+  /* Check our chosen algorithms against the list of allowed
+   * algorithms in the current compliance mode, and fail hard if it is
+   * not.  This is us being nice to the user informing her early that
+   * the chosen algorithms are not available.  We also check and
+   * enforce this right before the actual operation.  */
+  if (! gnupg_cipher_is_allowed (opt.compliance,
+                                 cmd == aEncr || cmd == aSignEncr,
+                                 gcry_cipher_map_name (opt.def_cipher_algoid),
+                                 GCRY_CIPHER_MODE_NONE)
+      && ! gnupg_cipher_is_allowed (opt.compliance,
+                                    cmd == aEncr || cmd == aSignEncr,
+                                    gcry_cipher_mode_from_oid
+                                    (opt.def_cipher_algoid),
+                                    GCRY_CIPHER_MODE_NONE))
+    log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+               opt.def_cipher_algoid,
+               gnupg_compliance_option_string (opt.compliance));
+
+  if (forced_digest_algo
+      && ! gnupg_digest_is_allowed (opt.compliance,
+                                     cmd == aSign
+                                     || cmd == aSignEncr
+                                     || cmd == aClearsign,
+                                     opt.forced_digest_algo))
+    log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+               forced_digest_algo,
+               gnupg_compliance_option_string (opt.compliance));
+
+  if (extra_digest_algo
+      && ! gnupg_digest_is_allowed (opt.compliance,
+                                     cmd == aSign
+                                     || cmd == aSignEncr
+                                     || cmd == aClearsign,
+                                     opt.extra_digest_algo))
+    log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+               forced_digest_algo,
+               gnupg_compliance_option_string (opt.compliance));
+
   if (log_get_errorcount(0))
     gpgsm_exit(2);
 
@@ -1718,6 +1767,7 @@ main ( int argc, char **argv)
        es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
        es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("enable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT,
@@ -1859,7 +1909,7 @@ main ( int argc, char **argv)
 
     case aListChain:
     case aDumpChain:
-       ctrl.with_chain = 1;
+       ctrl.with_chain = 1; /* fall through */
     case aListKeys:
     case aDumpKeys:
     case aListExternalKeys:
@@ -1995,14 +2045,14 @@ main ( int argc, char **argv)
 
     case aPasswd:
       if (argc != 1)
-        wrong_args ("--passwd <key-Id>");
+        wrong_args ("--change-passphrase <key-Id>");
       else
         {
           int rc;
           ksba_cert_t cert = NULL;
           char *grip = NULL;
 
-          rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert);
+          rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert, 0);
           if (rc)
             ;
           else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))