[git] GnuPG - branch, master, updated. gnupg-2.1.21-30-gbe8ca88

by Justus Winter cvs at cvs.gnupg.org
Thu Jun 1 14:10:13 CEST 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  be8ca8852629786266db4d3d69b2c2fb03bd6365 (commit)
       via  3b70f62423041e614332b90d782576ee6868a030 (commit)
       via  8a012280e0f0a462c094d106355aa436fceb1b76 (commit)
      from  02af509dfc2b893720aa0c7b380fd7736b2bafd0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit be8ca8852629786266db4d3d69b2c2fb03bd6365
Author: Justus Winter <justus at g10code.com>
Date:   Tue May 30 14:30:24 2017 +0200

    gpg: Report compliance with CO_DE_VS.
    
    * common/compliance.c (gnupg_pk_is_compliant): Add DSA with certain
    parameters.
    (gnupg_cipher_is_compliant): New function.
    (gnupg_digest_is_compliant): Likewise.
    * common/compliance.h (gnupg_cipher_is_compliant): New prototype.
    (gnupg_digest_is_compliant): Likewise.
    * common/status.h (STATUS_DECRYPTION_COMPLIANCE_MODE): New status.
    (STATUS_VERIFICATION_COMPLIANCE_MODE): Likewise.
    * doc/DETAILS: Document the new status lines.
    * g10/mainproc.c (proc_encrypted): Compute compliance with CO_DE_VS
    and report that using the new status line.
    (check_sig_and_print): Likewise.
    * sm/decrypt.c (gpgsm_decrypt): Likewise.
    * sm/verify.c (gpgsm_verify): Likewise.
    --
    
    When decrypting data and verifying signatures, report whether the
    operations are in compliance with the criteria for data classified as
    VS-NfD.  This information will be picked up by the frontend and
    presented to the user.
    
    GnuPG-bug-id: 3059
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/common/compliance.c b/common/compliance.c
index c0b6984..80134d6 100644
--- a/common/compliance.c
+++ b/common/compliance.c
@@ -45,8 +45,8 @@ int
 gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
 		       gcry_mpi_t key[], unsigned int keylength, const char *curvename)
 {
-  enum { is_rsa, is_pgp5, is_elg_sign, is_ecc } algotype;
-  int result;
+  enum { is_rsa, is_dsa, is_pgp5, is_elg_sign, is_ecc } algotype;
+  int result = 0;
 
   switch (algo)
     {
@@ -56,8 +56,11 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
       algotype = is_rsa;
       break;
 
-    case PUBKEY_ALGO_ELGAMAL_E:
     case PUBKEY_ALGO_DSA:
+      algotype = is_dsa;
+      break;
+
+    case PUBKEY_ALGO_ELGAMAL_E:
       algotype = is_pgp5;
       break;
 
@@ -91,6 +94,16 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
                     || keylength == 4096);
           break;
 
+	case is_dsa:
+	  if (key)
+	    {
+	      size_t L = gcry_mpi_get_nbits (key[0] /* p */);
+	      size_t N = gcry_mpi_get_nbits (key[1] /* q */);
+	      result = (L == 256
+			&& (N == 2048 || N == 3072));
+	    }
+	  break;
+
         case is_ecc:
           if (!curvename && key)
             {
@@ -126,6 +139,59 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
 }
 
 
+/* Return true if CIPHER is compliant to the give COMPLIANCE mode.  */
+int
+gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance, cipher_algo_t cipher)
+{
+  switch (compliance)
+    {
+    case CO_DE_VS:
+      switch (cipher)
+	{
+	case CIPHER_ALGO_AES:
+	case CIPHER_ALGO_AES192:
+	case CIPHER_ALGO_AES256:
+	case CIPHER_ALGO_3DES:
+	  return 1;
+	default:
+	  return 0;
+	}
+      log_assert (!"reached");
+
+    default:
+      return 0;
+    }
+
+  log_assert (!"reached");
+}
+
+
+/* Return true if DIGEST is compliant to the give COMPLIANCE mode.  */
+int
+gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance, digest_algo_t digest)
+{
+  switch (compliance)
+    {
+    case CO_DE_VS:
+      switch (digest)
+	{
+	case DIGEST_ALGO_SHA256:
+	case DIGEST_ALGO_SHA384:
+	case DIGEST_ALGO_SHA512:
+	  return 1;
+	default:
+	  return 0;
+	}
+      log_assert (!"reached");
+
+    default:
+      return 0;
+    }
+
+  log_assert (!"reached");
+}
+
+
 const char *
 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
 {
diff --git a/common/compliance.h b/common/compliance.h
index 123bd1b..4f78ad4 100644
--- a/common/compliance.h
+++ b/common/compliance.h
@@ -42,6 +42,10 @@ enum gnupg_compliance_mode
 int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
                            gcry_mpi_t key[], unsigned int keylength,
                            const char *curvename);
