aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/mainproc.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c
index af11877aa..0757fcd90 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -47,6 +47,16 @@
#define MAX_NESTING_DEPTH 32
+/* An object to build a list of symkey packet info. */
+struct symlist_item
+{
+ struct symlist_item *next;
+ int cipher_algo;
+ int cfb_mode;
+ int other_error;
+};
+
+
/*
* Object to hold the processing context.
*/
@@ -87,6 +97,7 @@ struct mainproc_context
int trustletter; /* Temporary usage in list_node. */
ulong symkeys; /* Number of symmetrically encrypted session keys. */
struct pubkey_enc_list *pkenc_list; /* List of encryption packets. */
+ struct symlist_item *symenc_list; /* List of sym. encryption packets. */
int seen_pkt_encrypted_aead; /* PKT_ENCRYPTED_AEAD packet seen. */
int seen_pkt_encrypted_mdc; /* PKT_ENCRYPTED_MDC packet seen. */
struct {
@@ -136,6 +147,13 @@ release_list( CTX c )
c->pkenc_list = tmp;
}
c->pkenc_list = NULL;
+ while (c->symenc_list)
+ {
+ struct symlist_item *tmp = c->symenc_list->next;
+ xfree (c->symenc_list);
+ c->symenc_list = tmp;
+ }
+ c->symenc_list = NULL;
c->list = NULL;
c->any.data = 0;
c->any.uncompress_failed = 0;
@@ -460,6 +478,20 @@ proc_symkey_enc (CTX c, PACKET *pkt)
}
leave:
+ /* Record infos from the packet. */
+ {
+ struct symlist_item *symitem;
+ symitem = xcalloc (1, sizeof *symitem);
+ if (enc)
+ {
+ symitem->cipher_algo = enc->cipher_algo;
+ symitem->cfb_mode = !enc->aead_algo;
+ }
+ else
+ symitem->other_error = 1;
+ symitem->next = c->symenc_list;
+ c->symenc_list = symitem;
+ }
c->symkeys++;
free_packet (pkt, NULL);
}
@@ -695,8 +727,6 @@ proc_encrypted (CTX c, PACKET *pkt)
/* Compute compliance with CO_DE_VS. */
if (!result && is_status_enabled ()
- /* Symmetric encryption and asymmetric encryption voids compliance. */
- && (c->symkeys != !!c->pkenc_list )
/* Overriding session key voids compliance. */
&& !opt.override_session_key
/* Check symmetric cipher. */
@@ -705,14 +735,26 @@ proc_encrypted (CTX c, PACKET *pkt)
GCRY_CIPHER_MODE_CFB))
{
struct pubkey_enc_list *i;
+ struct symlist_item *si;
int compliant = 1;
PKT_public_key *pk = xmalloc (sizeof *pk);
if ( !(c->pkenc_list || c->symkeys) )
log_debug ("%s: where else did the session key come from?\n", __func__);
- /* Now check that every key used to encrypt the session key is
- * compliant. */
+ /* Check that all seen symmetric key packets use compliant
+ * algos. This is so that no non-compliant encrypted session
+ * key can be sneaked in. */
+ for (si = c->symenc_list; si && compliant; si = si->next)
+ {
+ if (!si->cfb_mode
+ || !gnupg_cipher_is_compliant (CO_DE_VS, si->cipher_algo,
+ GCRY_CIPHER_MODE_CFB))
+ compliant = 0;
+ }
+
+ /* Check that every public key used to encrypt the session key
+ * is compliant. */
for (i = c->pkenc_list; i && compliant; i = i->next)
{
memset (pk, 0, sizeof *pk);
@@ -836,7 +878,7 @@ proc_encrypted (CTX c, PACKET *pkt)
/* If we concluded that the decryption was compliant, issue a
- * compliance status before the thed end of decryption status. */
+ * compliance status before the end of the decryption status. */
if (compliance_de_vs == (4|2|1))
{
write_status_strings (STATUS_DECRYPTION_COMPLIANCE_MODE,