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>
This commit is contained in:
Werner Koch 2021-01-28 15:48:08 +01:00
parent 1e197c29ed
commit 90c514868f
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 69 additions and 17 deletions

View File

@ -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. */
#ifdef HAVE_W32_SYSTEM
char *buf;
const char *fields[5];
/* We also check whether the library is at all compliant. */
result = gnupg_gcrypt_is_compliant (compliance);
buf = gcry_get_config (0, "rng-type");
if (buf
&& split_fields_colon (buf, fields, DIM (fields)) >= 5
&& atoi (fields[4]) > 0)
result = 1;
/* In DE_VS mode under Windows we also require that the JENT RNG
* is active. Check it here. */
#ifdef HAVE_W32_SYSTEM
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;

View File

@ -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);

View File

@ -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))

View File

@ -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));

View File

@ -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));

View File

@ -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));