+int gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
+                               cipher_algo_t cipher);
+int gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
+                               digest_algo_t digest);
 const char *gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance);
 
 #endif /*GNUPG_COMMON_COMPLIANCE_H*/
diff --git a/common/status.h b/common/status.h
index 8831a0f..0250a65 100644
--- a/common/status.h
+++ b/common/status.h
@@ -141,6 +141,9 @@ enum
     STATUS_TOFU_STATS_SHORT,
     STATUS_TOFU_STATS_LONG,
 
+    STATUS_DECRYPTION_COMPLIANCE_MODE,
+    STATUS_VERIFICATION_COMPLIANCE_MODE,
+
     STATUS_TRUNCATED,
     STATUS_MOUNTPOINT,
     STATUS_BLOCKDEV,
diff --git a/doc/DETAILS b/doc/DETAILS
index 1624315..01b5cf9 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -638,6 +638,17 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     This indicates that a signature subpacket was seen.  The format is
     the same as the "spk" record above.
 
+*** DECRYPTION_COMPLIANCE_MODE <flags>
+    Indicates that the current decryption operation is in compliance
+    with the given set of modes.  "flags" is a space separated list of
+    numerical flags, see "Field 18 - Compliance flags" above.
+
+*** VERIFICATION_COMPLIANCE_MODE <flags>
+    Indicates that the current signature verification operation is in
+    compliance with the given set of modes.  "flags" is a space
+    separated list of numerical flags, see "Field 18 - Compliance
+    flags" above.
+
 ** Key related
 *** INV_RECP, INV_SGNR
     The two similar status codes:
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 9500081..21ea6ca 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -39,6 +39,7 @@
 #include "photoid.h"
 #include "../common/mbox-util.h"
 #include "call-dirmngr.h"
+#include "../common/compliance.h"
 
 /* Put an upper limit on nested packets.  The 32 is an arbitrary
    value, a much lower should actually be sufficient.  */
@@ -599,6 +600,44 @@ proc_encrypted (CTX c, PACKET *pkt)
   else if (!c->dek)
     result = GPG_ERR_NO_SECKEY;
 
+  /* Compute compliance with CO_DE_VS.  */
+  if (!result && is_status_enabled ()
+      /* Symmetric encryption voids compliance.  */
+      && c->symkeys == 0
+      /* Overriding session key voids compliance.  */
+      && opt.override_session_key == NULL
+      /* Check symmetric cipher.  */
+      && gnupg_cipher_is_compliant (CO_DE_VS, c->dek->algo))
+    {
+      struct kidlist_item *i;
+      int compliant = 1;
+      PKT_public_key *pk = xmalloc (sizeof *pk);
+
+      log_assert (c->pkenc_list || !"where else did the session key come from!?");
+
+      /* Now check that every key used to encrypt the session key is
+       * compliant.  */
+      for (i = c->pkenc_list; i && compliant; i = i->next)
+        {
+          memset (pk, 0, sizeof *pk);
+          pk->pubkey_algo = i->pubkey_algo;
+          if (get_pubkey (c->ctrl, pk, i->kid) != 0
+              || ! gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+                                          nbits_from_pk (pk), NULL))
+            compliant = 0;
+          release_public_key_parts (pk);
+        }
+
+      xfree (pk);
+
+      if (compliant)
+        write_status_strings (STATUS_DECRYPTION_COMPLIANCE_MODE,
+                              gnupg_status_compliance_flag (CO_DE_VS),
+                              NULL);
+
+    }
+
+
   if (!result)
     result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek );
 
