1 /* compliance.c - Functions for compliance modi
2 * Copyright (C) 2017 g10 Code GmbH
3 * Copyright (C) 2017 Bundesamt für Sicherheit in der Informationstechnik
5 * This file is part of GnuPG.
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of either
10 * - the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
16 * - the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
20 * or both in parallel, as here.
22 * This file is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses/>.
34 #include "openpgpdefs.h"
38 #include "compliance.h"
40 static int initialized;
43 /* Initializes the module. Must be called with the current
44 * GNUPG_MODULE_NAME. Checks a few invariants, and tunes the policies
45 * for the given module. */
47 gnupg_initialize_compliance (int gnupg_module_name)
49 log_assert (! initialized);
51 /* We accept both OpenPGP-style and gcrypt-style algorithm ids.
52 * Assert that they are compatible. */
53 log_assert ((int) GCRY_PK_RSA == (int) PUBKEY_ALGO_RSA);
54 log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
55 log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
56 log_assert ((int) GCRY_PK_ELG_E == (int) PUBKEY_ALGO_ELGAMAL_E);
57 log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA);
58 log_assert ((int) GCRY_PK_ECC == (int) PUBKEY_ALGO_ECDH);
59 log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL);
60 log_assert ((int) GCRY_CIPHER_NONE == (int) CIPHER_ALGO_NONE);
61 log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
62 log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
63 log_assert ((int) GCRY_CIPHER_CAST5 == (int) CIPHER_ALGO_CAST5);
64 log_assert ((int) GCRY_CIPHER_BLOWFISH == (int) CIPHER_ALGO_BLOWFISH);
65 log_assert ((int) GCRY_CIPHER_AES == (int) CIPHER_ALGO_AES);
66 log_assert ((int) GCRY_CIPHER_AES192 == (int) CIPHER_ALGO_AES192);
67 log_assert ((int) GCRY_CIPHER_AES256 == (int) CIPHER_ALGO_AES256);
68 log_assert ((int) GCRY_CIPHER_TWOFISH == (int) CIPHER_ALGO_TWOFISH);
69 log_assert ((int) GCRY_MD_MD5 == (int) DIGEST_ALGO_MD5);
70 log_assert ((int) GCRY_MD_SHA1 == (int) DIGEST_ALGO_SHA1);
71 log_assert ((int) GCRY_MD_RMD160 == (int) DIGEST_ALGO_RMD160);
72 log_assert ((int) GCRY_MD_SHA256 == (int) DIGEST_ALGO_SHA256);
73 log_assert ((int) GCRY_MD_SHA384 == (int) DIGEST_ALGO_SHA384);
74 log_assert ((int) GCRY_MD_SHA512 == (int) DIGEST_ALGO_SHA512);
75 log_assert ((int) GCRY_MD_SHA224 == (int) DIGEST_ALGO_SHA224);
77 switch (gnupg_module_name)
79 case GNUPG_MODULE_NAME_GPGSM:
80 case GNUPG_MODULE_NAME_GPG:
84 log_assert (!"no policies for this module");
87 module = gnupg_module_name;
91 /* Return true if ALGO with a key of KEYLENGTH is compliant to the
92 * given COMPLIANCE mode. If KEY is not NULL, various bits of
93 * information will be extracted from it. If CURVENAME is not NULL, it
94 * is assumed to be the already computed. ALGO may be either an
95 * OpenPGP-style pubkey_algo_t, or a gcrypt-style enum gcry_pk_algos,
96 * both are compatible from the point of view of this function. */
98 gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
99 gcry_mpi_t key[], unsigned int keylength,
100 const char *curvename)
102 enum { is_rsa, is_dsa, is_elg, is_ecc } algotype;
110 case PUBKEY_ALGO_RSA:
111 case PUBKEY_ALGO_RSA_E:
112 case PUBKEY_ALGO_RSA_S:
116 case PUBKEY_ALGO_DSA:
120 case PUBKEY_ALGO_ELGAMAL_E:
124 case PUBKEY_ALGO_ECDH:
125 case PUBKEY_ALGO_ECDSA:
126 case PUBKEY_ALGO_EDDSA:
130 case PUBKEY_ALGO_ELGAMAL:
131 return 0; /* Signing with Elgamal is not at all supported. */
133 default: /* Unknown. */
137 if (compliance == CO_DE_VS)
148 result = (keylength == 2048
150 || keylength == 4096);
156 size_t P = gcry_mpi_get_nbits (key[0]);
157 size_t Q = gcry_mpi_get_nbits (key[1]);
159 && (P == 2048 || P == 3072));
164 if (!curvename && key)
166 curve = openpgp_oid_to_str (key[0]);
167 curvename = openpgp_oid_to_curve (curve, 0);
173 && (algo == PUBKEY_ALGO_ECDH
174 || algo == PUBKEY_ALGO_ECDSA)
175 && (!strcmp (curvename, "brainpoolP256r1")
176 || !strcmp (curvename, "brainpoolP384r1")
177 || !strcmp (curvename, "brainpoolP512r1")));
187 result = 1; /* Assume compliance. */
194 /* Return true if ALGO with the given KEYLENGTH is allowed in the
195 * given COMPLIANCE mode. USE specifies for which use case the
196 * predicate is evaluated. This way policies can be strict in what
197 * they produce, and liberal in what they accept. */
199 gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
200 enum pk_use_case use, int algo, gcry_mpi_t key[],
201 unsigned int keylength, const char *curvename)
213 case PUBKEY_ALGO_RSA:
214 case PUBKEY_ALGO_RSA_E:
215 case PUBKEY_ALGO_RSA_S:
218 case PK_USE_DECRYPTION:
219 case PK_USE_VERIFICATION:
222 case PK_USE_ENCRYPTION:
224 result = (keylength == 2048
226 || keylength == 4096);
229 log_assert (!"reached");
233 case PUBKEY_ALGO_DSA:
234 if (use == PK_USE_VERIFICATION)
236 else if (use == PK_USE_SIGNING && key)
238 size_t P = gcry_mpi_get_nbits (key[0]);
239 size_t Q = gcry_mpi_get_nbits (key[1]);
240 result = (Q == 256 && (P == 2048 || P == 3072));
244 case PUBKEY_ALGO_ELGAMAL:
245 case PUBKEY_ALGO_ELGAMAL_E:
246 result = (use == PK_USE_DECRYPTION);
249 case PUBKEY_ALGO_ECDH:
250 if (use == PK_USE_DECRYPTION)
252 else if (use == PK_USE_ENCRYPTION)
256 if (!curvename && key)
258 curve = openpgp_oid_to_str (key[0]);
259 curvename = openpgp_oid_to_curve (curve, 0);
265 && (!strcmp (curvename, "brainpoolP256r1")
266 || !strcmp (curvename, "brainpoolP384r1")
267 || !strcmp (curvename, "brainpoolP512r1")));
273 case PUBKEY_ALGO_ECDSA:
274 if (use == PK_USE_VERIFICATION)
280 if (! curvename && key)
282 curve = openpgp_oid_to_str (key[0]);
283 curvename = openpgp_oid_to_curve (curve, 0);
288 result = (use == PK_USE_SIGNING
290 && (!strcmp (curvename, "brainpoolP256r1")
291 || !strcmp (curvename, "brainpoolP384r1")
292 || !strcmp (curvename, "brainpoolP512r1")));
298 case PUBKEY_ALGO_EDDSA:
307 /* The default policy is to allow all algorithms. */
315 /* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode. */
317 gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
318 cipher_algo_t cipher,
319 enum gcry_cipher_modes mode)
329 case CIPHER_ALGO_AES:
330 case CIPHER_ALGO_AES192:
331 case CIPHER_ALGO_AES256:
332 case CIPHER_ALGO_3DES:
335 case GNUPG_MODULE_NAME_GPG:
336 return mode == GCRY_CIPHER_MODE_CFB;
337 case GNUPG_MODULE_NAME_GPGSM:
338 return mode == GCRY_CIPHER_MODE_CBC;
340 log_assert (!"reached");
345 log_assert (!"reached");
351 log_assert (!"reached");
355 /* Return true if CIPHER is allowed in the given COMPLIANCE mode. If
356 * PRODUCER is true, the predicate is evaluated for the producer, if
357 * false for the consumer. This way policies can be strict in what
358 * they produce, and liberal in what they accept. */
360 gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
361 cipher_algo_t cipher,
362 enum gcry_cipher_modes mode)
372 case CIPHER_ALGO_AES:
373 case CIPHER_ALGO_AES192:
374 case CIPHER_ALGO_AES256:
375 case CIPHER_ALGO_3DES:
378 case GNUPG_MODULE_NAME_GPG:
379 return (mode == GCRY_CIPHER_MODE_NONE
380 || mode == GCRY_CIPHER_MODE_CFB);
381 case GNUPG_MODULE_NAME_GPGSM:
382 return (mode == GCRY_CIPHER_MODE_NONE
383 || mode == GCRY_CIPHER_MODE_CBC);
385 log_assert (!"reached");
387 case CIPHER_ALGO_BLOWFISH:
388 case CIPHER_ALGO_CAMELLIA128:
389 case CIPHER_ALGO_CAMELLIA192:
390 case CIPHER_ALGO_CAMELLIA256:
391 case CIPHER_ALGO_CAST5:
392 case CIPHER_ALGO_IDEA:
393 case CIPHER_ALGO_TWOFISH:
394 return (module == GNUPG_MODULE_NAME_GPG
395 && (mode == GCRY_CIPHER_MODE_NONE
396 || mode == GCRY_CIPHER_MODE_CFB)
401 log_assert (!"reached");
404 /* The default policy is to allow all algorithms. */
408 log_assert (!"reached");
412 /* Return true if DIGEST is compliant to the given COMPLIANCE mode. */
414 gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
415 digest_algo_t digest)
425 case DIGEST_ALGO_SHA256:
426 case DIGEST_ALGO_SHA384:
427 case DIGEST_ALGO_SHA512:
432 log_assert (!"reached");
438 log_assert (!"reached");
442 /* Return true if DIGEST is allowed in the given COMPLIANCE mode. If
443 * PRODUCER is true, the predicate is evaluated for the producer, if
444 * false for the consumer. This way policies can be strict in what
445 * they produce, and liberal in what they accept. */
447 gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
448 digest_algo_t digest)
458 case DIGEST_ALGO_SHA256:
459 case DIGEST_ALGO_SHA384:
460 case DIGEST_ALGO_SHA512:
462 case DIGEST_ALGO_SHA1:
463 case DIGEST_ALGO_SHA224:
464 case DIGEST_ALGO_RMD160:
466 case DIGEST_ALGO_MD5:
467 return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
471 log_assert (!"reached");
474 /* The default policy is to allow all algorithms. */
478 log_assert (!"reached");
482 /* Return True if the random number generator is compliant in
483 * COMPLIANCE mode. */
485 gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
487 static int result = -1;
490 ; /* Use cached result. */
491 else if (compliance == CO_DE_VS)
493 /* In DE_VS mode under Windows we require that the JENT RNG
495 #ifdef HAVE_W32_SYSTEM
496 # if GCRYPT_VERSION_NUMBER >= 0x010800
500 buf = gcry_get_config (0, "rng-type");
502 && split_fields_colon (buf, fields, DIM (fields)) >= 5
503 && atoi (fields[4]) > 0)
509 result = 0; /* No JENT - can't be compliant. */
511 #else /*!HAVE_W32_SYSTEM*/
512 result = 1; /* Not Windows - RNG is good. */
513 #endif /*!HAVE_W32_SYSTEM*/
523 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
534 log_assert (!"no status code assigned for this compliance mode");
538 log_assert (!"invalid compliance mode");
542 /* Parse the value of --compliance. Returns the value corresponding
543 * to the given STRING according to OPTIONS of size LENGTH, or -1
544 * indicating that the lookup was unsuccessful, or the list of options
545 * was printed. If quiet is false, an additional hint to use 'help'
546 * is printed on unsuccessful lookups. */
548 gnupg_parse_compliance_option (const char *string,
549 struct gnupg_compliance_option options[],
555 if (! ascii_strcasecmp (string, "help"))
557 log_info (_("valid values for option '%s':\n"), "--compliance");
558 for (i = 0; i < length; i++)
559 log_info (" %s\n", options[i].keyword);
563 for (i = 0; i < length; i++)
564 if (! ascii_strcasecmp (string, options[i].keyword))
565 return options[i].value;
567 log_error (_("invalid value for option '%s'\n"), "--compliance");
569 log_info (_("(use \"help\" to list choices)\n"));
574 /* Return the command line option for the given COMPLIANCE mode. */
576 gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
580 case CO_GNUPG: return "--compliance=gnupg";
581 case CO_RFC4880: return "--compliance=openpgp";
582 case CO_RFC2440: return "--compliance=rfc2440";
583 case CO_PGP6: return "--compliance=pgp6";
584 case CO_PGP7: return "--compliance=pgp7";
585 case CO_PGP8: return "--compliance=pgp8";
586 case CO_DE_VS: return "--compliance=de-vs";
589 log_assert (!"invalid compliance mode");