gpg,gpgsm: Emit status code ENCRYPTION_COMPLIANCE_MODE.
authorWerner Koch <wk@gnupg.org>
Tue, 20 Jun 2017 07:25:56 +0000 (09:25 +0200)
committerWerner Koch <wk@gnupg.org>
Fri, 23 Jun 2017 10:01:20 +0000 (12:01 +0200)
* common/status.h (STATUS_ENCRYPTION_COMPLIANCE_MODE): New.
* g10/encrypt.c (encrypt_crypt): Emit new status code.
* sm/encrypt.c (gpgsm_encrypt): Ditto.
--

This status code allows to report whether an encryption operation was
compliant to de-vs.

Signed-off-by: Werner Koch <wk@gnupg.org>
common/status.h
doc/DETAILS
g10/encrypt.c
sm/encrypt.c

index 0250a65..dc62f36 100644 (file)
@@ -141,6 +141,7 @@ enum
     STATUS_TOFU_STATS_SHORT,
     STATUS_TOFU_STATS_LONG,
 
+    STATUS_ENCRYPTION_COMPLIANCE_MODE,
     STATUS_DECRYPTION_COMPLIANCE_MODE,
     STATUS_VERIFICATION_COMPLIANCE_MODE,
 
index 01b5cf9..b915f06 100644 (file)
@@ -638,6 +638,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
     This indicates that a signature subpacket was seen.  The format is
     the same as the "spk" record above.
 
+*** ENCRYPTION_COMPLIANCE_MODE <flags>
+    Indicates that the current encryption operation was in compliance
+    with the given set of modes for all recipients.  "flags" is a
+    space separated list of numerical flags, see "Field 18 -
+    Compliance flags" 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
index 0d96659..4b21a61 100644 (file)
@@ -486,6 +486,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
   progress_filter_context_t *pfx;
   PK_LIST pk_list;
   int do_compress;
+  int compliant;
 
   if (filefd != -1 && filename)
     return gpg_error (GPG_ERR_INV_ARG);  /* Both given.  */
@@ -625,15 +626,19 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
       goto leave;
     }
 
+  compliant = gnupg_cipher_is_compliant (CO_DE_VS, cfx.dek->algo,
+                                         GCRY_CIPHER_MODE_CFB);
+
   {
     pk_list_t pkr;
+
     for (pkr = pk_list; pkr; pkr = pkr->next)
       {
         PKT_public_key *pk = pkr->pk;
+        unsigned int nbits = nbits_from_pk (pk);
 
         if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_ENCRYPTION,
-                                   pk->pubkey_algo,
-                                   pk->pkey, nbits_from_pk (pk), NULL))
+                                   pk->pubkey_algo, pk->pkey, nbits, NULL))
           {
             log_error (_("key %s not suitable for encryption"
                          " while in %s mode\n"),
@@ -642,9 +647,20 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
             rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
             goto leave;
           }
+
+        if (compliant
+            && !gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+                                       nbits, NULL))
+          compliant = 0;
       }
+
   }
 
+  if (compliant)
+    write_status_strings (STATUS_ENCRYPTION_COMPLIANCE_MODE,
+                          gnupg_status_compliance_flag (CO_DE_VS),
+                          NULL);
+
   cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
 
   /* Only do the is-file-already-compressed check if we are using a
@@ -965,7 +981,8 @@ write_pubkey_enc_from_list (ctrl_t ctrl, PK_LIST pk_list, DEK *dek, iobuf_t out)
   if (opt.throw_keyids && (PGP6 || PGP7 || PGP8))
     {
       log_info(_("you may not use %s while in %s mode\n"),
-               "--throw-keyids", gnupg_compliance_option_string (opt.compliance));
+               "--throw-keyids",
+               gnupg_compliance_option_string (opt.compliance));
       compliance_failure();
     }
 
index 2819a22..9e3216a 100644 (file)
@@ -313,6 +313,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
   estream_t data_fp = NULL;
   certlist_t cl;
   int count;
+  int compliant;
 
   memset (&encparm, 0, sizeof encparm);
 
@@ -456,15 +457,19 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
 
   audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
 
+  compliant = gnupg_cipher_is_compliant (CO_DE_VS, dek->algo,
+                                         GCRY_CIPHER_MODE_CBC);
+
   /* Gather certificates of recipients, encrypt the session key for
      each and store them in the CMS object */
   for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
     {
       unsigned char *encval;
+      unsigned int nbits;
+      int pk_algo;
 
       /* Check compliance.  */
-      unsigned int nbits;
-      int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
+      pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
       if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_ENCRYPTION, pk_algo,
                                  NULL, nbits, NULL))
         {
@@ -476,6 +481,12 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
           goto leave;
         }
 
+      /* Fixme: When adding ECC we need to provide the curvename and
+       * the key to gnupg_pk_is_compliant.  */
+      if (compliant
+          && !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL))
+        compliant = 0;
+
       rc = encrypt_dek (dek, cl->cert, &encval);
       if (rc)
         {
@@ -508,6 +519,10 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
         }
     }
 
+  if (compliant)
+    gpgsm_status (ctrl, STATUS_ENCRYPTION_COMPLIANCE_MODE,
+                  gnupg_status_compliance_flag (CO_DE_VS));
+
   /* Main control loop for encryption. */
   recpno = 0;
   do