aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2021-01-28 15:48:08 +0100
committerWerner Koch <wk@gnupg.org>2021-01-28 15:48:08 +0100
commit90c514868ff5fcf6d39490d4874ac3a31ba9e85f (patch)
tree8dc8d09146841ea634965c2d3a70234d93d33572
parent1e197c29ed95d021f5693cd3652b6acb07d928ea (diff)
downloadgnupg-90c514868ff5fcf6d39490d4874ac3a31ba9e85f.tar.gz
Include the library version in the compliance checks.
* common/compliance.c (gnupg_gcrypt_is_compliant): New. (gnupg_rng_is_compliant): Also check library version. * g10/mainproc.c (proc_encrypted): Use new function. (check_sig_and_print): Ditto. * sm/decrypt.c (gpgsm_decrypt): Ditto. * sm/encrypt.c (gpgsm_encrypt): Ditto. * sm/verify.c (gpgsm_verify): Ditto -- This will eventually allow us to declare Libgcrypt 1.9 to be de-vs compliant. GnuPG can use this information then for its own checks. As of now GnuPG tests the version of the used library but that is a bit cumbersome to maintain. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--common/compliance.c78
-rw-r--r--common/compliance.h1
-rw-r--r--g10/mainproc.c2
-rw-r--r--sm/decrypt.c2
-rw-r--r--sm/encrypt.c2
-rw-r--r--sm/verify.c1
6 files changed, 69 insertions, 17 deletions
diff --git a/common/compliance.c b/common/compliance.c
index 0c785799e..48eeb1fe7 100644
--- a/common/compliance.c
+++ b/common/compliance.c
@@ -496,23 +496,71 @@ gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
; /* Use cached result. */
else if (compliance == CO_DE_VS)
{
- /* In DE_VS mode under Windows we require that the JENT RNG
- * is active. */
+ /* We also check whether the library is at all compliant. */
+ result = gnupg_gcrypt_is_compliant (compliance);
+
+ /* In DE_VS mode under Windows we also require that the JENT RNG
+ * is active. Check it here. */
#ifdef HAVE_W32_SYSTEM
- char *buf;
- const char *fields[5];
-
- buf = gcry_get_config (0, "rng-type");
- if (buf
- && split_fields_colon (buf, fields, DIM (fields)) >= 5
- && atoi (fields[4]) > 0)
- result = 1;
+ if (result == 1)
+ {
+ char *buf;
+ const char *fields[5];
+
+ buf = gcry_get_config (0, "rng-type");
+ if (buf
+ && split_fields_colon (buf, fields, DIM (fields)) >= 5
+ && atoi (fields[4]) > 0)
+ ; /* Field 5 > 0 := Jent is active. */
+ else
+ result = 0; /* Force non-compliance. */
+ gcry_free (buf);
+ }
+#endif /*HAVE_W32_SYSTEM*/
+ }
+ else
+ result = 1;
+
+ return result;
+}
+
+
+/* Return true if the used Libgcrypt is compliant in COMPLIANCE
+ * mode. */
+int
+gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance)
+{
+ static int result = -1;
+
+ if (result != -1)
+ ; /* Use cached result. */
+ else if (compliance == CO_DE_VS)
+ {
+ int is19orlater = !!gcry_check_version ("1.9.0");
+
+ /* A compliant version of GnuPG requires Libgcrypt >= 1.8.1 and
+ * less than 1.9.0. Version 1.9.0 requires a re-evaluation and
+ * can thus not be used for de-vs. */
+ if (gcry_check_version ("1.8.1") && !is19orlater)
+ result = 1; /* Compliant version of Libgcrypt. */
+ else if (is19orlater)
+ {
+ /* Libgcrypt might be nice enough to tell us whether it is
+ * compliant. */
+ char *buf;
+ const char *fields[3];
+
+ buf = gcry_get_config (0, "compliance");
+ if (buf
+ && split_fields_colon (buf, fields, DIM (fields)) >= 2
+ && strstr (fields[1], "de-vs"))
+ result = 1; /* Compliant. */
+ else
+ result = 0; /* Non-compliant. */
+ gcry_free (buf);
+ }
else
- result = 0;
- gcry_free (buf);
-#else /*!HAVE_W32_SYSTEM*/
- result = 1; /* Not Windows - RNG is good. */
-#endif /*!HAVE_W32_SYSTEM*/
+ result = 0; /* Non-compliant version of Libgcrypt. */
}
else
result = 1;
diff --git a/common/compliance.h b/common/compliance.h
index 7c74da38a..2f7039206 100644
--- a/common/compliance.h
+++ b/common/compliance.h
@@ -73,6 +73,7 @@ int gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance,
int producer,
digest_algo_t digest);
int gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance);
+int gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance);
const char *gnupg_status_compliance_flag (enum gnupg_compliance_mode
compliance);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 08986a070..ca6c24323 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -688,6 +688,7 @@ proc_encrypted (CTX c, PACKET *pkt)
/* Overriding session key voids compliance. */
&& !opt.override_session_key
/* Check symmetric cipher. */
+ && gnupg_gcrypt_is_compliant (CO_DE_VS)
&& gnupg_cipher_is_compliant (CO_DE_VS, c->dek->algo,
GCRY_CIPHER_MODE_CFB))
{
@@ -2537,6 +2538,7 @@ check_sig_and_print (CTX c, kbnode_t node)
/* Compute compliance with CO_DE_VS. */
if (pk && is_status_enabled ()
+ && gnupg_gcrypt_is_compliant (CO_DE_VS)
&& gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0, pk->pkey,
nbits_from_pk (pk), NULL)
&& gnupg_digest_is_compliant (CO_DE_VS, sig->digest_algo))
diff --git a/sm/decrypt.c b/sm/decrypt.c
index 2d846335e..aa91b370d 100644
--- a/sm/decrypt.c
+++ b/sm/decrypt.c
@@ -925,7 +925,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
decrypt_filter,
&dfparm);
- if (is_de_vs)
+ if (is_de_vs && gnupg_gcrypt_is_compliant (CO_DE_VS))
gpgsm_status (ctrl, STATUS_DECRYPTION_COMPLIANCE_MODE,
gnupg_status_compliance_flag (CO_DE_VS));
diff --git a/sm/encrypt.c b/sm/encrypt.c
index 34a5e878b..fbd88b6cd 100644
--- a/sm/encrypt.c
+++ b/sm/encrypt.c
@@ -807,7 +807,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
}
}
- if (compliant)
+ if (compliant && gnupg_gcrypt_is_compliant (CO_DE_VS))
gpgsm_status (ctrl, STATUS_ENCRYPTION_COMPLIANCE_MODE,
gnupg_status_compliance_flag (CO_DE_VS));
diff --git a/sm/verify.c b/sm/verify.c
index 1575a1eb2..fe111c32a 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -516,6 +516,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
/* Check compliance with CO_DE_VS. */
if (gnupg_pk_is_compliant (CO_DE_VS, pkalgo, pkalgoflags,
NULL, nbits, NULL)
+ && gnupg_gcrypt_is_compliant (CO_DE_VS)
&& gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE,
gnupg_status_compliance_flag (CO_DE_VS));