@@ -2196,6 +2235,15 @@ check_sig_and_print (CTX c, kbnode_t node)
             }
         }
 
+      /* Compute compliance with CO_DE_VS.  */
+      if (pk && is_status_enabled ()
+          && gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+                                    nbits_from_pk (pk), NULL)
+          && gnupg_digest_is_compliant (CO_DE_VS, sig->digest_algo))
+        write_status_strings (STATUS_VERIFICATION_COMPLIANCE_MODE,
+                              gnupg_status_compliance_flag (CO_DE_VS),
+                              NULL);
+
       free_public_key (pk);
       pk = NULL;
       release_kbnode( keyblock );
diff --git a/sm/decrypt.c b/sm/decrypt.c
index f8b0199..aa621dd 100644
--- a/sm/decrypt.c
+++ b/sm/decrypt.c
@@ -32,6 +32,7 @@
 
 #include "keydb.h"
 #include "../common/i18n.h"
+#include "../common/compliance.h"
 
 struct decrypt_filter_parm_s
 {
@@ -325,6 +326,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
           int algo, mode;
           const char *algoid;
           int any_key = 0;
+          int is_de_vs;	/* Computed compliance with CO_DE_VS.  */
 
           audit_log (ctrl->audit, AUDIT_GOT_DATA);
 
@@ -356,6 +358,10 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
               goto leave;
             }
 
+          /* For CMS, CO_DE_VS demands CBC mode.  */
+          is_de_vs = (mode == GCRY_CIPHER_MODE_CBC
+                      && gnupg_cipher_is_compliant (CO_DE_VS, algo));
+
           audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
           dfparm.algo = algo;
           dfparm.mode = mode;
@@ -460,7 +466,21 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
                   hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
                   desc = gpgsm_format_keydesc (cert);
 
+                  /* Check that all certs are compliant with CO_DE_VS.  */
+                  if (is_de_vs)
+                    {
+                      unsigned int nbits;
+                      int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
+
+                      is_de_vs = gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL,
+                                                        nbits, NULL);
+                    }
+
                 oops:
+                  if (rc)
+                    /* We cannot check compliance of certs that we
+                     * don't have.  */
+                    is_de_vs = 0;
                   xfree (issuer);
                   xfree (serial);
                   ksba_cert_release (cert);
@@ -489,6 +509,11 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
                       ksba_writer_set_filter (writer,
                                               decrypt_filter,
                                               &dfparm);
+
+                      if (is_de_vs)
+                        gpgsm_status (ctrl, STATUS_DECRYPTION_COMPLIANCE_MODE,
+                                      gnupg_status_compliance_flag (CO_DE_VS));
+
                     }
                   audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
                 }
diff --git a/sm/verify.c b/sm/verify.c
index 7bdc68b..e19c04e 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -33,6 +33,7 @@
 
 #include "keydb.h"
 #include "../common/i18n.h"
+#include "../common/compliance.h"
 
 static char *
 strtimestamp_r (ksba_isotime_t atime)
@@ -631,6 +632,16 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
                     (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
                     "0 chain": "0 shell");
 
+      /* Check compliance with CO_DE_VS.  */
+      {
+        unsigned int nbits;
+        int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
+
+        if (gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL)
+            && gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
+          gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE,
+                        gnupg_status_compliance_flag (CO_DE_VS));
+      }
 
     next_signer:
       rc = 0;

commit 3b70f62423041e614332b90d782576ee6868a030
Author: Justus Winter <justus at g10code.com>
Date:   Thu Jun 1 11:56:42 2017 +0200

    common: Improve checking for compliance with CO_DE_VS.
    
    * common/compliance.c (gnupg_pk_is_compliant): Only certain RSA key
    sizes are compliant.
    
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/common/compliance.c b/common/compliance.c
index 73c7ad7..c0b6984 100644
--- a/common/compliance.c
+++ b/common/compliance.c
@@ -86,7 +86,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
           break;
 
         case is_rsa:
-          result = (keylength >= 2048);
+          result = (keylength == 2048
+                    || keylength == 3072
+                    || keylength == 4096);
           break;
 
         case is_ecc:

