gpg,sm: Fix compliance checking for decryption.
[gnupg.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   if (! initialized)
204     return 1;
205
206   switch (compliance)
207     {
208     case CO_DE_VS:
209       switch (algo)
210         {
211         case PUBKEY_ALGO_RSA:
212         case PUBKEY_ALGO_RSA_E:
213         case PUBKEY_ALGO_RSA_S:
214           switch (use)
215             {
216             case PK_USE_DECRYPTION:
217               return 1;
218             case PK_USE_ENCRYPTION:
219             case PK_USE_SIGNING:
220               return (keylength == 2048
221                       || keylength == 3072
222                       || keylength == 4096);
223             case PK_USE_VERIFICATION:
224               return (keylength == 2048
225                       || keylength == 3072
226                       || keylength == 4096
227                       || keylength < 2048);
228             default:
229               log_assert (!"reached");
230             }
231           log_assert (!"reached");
232
233         case PUBKEY_ALGO_DSA:
234           if (key)
235             {
236               size_t P = gcry_mpi_get_nbits (key[0]);
237               size_t Q = gcry_mpi_get_nbits (key[1]);
238               return ((use == PK_USE_SIGNING
239                        && Q == 256
240                        && (P == 2048 || P == 3072))
241                       || (use == PK_USE_VERIFICATION
242                           && P < 2048));
243             }
244           else
245             return 0;
246           log_assert (!"reached");
247
248         case PUBKEY_ALGO_ELGAMAL:
249         case PUBKEY_ALGO_ELGAMAL_E:
250           return use == PK_USE_DECRYPTION;
251
252         case PUBKEY_ALGO_ECDH:
253           if (use == PK_USE_DECRYPTION)
254             return 1;
255           else if (use == PK_USE_ENCRYPTION)
256             {
257               int result = 0;
258               char *curve = NULL;
259
260               if (!curvename && key)
261                 {
262                   curve = openpgp_oid_to_str (key[0]);
263                   curvename = openpgp_oid_to_curve (curve, 0);
264                   if (!curvename)
265                     curvename = curve;
266                 }
267
268               result = (curvename
269                         && (!strcmp (curvename, "brainpoolP256r1")
270                             || !strcmp (curvename, "brainpoolP384r1")
271                             || !strcmp (curvename, "brainpoolP512r1")));
272
273               xfree (curve);
274               return result;
275             }
276           else
277             return 0;
278
279         case PUBKEY_ALGO_ECDSA:
280           {
281             int result = 0;
282             char *curve = NULL;
283
284             if (! curvename && key)
285               {
286                 curve = openpgp_oid_to_str (key[0]);
287                 curvename = openpgp_oid_to_curve (curve, 0);
288                 if (!curvename)
289                   curvename = curve;
290               }
291
292             result = ((use == PK_USE_SIGNING
293                        && curvename
294                        && (!strcmp (curvename, "brainpoolP256r1")
295                            || !strcmp (curvename, "brainpoolP384r1")
296                            || !strcmp (curvename, "brainpoolP512r1")))
297                       || use == PK_USE_VERIFICATION);
298
299             xfree (curve);
300             return result;
301           }
302
303         case PUBKEY_ALGO_EDDSA:
304           return 0;
305
306         default:
307           return 0;
308         }
309       log_assert (!"reached");
310
311     default:
312       /* The default policy is to allow all algorithms.  */
313       return 1;
314     }
315
316   log_assert (!"reached");
317 }
318
319
320 /* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode.  */
321 int
322 gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
323                            cipher_algo_t cipher,
324                            enum gcry_cipher_modes mode)
325 {
326   if (! initialized)
327     return 0;
328
329   switch (compliance)
330     {
331     case CO_DE_VS:
332       switch (cipher)
333         {
334         case CIPHER_ALGO_AES:
335         case CIPHER_ALGO_AES192:
336         case CIPHER_ALGO_AES256:
337         case CIPHER_ALGO_3DES:
338           switch (module)
339             {
340             case GNUPG_MODULE_NAME_GPG:
341               return mode == GCRY_CIPHER_MODE_CFB;
342             case GNUPG_MODULE_NAME_GPGSM:
343               return mode == GCRY_CIPHER_MODE_CBC;
344             }
345           log_assert (!"reached");
346
347         default:
348           return 0;
349         }
350       log_assert (!"reached");
351
352     default:
353       return 0;
354     }
355
356   log_assert (!"reached");
357 }
358
359
360 /* Return true if CIPHER is allowed in the given COMPLIANCE mode.  If
361  * PRODUCER is true, the predicate is evaluated for the producer, if
362  * false for the consumer.  This way policies can be strict in what
363  * they produce, and liberal in what they accept.  */
364 int
365 gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
366                          cipher_algo_t cipher,
367                          enum gcry_cipher_modes mode)
368 {
369   if (! initialized)
370     return 1;
371
372   switch (compliance)
373     {
374     case CO_DE_VS:
375       switch (cipher)
376         {
377         case CIPHER_ALGO_AES:
378         case CIPHER_ALGO_AES192:
379         case CIPHER_ALGO_AES256:
380         case CIPHER_ALGO_3DES:
381           switch (module)
382             {
383             case GNUPG_MODULE_NAME_GPG:
384               return (mode == GCRY_CIPHER_MODE_NONE
385                       || mode == GCRY_CIPHER_MODE_CFB);
386             case GNUPG_MODULE_NAME_GPGSM:
387               return (mode == GCRY_CIPHER_MODE_NONE
388                       || mode == GCRY_CIPHER_MODE_CBC);
389             }
390           log_assert (!"reached");
391
392         case CIPHER_ALGO_BLOWFISH:
393         case CIPHER_ALGO_CAMELLIA128:
394         case CIPHER_ALGO_CAMELLIA192:
395         case CIPHER_ALGO_CAMELLIA256:
396         case CIPHER_ALGO_CAST5:
397         case CIPHER_ALGO_IDEA:
398         case CIPHER_ALGO_TWOFISH:
399           return (module == GNUPG_MODULE_NAME_GPG
400                   && (mode == GCRY_CIPHER_MODE_NONE
401                       || mode == GCRY_CIPHER_MODE_CFB)
402                   && ! producer);
403         default:
404           return 0;
405         }
406       log_assert (!"reached");
407
408     default:
409       /* The default policy is to allow all algorithms.  */
410       return 1;
411     }
412
413   log_assert (!"reached");
414 }
415
416
417 /* Return true if DIGEST is compliant to the given COMPLIANCE mode.  */
418 int
419 gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
420                            digest_algo_t digest)
421 {
422   if (! initialized)
423     return 0;
424
425   switch (compliance)
426     {
427     case CO_DE_VS:
428       switch (digest)
429         {
430         case DIGEST_ALGO_SHA256:
431         case DIGEST_ALGO_SHA384:
432         case DIGEST_ALGO_SHA512:
433           return 1;
434         default:
435           return 0;
436         }
437       log_assert (!"reached");
438
439     default:
440       return 0;
441     }
442
443   log_assert (!"reached");
444 }
445
446
447 /* Return true if DIGEST is allowed in the given COMPLIANCE mode.  If
448  * PRODUCER is true, the predicate is evaluated for the producer, if
449  * false for the consumer.  This way policies can be strict in what
450  * they produce, and liberal in what they accept.  */
451 int
452 gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
453                          digest_algo_t digest)
454 {
455   if (! initialized)
456     return 1;
457
458   switch (compliance)
459     {
460     case CO_DE_VS:
461       switch (digest)
462         {
463         case DIGEST_ALGO_SHA256:
464         case DIGEST_ALGO_SHA384:
465         case DIGEST_ALGO_SHA512:
466           return 1;
467         case DIGEST_ALGO_SHA1:
468         case DIGEST_ALGO_SHA224:
469         case DIGEST_ALGO_RMD160:
470           return ! producer;
471         case DIGEST_ALGO_MD5:
472           return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
473         default:
474           return 0;
475         }
476       log_assert (!"reached");
477
478     default:
479       /* The default policy is to allow all algorithms.  */
480       return 1;
481     }
482
483   log_assert (!"reached");
484 }
485
486
487 /* Return True if the random number generator is compliant in
488  * COMPLIANCE mode.  */
489 int
490 gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance)
491 {
492   static int result = -1;
493
494   if (result != -1)
495     ; /* Use cached result.  */
496   else if (compliance == CO_DE_VS)
497     {
498       /* In DE_VS mode under Windows we require that the JENT RNG
499        * is active.  */
500 #ifdef HAVE_W32_SYSTEM
501 # if GCRYPT_VERSION_NUMBER >= 0x010800
502       char *buf;
503       char *fields[5];
504
505       buf = gcry_get_config (0, "rng-type");
506       if (buf
507           && split_fields_colon (buf, fields, DIM (fields)) >= 5
508           && atoi (fields[4]) > 0)
509         result = 1;
510       else
511         result = 0;
512       gcry_free (buf);
513 # else
514       result = 0;  /* No JENT - can't be compliant.  */
515 # endif
516 #else /*!HAVE_W32_SYSTEM*/
517       result = 1;  /* Not Windows - RNG is good.  */
518 #endif /*!HAVE_W32_SYSTEM*/
519     }
520   else
521     result = 1;
522
523   return result;
524 }
525
526
527 const char *
528 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
529 {
530   switch (compliance)
531     {
532     case CO_GNUPG:
533       return "8";
534     case CO_RFC4880:
535     case CO_RFC2440:
536     case CO_PGP6:
537     case CO_PGP7:
538     case CO_PGP8:
539       log_assert (!"no status code assigned for this compliance mode");
540     case CO_DE_VS:
541       return "23";
542     }
543   log_assert (!"invalid compliance mode");
544 }
545
546
547 /* Parse the value of --compliance.  Returns the value corresponding
548  * to the given STRING according to OPTIONS of size LENGTH, or -1
549  * indicating that the lookup was unsuccessful, or the list of options
550  * was printed.  If quiet is false, an additional hint to use 'help'
551  * is printed on unsuccessful lookups.  */
552 int
553 gnupg_parse_compliance_option (const char *string,
554                                struct gnupg_compliance_option options[],
555                                size_t length,
556                                int quiet)
557 {
558   size_t i;
559
560   if (! ascii_strcasecmp (string, "help"))
561     {
562       log_info (_("valid values for option '%s':\n"), "--compliance");
563       for (i = 0; i < length; i++)
564         log_info ("  %s\n", options[i].keyword);
565       return -1;
566     }
567
568   for (i = 0; i < length; i++)
569     if (! ascii_strcasecmp (string, options[i].keyword))
570       return options[i].value;
571
572   log_error (_("invalid value for option '%s'\n"), "--compliance");
573   if (! quiet)
574     log_info (_("(use \"help\" to list choices)\n"));
575   return -1;
576 }
577
578
579 /* Return the command line option for the given COMPLIANCE mode.  */
580 const char *
581 gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
582 {
583   switch (compliance)
584     {
585     case CO_GNUPG:   return "--compliance=gnupg";
586     case CO_RFC4880: return "--compliance=openpgp";
587     case CO_RFC2440: return "--compliance=rfc2440";
588     case CO_PGP6:    return "--compliance=pgp6";
589     case CO_PGP7:    return "--compliance=pgp7";
590     case CO_PGP8:    return "--compliance=pgp8";
591     case CO_DE_VS:   return "--compliance=de-vs";
592     }
593
594   log_assert (!"invalid compliance mode");
595 }