agent: Avoid appending a '\0' byte to the response of READKEY
[gnupg.git] / sm / decrypt.c
index aa621dd..60ed14a 100644 (file)
@@ -358,9 +358,19 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
               goto leave;
             }
 
+          /* Check compliance.  */
+          if (! gnupg_cipher_is_allowed (opt.compliance, 0, algo, mode))
+            {
+              log_error (_("cipher algorithm '%s'"
+                           " may not be used in %s mode\n"),
+                         gcry_cipher_algo_name (algo),
+                         gnupg_compliance_option_string (opt.compliance));
+              rc = gpg_error (GPG_ERR_CIPHER_ALGO);
+              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));
+          is_de_vs = gnupg_cipher_is_compliant (CO_DE_VS, algo, mode);
 
           audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
           dfparm.algo = algo;
@@ -466,21 +476,42 @@ 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);
-                    }
+                  {
+                    unsigned int nbits;
+                    int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
+
+                    /* Check compliance.  */
+                    if (!gnupg_pk_is_allowed (opt.compliance,
+                                              PK_USE_DECRYPTION,
+                                              pk_algo, NULL, nbits, NULL))
+                      {
+                        char  kidstr[10+1];
+
+                        snprintf (kidstr, sizeof kidstr, "0x%08lX",
+                                  gpgsm_get_short_fingerprint (cert, NULL));
+                        log_info
+                          (_("key %s is not suitable for decryption"
+                             " in %s mode\n"),
+                           kidstr,
+                           gnupg_compliance_option_string (opt.compliance));
+                        rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
+                        goto oops;
+                      }
+
+                    /* Check that all certs are compliant with CO_DE_VS.  */
+                    is_de_vs =
+                      (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;
+                    {
+                      /* We cannot check compliance of certs that we
+                       * don't have.  */
+                      is_de_vs = 0;
+                    }
                   xfree (issuer);
                   xfree (serial);
                   ksba_cert_release (cert);