commit 8a012280e0f0a462c094d106355aa436fceb1b76
Author: Justus Winter <justus at g10code.com>
Date:   Wed May 31 14:33:45 2017 +0200

    gpg,common: Move the compliance framework.
    
    * common/Makefile.am (common_sources): Add new files.
    * common/compliance.c: New file.  Move 'gnupg_pk_is_compliant' here,
    and tweak it to not rely on types private to gpg.
    * common/compliance.h: New file.  Move the compliance enum here.
    * g10/keylist.c (print_compliance_flags): Adapt callsite.
    * g10/main.h (gnupg_pk_is_compliant): Remove prototype.
    * g10/misc.c (gnupg_pk_is_compliant): Remove function.
    * g10/options.h (opt): Use the new compliance enum.
    * sm/keylist.c (print_compliance_flags): Use the common functions.
    
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/common/Makefile.am b/common/Makefile.am
index 83d82ac..fcbe7ea 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -93,7 +93,8 @@ common_sources = \
 	server-help.c server-help.h \
 	name-value.c name-value.h \
 	recsel.c recsel.h \
-	ksba-io-support.c ksba-io-support.h
+	ksba-io-support.c ksba-io-support.h \
+	compliance.c compliance.h
 
 
 if HAVE_W32_SYSTEM
diff --git a/common/compliance.c b/common/compliance.c
new file mode 100644
index 0000000..73c7ad7
--- /dev/null
+++ b/common/compliance.c
@@ -0,0 +1,144 @@
+/* compliance.c - Functions for compliance modi
+ * Copyright (C) 2017 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - the GNU General Public License as published by the Free
+ *     Software Foundation; either version 2 of the License, or (at
+ *     your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <gcrypt.h>
+
+#include "openpgpdefs.h"
+#include "logging.h"
+#include "util.h"
+#include "compliance.h"
+
+/* Return true if ALGO with a key of KEYLENGTH is compliant to the
+ * give COMPLIANCE mode.  If KEY is not NULL, various bits of
+ * information will be extracted from it.  If CURVENAME is not NULL, it
+ * is assumed to be the already computed.  ALGO may be either an
+ * OpenPGP-style pubkey_algo_t, or a gcrypt-style enum gcry_pk_algos,
+ * both are compatible from the point of view of this function.  */
+int
+gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
+		       gcry_mpi_t key[], unsigned int keylength, const char *curvename)
+{
+  enum { is_rsa, is_pgp5, is_elg_sign, is_ecc } algotype;
+  int result;
+
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:
+      algotype = is_rsa;
+      break;
+
+    case PUBKEY_ALGO_ELGAMAL_E:
+    case PUBKEY_ALGO_DSA:
+      algotype = is_pgp5;
+      break;
+
+    case PUBKEY_ALGO_ECDH:
+    case PUBKEY_ALGO_ECDSA:
+    case PUBKEY_ALGO_EDDSA:
+      algotype = is_ecc;
+      break;
+
+    case PUBKEY_ALGO_ELGAMAL:
+      algotype = is_elg_sign;
+      break;
+
+    default: /* Unknown.  */
+      return 0;
+    }
+
+  if (compliance == CO_DE_VS)
+    {
+      char *curve = NULL;
+
+      switch (algotype)
+        {
+        case is_pgp5:
+          result = 0;
+          break;
+
+        case is_rsa:
+          result = (keylength >= 2048);
+          break;
+
+        case is_ecc:
+          if (!curvename && key)
+            {
+              curve = openpgp_oid_to_str (key[0]);
+              curvename = openpgp_oid_to_curve (curve, 0);
+              if (!curvename)
+                curvename = curve;
+            }
+
+          result = (curvename
+                    && algo != PUBKEY_ALGO_EDDSA
+                    && (!strcmp (curvename, "brainpoolP256r1")
+                        || !strcmp (curvename, "brainpoolP384r1")
+                        || !strcmp (curvename, "brainpoolP512r1")));
+          break;
+
+        default:
+          result = 0;
+        }
+      xfree (curve);
+    }
+  else if (algotype == is_elg_sign)
+    {
+      /* An Elgamal signing key is only RFC-2440 compliant.  */
+      result = (compliance == CO_RFC2440);
+    }
+  else
+    {
+      result = 1; /* Assume compliance.  */
+    }
+
+  return result;
+}
+
+
+const char *
+gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
+{
+  switch (compliance)
+    {
+    case CO_GNUPG:
+      return "8";
+    case CO_RFC4880:
+    case CO_RFC2440:
+    case CO_PGP6:
+    case CO_PGP7:
+    case CO_PGP8:
+      log_assert (!"no status code assigned for this compliance mode");
+    case CO_DE_VS:
+      return "23";
+    }
+  log_assert (!"invalid compliance mode");
+}
diff --git a/common/compliance.h b/common/compliance.h
new file mode 100644
index 0000000..123bd1b
--- /dev/null
+++ b/common/compliance.h
@@ -0,0 +1,47 @@
+/* compliance.h - Definitions for compliance modi
+ * Copyright (C) 2017 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - the GNU General Public License as published by the Free
+ *     Software Foundation; either version 2 of the License, or (at
+ *     your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_COMPLIANCE_H
+#define GNUPG_COMMON_COMPLIANCE_H
+
+#include <gcrypt.h>
+#include "openpgpdefs.h"
+
+enum gnupg_compliance_mode
+  {
+    CO_GNUPG, CO_RFC4880, CO_RFC2440,
+    CO_PGP6, CO_PGP7, CO_PGP8, CO_DE_VS
+  };
+
+int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
+                           gcry_mpi_t key[], unsigned int keylength,
+                           const char *curvename);
+const char *gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance);
+
+#endif /*GNUPG_COMMON_COMPLIANCE_H*/
diff --git a/g10/keylist.c b/g10/keylist.c
index e2b8fef..4848bab 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -44,6 +44,7 @@
 #include "../common/mbox-util.h"
 #include "../common/zb32.h"
 #include "tofu.h"
