Imported Upstream version 2.1.23
[platform/upstream/gpg2.git] / common / compliance.c
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
4  *
5  * This file is part of GnuPG.
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of either
9  *
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.
13  *
14  * or
15  *
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.
19  *
20  * or both in parallel, as here.
21  *
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.
26  *
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/>.
29  */
30
31 #include <config.h>
32 #include <gcrypt.h>
33
34 #include "openpgpdefs.h"
35 #include "logging.h"
36 #include "util.h"
37 #include "i18n.h"
38 #include "compliance.h"
39
40 static int initialized;
41 static int module;
42
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.  */
46 void
47 gnupg_initialize_compliance (int gnupg_module_name)
48 {
49   log_assert (! initialized);
50
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);
76
77   switch (gnupg_module_name)
78     {
79     case GNUPG_MODULE_NAME_GPGSM:
80     case GNUPG_MODULE_NAME_GPG:
81       break;
82
83     default:
84       log_assert (!"no policies for this module");
85     }
86
87   module = gnupg_module_name;
88   initialized = 1;
89 }
90
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.  */
97 int
98 gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
99                        gcry_mpi_t key[], unsigned int keylength,
100                        const char *curvename)
101 {
102   enum { is_rsa, is_dsa, is_elg, is_ecc } algotype;
103   int result = 0;
104
105   if (! initialized)
106     return 0;
107
108   switch (algo)
109     {
110     case PUBKEY_ALGO_RSA:
111     case PUBKEY_ALGO_RSA_E:
112     case PUBKEY_ALGO_RSA_S:
113       algotype = is_rsa;
114       break;
115
116     case PUBKEY_ALGO_DSA:
117       algotype = is_dsa;
118       break;
119
120     case PUBKEY_ALGO_ELGAMAL_E:
121       algotype = is_elg;
122       break;
123
124     case PUBKEY_ALGO_ECDH:
125     case PUBKEY_ALGO_ECDSA:
126     case PUBKEY_ALGO_EDDSA:
127       algotype = is_ecc;
128       break;
129
130     case PUBKEY_ALGO_ELGAMAL:
131       return 0; /* Signing with Elgamal is not at all supported.  */
132
133     default: /* Unknown.  */
134       return 0;
135     }
136
137   if (compliance == CO_DE_VS)
138     {
139       char *curve = NULL;
140
141       switch (algotype)
142         {
143         case is_elg:
144           result = 0;
145           break;
146
147         case is_rsa:
148           result = (keylength == 2048
149                     || keylength == 3072
150                     || keylength == 4096);
151           break;
152
153         case is_dsa:
154           if (key)
155             {
156               size_t P = gcry_mpi_get_nbits (key[0]);
157               size_t Q = gcry_mpi_get_nbits (key[1]);
158               result = (Q == 256
159                         && (P == 2048 || P == 3072));
160             }
161           break;
162
163         case is_ecc:
164           if (!curvename && key)
165             {
166               curve = openpgp_oid_to_str (key[0]);
167               curvename = openpgp_oid_to_curve (curve, 0);
168               if (!curvename)
169                 curvename = curve;
170             }
171
172           result = (curvename
173                     && (algo == PUBKEY_ALGO_ECDH
174                         || algo == PUBKEY_ALGO_ECDSA)
175                     && (!strcmp (curvename, "brainpoolP256r1")
176                         || !strcmp (curvename, "brainpoolP384r1")
177                         || !strcmp (curvename, "brainpoolP512r1")));
178           break;
179
180         default:
181           result = 0;
182         }
183       xfree (curve);
184     }
185   else
186     {
187       result = 1; /* Assume compliance.  */
188     }
189
190   return result;
191 }
192
193
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.  */
198 int
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)
202 {
203   int result = 0;
204
205   if (! initialized)
206     return 1;
207
208   switch (compliance)
209     {
210     case CO_DE_VS:
211       switch (algo)
212         {
213         case PUBKEY_ALGO_RSA:
214         case PUBKEY_ALGO_RSA_E:
215         case PUBKEY_ALGO_RSA_S:
216           switch (use)
217             {
218             case PK_USE_DECRYPTION:
219             case PK_USE_VERIFICATION:
220               result = 1;
221               break;
222             case PK_USE_ENCRYPTION:
223             case PK_USE_SIGNING:
224               result = (keylength == 2048
225                         || keylength == 3072
226                         || keylength == 4096);
227               break;
228             default:
229               log_assert (!"reached");
230             }
231           break;
232
233         case PUBKEY_ALGO_DSA:
234           if (use == PK_USE_VERIFICATION)
235             result = 1;
236           else if (use == PK_USE_SIGNING && key)
237             {
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));
241             }
242           break;
243
244         case PUBKEY_ALGO_ELGAMAL:
245         case PUBKEY_ALGO_ELGAMAL_E:
246           result = (use == PK_USE_DECRYPTION);
247           break;
248
249         case PUBKEY_ALGO_ECDH:
250           if (use == PK_USE_DECRYPTION)
251             result = 1;
252           else if (use == PK_USE_ENCRYPTION)
253             {
254               char *curve = NULL;
255
256               if (!curvename && key)
257                 {
258                   curve = openpgp_oid_to_str (key[0]);
259                   curvename = openpgp_oid_to_curve (curve, 0);
260                   if (!curvename)
261                     curvename = curve;
262                 }
263
264               result = (curvename
265                         && (!strcmp (curvename, "brainpoolP256r1")
266                             || !strcmp (curvename, "brainpoolP384r1")
267                             || !strcmp (curvename, "brainpoolP512r1")));
268
269               xfree (curve);
270             }
271           break;
272
273         case PUBKEY_ALGO_ECDSA:
274           if (use == PK_USE_VERIFICATION)
275             result = 1;
276           else
277             {
278               char *curve = NULL;
279
280               if (! curvename && key)
281               {
282                 curve = openpgp_oid_to_str (key[0]);
283                 curvename = openpgp_oid_to_curve (curve, 0);
284                 if (!curvename)
285                   curvename = curve;
286               }
287
288               result = (use == PK_USE_SIGNING
289                          && curvename
290                          && (!strcmp (curvename, "brainpoolP256r1")
291                              || !strcmp (curvename, "brainpoolP384r1")
292                              || !strcmp (curvename, "brainpoolP512r1")));
293               xfree (curve);
294             }
295           break;
296
297
298         case PUBKEY_ALGO_EDDSA:
299           break;
300
301         default:
302           break;
303         }
304       break;
305
306     default:
307       /* The default policy is to allow all algorithms.  */
308       result = 1;
309     }
310
311   return result;
312 }
313
314
315 /* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode.  */
316 int
317 gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
318                            cipher_algo_t cipher,
319                            enum gcry_cipher_modes mode)
320 {
321   if (! initialized)
322     return 0;
323
324   switch (compliance)
325     {
326     case CO_DE_VS:
327       switch (cipher)
328         {
329         case CIPHER_ALGO_AES:
330         case CIPHER_ALGO_AES192:
331         case CIPHER_ALGO_AES256:
332         case CIPHER_ALGO_3DES:
333           switch (module)
334             {
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;
339             }
340           log_assert (!"reached");
341
342         default:
343           return 0;
344         }
345       log_assert (!"reached");
346
347     default:
348       return 0;
349     }
350
351   log_assert (!"reached");
352 }
353
354
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.  */
359 int
360 gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
361                          cipher_algo_t cipher,
362                          enum gcry_cipher_modes mode)
363 {
364   if (! initialized)
365     return 1;
366
367   switch (compliance)
368     {
369     case CO_DE_VS:
370       switch (cipher)
371         {
372         case CIPHER_ALGO_AES:
373         case CIPHER_ALGO_AES192:
374         case CIPHER_ALGO_AES256:
375         case CIPHER_ALGO_3DES:
376           switch (module)
377             {
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);
384             }
385           log_assert (!"reached");
386
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)
397                   && ! producer);
398         default:
399           return 0;
400         }
401       log_assert (!"reached");
402
403     default:
404       /* The default policy is to allow all algorithms.  */
405       return 1;
406     }
407
408   log_assert (!"reached");
409 }
410
411
412 /* Return true if DIGEST is compliant to the given COMPLIANCE mode.  */
413 int
414 gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
415                            digest_algo_t digest)
416 {
417   if (! initialized)
418     return 0;
419
420   switch (compliance)
421     {
422     case CO_DE_VS:
423       switch (digest)
424         {
425         case DIGEST_ALGO_SHA256:
426         case DIGEST_ALGO_SHA384:
427         case DIGEST_ALGO_SHA512:
428           return 1;
429         default:
430           return 0;
431         }
432       log_assert (!"reached");
433
434     default:
435       return 0;
436     }
437
438   log_assert (!"reached");
439 }
440
441
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.  */
446 int
447 gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
448                          digest_algo_t digest)
449 {
450   if (! initialized)
451     return 1;
452
453   switch (compliance)
454     {
455     case CO_DE_VS:
456       switch (digest)
457         {
458         case DIGEST_ALGO_SHA256:
459         case DIGEST_ALGO_SHA384:
460         case DIGEST_ALGO_SHA512:
461           return 1;
462         case DIGEST_ALGO_SHA1:
463         case DIGEST_ALGO_SHA224:
464         case DIGEST_ALGO_RMD160:
465           return ! producer;
466         case DIGEST_ALGO_MD5:
467           return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
468         default:
469           return 0;
470         }
471       log_assert (!"reached");
472
473     default:
474       /* The default policy is to allow all algorithms.  */
475       return 1;
476     }
477
478   log_assert (!"reached");
479 }
480
481
482 /* Return True if the random number generator is compliant in
483  * COMPLIANCE mode.  */
484 int
485 gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
486 {
487   static int result = -1;
488
489   if (result != -1)
490     ; /* Use cached result.  */
491   else if (compliance == CO_DE_VS)
492     {
493       /* In DE_VS mode under Windows we require that the JENT RNG
494        * is active.  */
495 #ifdef HAVE_W32_SYSTEM
496 # if GCRYPT_VERSION_NUMBER >= 0x010800
497       char *buf;
498       char *fields[5];
499
500       buf = gcry_get_config (0, "rng-type");
501       if (buf
502           && split_fields_colon (buf, fields, DIM (fields)) >= 5
503           && atoi (fields[4]) > 0)
504         result = 1;
505       else
506         result = 0;
507       gcry_free (buf);
508 # else
509       result = 0;  /* No JENT - can't be compliant.  */
510 # endif
511 #else /*!HAVE_W32_SYSTEM*/
512       result = 1;  /* Not Windows - RNG is good.  */
513 #endif /*!HAVE_W32_SYSTEM*/
514     }
515   else
516     result = 1;
517
518   return result;
519 }
520
521
522 const char *
523 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
524 {
525   switch (compliance)
526     {
527     case CO_GNUPG:
528       return "8";
529     case CO_RFC4880:
530     case CO_RFC2440:
531     case CO_PGP6:
532     case CO_PGP7:
533     case CO_PGP8:
534       log_assert (!"no status code assigned for this compliance mode");
535     case CO_DE_VS:
536       return "23";
537     }
538   log_assert (!"invalid compliance mode");
539 }
540
541
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.  */
547 int
548 gnupg_parse_compliance_option (const char *string,
549                                struct gnupg_compliance_option options[],
550                                size_t length,
551                                int quiet)
552 {
553   size_t i;
554
555   if (! ascii_strcasecmp (string, "help"))
556     {
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);
560       return -1;
561     }
562
563   for (i = 0; i < length; i++)
564     if (! ascii_strcasecmp (string, options[i].keyword))
565       return options[i].value;
566
567   log_error (_("invalid value for option '%s'\n"), "--compliance");
568   if (! quiet)
569     log_info (_("(use \"help\" to list choices)\n"));
570   return -1;
571 }
572
573
574 /* Return the command line option for the given COMPLIANCE mode.  */
575 const char *
576 gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
577 {
578   switch (compliance)
579     {
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";
587     }
588
589   log_assert (!"invalid compliance mode");
590 }