mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
common: Make the compliance check more robust.
* common/compliance.c (get_compliance_cache): New. (gnupg_rng_is_compliant): Use per mode cache. (gnupg_gcrypt_is_compliant): Ditto. -- This addresses the problem tha the check might be called with different compliance values and thus it should return the corresponding cached result. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
c727951a24
commit
1d1ec1146c
@ -40,6 +40,36 @@
|
|||||||
static int initialized;
|
static int initialized;
|
||||||
static int module;
|
static int module;
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the address of a compliance cache variable for COMPLIANCE.
|
||||||
|
* If no such variable exists NULL is returned. FOR_RNG returns the
|
||||||
|
* cache variable for the RNG compliance check. */
|
||||||
|
static int *
|
||||||
|
get_compliance_cache (enum gnupg_compliance_mode compliance, int for_rng)
|
||||||
|
{
|
||||||
|
static int r_gnupg = -1, s_gnupg = -1;
|
||||||
|
static int r_rfc4880 = -1, s_rfc4880 = -1;
|
||||||
|
static int r_rfc2440 = -1, s_rfc2440 = -1;
|
||||||
|
static int r_pgp7 = -1, s_pgp7 = -1;
|
||||||
|
static int r_pgp8 = -1, s_pgp8 = -1;
|
||||||
|
static int r_de_vs = -1, s_de_vs = -1;
|
||||||
|
|
||||||
|
int *ptr = NULL;
|
||||||
|
|
||||||
|
switch (compliance)
|
||||||
|
{
|
||||||
|
case CO_GNUPG: ptr = for_rng? &r_gnupg : &s_gnupg ; break;
|
||||||
|
case CO_RFC4880: ptr = for_rng? &r_rfc4880 : &s_rfc4880; break;
|
||||||
|
case CO_RFC2440: ptr = for_rng? &r_rfc2440 : &s_rfc2440; break;
|
||||||
|
case CO_PGP7: ptr = for_rng? &r_pgp7 : &s_pgp7 ; break;
|
||||||
|
case CO_PGP8: ptr = for_rng? &r_pgp8 : &s_pgp8 ; break;
|
||||||
|
case CO_DE_VS: ptr = for_rng? &r_de_vs : &s_de_vs ; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initializes the module. Must be called with the current
|
/* Initializes the module. Must be called with the current
|
||||||
* GNUPG_MODULE_NAME. Checks a few invariants, and tunes the policies
|
* GNUPG_MODULE_NAME. Checks a few invariants, and tunes the policies
|
||||||
* for the given module. */
|
* for the given module. */
|
||||||
@ -490,19 +520,22 @@ gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
|
|||||||
int
|
int
|
||||||
gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
|
gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
|
||||||
{
|
{
|
||||||
static int result = -1;
|
int *result;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (result != -1)
|
result = get_compliance_cache (compliance, 1);
|
||||||
; /* Use cached result. */
|
|
||||||
|
if (result && *result != -1)
|
||||||
|
res = *result; /* Use cached result. */
|
||||||
else if (compliance == CO_DE_VS)
|
else if (compliance == CO_DE_VS)
|
||||||
{
|
{
|
||||||
/* We also check whether the library is at all compliant. */
|
/* We also check whether the library is at all compliant. */
|
||||||
result = gnupg_gcrypt_is_compliant (compliance);
|
res = gnupg_gcrypt_is_compliant (compliance);
|
||||||
|
|
||||||
/* In DE_VS mode under Windows we also require that the JENT RNG
|
/* In DE_VS mode under Windows we also require that the JENT RNG
|
||||||
* is active. Check it here. */
|
* is active. Check it here. */
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
if (result == 1)
|
if (res == 1)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
const char *fields[5];
|
const char *fields[5];
|
||||||
@ -519,9 +552,12 @@ gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
|
|||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = 1;
|
res = 1;
|
||||||
|
|
||||||
return result;
|
if (result)
|
||||||
|
*result = res;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -530,10 +566,13 @@ gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
|
|||||||
int
|
int
|
||||||
gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance)
|
gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance)
|
||||||
{
|
{
|
||||||
static int result = -1;
|
int *result;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (result != -1)
|
result = get_compliance_cache (compliance, 0);
|
||||||
; /* Use cached result. */
|
|
||||||
|
if (result && *result != -1)
|
||||||
|
res = *result; /* Use cached result. */
|
||||||
else if (compliance == CO_DE_VS)
|
else if (compliance == CO_DE_VS)
|
||||||
{
|
{
|
||||||
int is19orlater = !!gcry_check_version ("1.9.0");
|
int is19orlater = !!gcry_check_version ("1.9.0");
|
||||||
@ -542,7 +581,7 @@ gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance)
|
|||||||
* less than 1.9.0. Version 1.9.0 requires a re-evaluation and
|
* less than 1.9.0. Version 1.9.0 requires a re-evaluation and
|
||||||
* can thus not be used for de-vs. */
|
* can thus not be used for de-vs. */
|
||||||
if (gcry_check_version ("1.8.1") && !is19orlater)
|
if (gcry_check_version ("1.8.1") && !is19orlater)
|
||||||
result = 1; /* Compliant version of Libgcrypt. */
|
res = 1; /* Compliant version of Libgcrypt. */
|
||||||
else if (is19orlater)
|
else if (is19orlater)
|
||||||
{
|
{
|
||||||
/* Libgcrypt might be nice enough to tell us whether it is
|
/* Libgcrypt might be nice enough to tell us whether it is
|
||||||
@ -554,18 +593,21 @@ gnupg_gcrypt_is_compliant (enum gnupg_compliance_mode compliance)
|
|||||||
if (buf
|
if (buf
|
||||||
&& split_fields_colon (buf, fields, DIM (fields)) >= 2
|
&& split_fields_colon (buf, fields, DIM (fields)) >= 2
|
||||||
&& strstr (fields[1], "de-vs"))
|
&& strstr (fields[1], "de-vs"))
|
||||||
result = 1; /* Compliant. */
|
res = 1; /* Compliant. */
|
||||||
else
|
else
|
||||||
result = 0; /* Non-compliant. */
|
res = 0; /* Non-compliant. */
|
||||||
gcry_free (buf);
|
gcry_free (buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = 0; /* Non-compliant version of Libgcrypt. */
|
res = 0; /* Non-compliant version of Libgcrypt. */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = 1;
|
res = 1;
|
||||||
|
|
||||||
return result;
|
if (result)
|
||||||
|
*result = res;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user