+#include "../common/compliance.h"
 
 
 static void list_all (ctrl_t, int, int);
@@ -1180,14 +1181,19 @@ print_compliance_flags (PKT_public_key *pk,
 {
   int any = 0;
 
+  if (!keylength)
+    keylength = nbits_from_pk (pk);
+
   if (pk->version == 5)
     {
-      es_fputs ("8", es_stdout);
+      es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
       any++;
     }
-  if (gnupg_pk_is_compliant (CO_DE_VS, pk, keylength, curvename))
+  if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+			     keylength, curvename))
     {
-      es_fputs (any? " 23":"23", es_stdout);
+      es_fprintf (es_stdout, any ? " %s" : "%s",
+		  gnupg_status_compliance_flag (CO_DE_VS));
       any++;
     }
 }
diff --git a/g10/main.h b/g10/main.h
index 129d746..c406113 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -126,9 +126,6 @@ int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use);
 int openpgp_pk_algo_usage ( int algo );
 const char *openpgp_pk_algo_name (pubkey_algo_t algo);
 
-int gnupg_pk_is_compliant (int compliance, PKT_public_key *pk,
-                           unsigned int keylength, const char *curvename);
-
 enum gcry_md_algos map_md_openpgp_to_gcry (digest_algo_t algo);
 int openpgp_md_test_algo (digest_algo_t algo);
 const char *openpgp_md_algo_name (int algo);
diff --git a/g10/misc.c b/g10/misc.c
index bdd27cf..d485c94 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -707,94 +707,6 @@ openpgp_pk_algo_name (pubkey_algo_t algo)
 }
 
 
