diff --git a/common/status.h b/common/status.h index 0250a656f..dc62f3629 100644 --- a/common/status.h +++ b/common/status.h @@ -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, diff --git a/doc/DETAILS b/doc/DETAILS index 01b5cf9c3..b915f0658 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -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 + 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 Indicates that the current decryption operation is in compliance with the given set of modes. "flags" is a space separated list of diff --git a/g10/encrypt.c b/g10/encrypt.c index 0d96659eb..4b21a6178 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -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(); } diff --git a/sm/encrypt.c b/sm/encrypt.c index 2819a22b5..9e3216a79 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -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