-/* Return true if PK is compliant to the give COMPLIANCE mode.  If
- * KEYLENGTH and CURVENAME are not 0/NULL the are assumed to be the
- * already computed values from PK.  */
-int
-gnupg_pk_is_compliant (int compliance, PKT_public_key *pk,
-                       unsigned int keylength, const char *curvename)
-{
-  enum { is_rsa, is_pgp5, is_elg_sign, is_ecc } algotype;
-  int result;
-
-  switch (pk->pubkey_algo)
-    {
-    case PUBKEY_ALGO_RSA:
-    case PUBKEY_ALGO_RSA_E:
-    case PUBKEY_ALGO_RSA_S:
-      algotype = is_rsa;
-      break;
-
-    case PUBKEY_ALGO_ELGAMAL_E:
-    case PUBKEY_ALGO_DSA:
-      algotype = is_pgp5;
-      break;
-
-    case PUBKEY_ALGO_ECDH:
-    case PUBKEY_ALGO_ECDSA:
-    case PUBKEY_ALGO_EDDSA:
-      algotype = is_ecc;
-      break;
-
-    case PUBKEY_ALGO_ELGAMAL:
-      algotype = is_elg_sign;
-      break;
-
-    default: /* Unknown.  */
-      return 0;
-    }
-
-  if (compliance == CO_DE_VS)
-    {
-      char *curve = NULL;
-
-      switch (algotype)
-        {
-        case is_pgp5:
-          result = 0;
-          break;
-
-        case is_rsa:
-          if (!keylength)
-            keylength = nbits_from_pk (pk);
-          result = (keylength >= 2048);
-          break;
-
-        case is_ecc:
-          if (!curvename)
-            {
-              curve = openpgp_oid_to_str (pk->pkey[0]);
-              curvename = openpgp_oid_to_curve (curve, 0);
-              if (!curvename)
-                curvename = curve;
-            }
-
-          result = (curvename
-                    && pk->pubkey_algo != PUBKEY_ALGO_EDDSA
-                    && (!strcmp (curvename, "brainpoolP256r1")
-                        || !strcmp (curvename, "brainpoolP384r1")
-                        || !strcmp (curvename, "brainpoolP512r1")));
-          break;
-
-        default:
-          result = 0;
-        }
-      xfree (curve);
-    }
-  else if (algotype == is_elg_sign)
-    {
-      /* An Elgamal signing key is only RFC-2440 compliant.  */
-      result = (compliance == CO_RFC2440);
-    }
-  else
-    {
-      result = 1; /* Assume compliance.  */
-    }
-
-  return result;
-}
-
-
 /* Explicit mapping of OpenPGP digest algos to Libgcrypt.  */
 /* FIXME: We do not yes use it everywhere.  */
 enum gcry_md_algos
diff --git a/g10/options.h b/g10/options.h
index c634f0f..8d1d93e 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -28,6 +28,7 @@
 #include "packet.h"
 #include "tofu.h"
 #include "../common/session-env.h"
+#include "../common/compliance.h"
 
 #ifndef EXTERN_UNLESS_MAIN_MODULE
 /* Norcraft can't cope with common symbols */
@@ -139,11 +140,7 @@ struct
     } trust_model;
   enum tofu_policy tofu_default_policy;
   int force_ownertrust;
-  enum
-    {
-      CO_GNUPG, CO_RFC4880, CO_RFC2440,
-      CO_PGP6, CO_PGP7, CO_PGP8, CO_DE_VS
-    } compliance;
+  enum gnupg_compliance_mode compliance;
   enum
     {
       KF_DEFAULT, KF_NONE, KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
diff --git a/sm/keylist.c b/sm/keylist.c
index 13de45d..abec049 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -36,6 +36,7 @@
 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
 #include "../common/i18n.h"
 #include "../common/tlv.h"
+#include "../common/compliance.h"
 
 struct list_external_parm_s
 {
@@ -351,8 +352,8 @@ email_kludge (const char *name)
 static void
 print_compliance_flags (int algo, unsigned int nbits, estream_t fp)
 {
-  if (algo == GCRY_PK_RSA && nbits >= 2048)
-    es_fputs ("23", fp);
+  if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
+    es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
 }
 
 

-----------------------------------------------------------------------

Summary of changes:
 common/Makefile.am                  |   3 +-
 common/compliance.c                 | 212 ++++++++++++++++++++++++++++++++++++
 common/{ccparray.h => compliance.h} |  40 +++----
 common/status.h                     |   3 +
 doc/DETAILS                         |  11 ++
 g10/keylist.c                       |  12 +-
 g10/main.h                          |   3 -
 g10/mainproc.c                      |  48 ++++++++
 g10/misc.c                          |  88 ---------------
 g10/options.h                       |   7 +-
 sm/decrypt.c                        |  25 +++++
 sm/keylist.c                        |   5 +-
 sm/verify.c                         |  11 ++
 13 files changed, 346 insertions(+), 122 deletions(-)
 create mode 100644 common/compliance.c
 copy common/{ccparray.h => compliance.h} (51%)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list