3c43fd8210aafb99cb903847e32e9027dbc5571e
[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_pgp5, is_elg_sign, 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_pgp5;
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       algotype = is_elg_sign;
132       break;
133
134     default: /* Unknown.  */
135       return 0;
136     }
137
138   if (compliance == CO_DE_VS)
139     {
140       char *curve = NULL;
141
142       switch (algotype)
143         {
144         case is_pgp5:
145           result = 0;
146           break;
147
148         case is_rsa:
149           result = (keylength == 2048
150                     || keylength == 3072
151                     || keylength == 4096);
152           break;
153
154         case is_dsa:
155           if (key)
156             {
157               size_t L = gcry_mpi_get_nbits (key[0] /* p */);
158               size_t N = gcry_mpi_get_nbits (key[1] /* q */);
159               result = (L == 256
160                         && (N == 2048 || N == 3072));
161             }
162           break;
163
164         case is_ecc:
165           if (!curvename && key)
166             {
167               curve = openpgp_oid_to_str (key[0]);
168               curvename = openpgp_oid_to_curve (curve, 0);
169               if (!curvename)
170                 curvename = curve;
171             }
172
173           result = (curvename
174                     && algo != PUBKEY_ALGO_EDDSA
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 if (algotype == is_elg_sign)
186     {
187       /* An Elgamal signing key is only RFC-2440 compliant.  */
188       result = (compliance == CO_RFC2440);
189     }
190   else
191     {
192       result = 1; /* Assume compliance.  */
193     }
194
195   return result;
196 }
197
198
199 /* Return true if ALGO with the given KEYLENGTH is allowed in the
200  * given COMPLIANCE mode.  USE specifies for which use case the
201  * predicate is evaluated.  This way policies can be strict in what
202  * they produce, and liberal in what they accept.  */
203 int
204 gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
205                      enum pk_use_case use, int algo, gcry_mpi_t key[],
206                      unsigned int keylength, const char *curvename)
207 {
208   if (! initialized)
209     return 1;
210
211   switch (compliance)
212     {
213     case CO_DE_VS:
214       switch (algo)
215         {
216         case PUBKEY_ALGO_RSA:
217         case PUBKEY_ALGO_RSA_E:
218         case PUBKEY_ALGO_RSA_S:
219           switch (use)
220             {
221             case PK_USE_ENCRYPTION:
222               return 1;
223             case PK_USE_DECRYPTION:
224             case PK_USE_SIGNING:
225               return (keylength == 2048
226                       || keylength == 3072
227                       || keylength == 4096);
228             case PK_USE_VERIFICATION:
229               return (keylength == 2048
230                       || keylength == 3072
231                       || keylength == 4096
232                       || keylength < 2048);
233             default:
234               log_assert (!"reached");
235             }
236           log_assert (!"reached");
237
238         case PUBKEY_ALGO_DSA:
239           if (key)
240             {
241               size_t L = gcry_mpi_get_nbits (key[0] /* p */);
242               size_t N = gcry_mpi_get_nbits (key[1] /* q */);
243               return ((use == PK_USE_SIGNING
244                        && L == 256
245                        && (N == 2048 || N == 3072))
246                       || (use == PK_USE_VERIFICATION
247                           && N < 2048));
248             }
249           else
250             return 0;
251           log_assert (!"reached");
252
253         case PUBKEY_ALGO_ELGAMAL:
254         case PUBKEY_ALGO_ELGAMAL_E:
255           return use == PK_USE_ENCRYPTION;
256
257         case PUBKEY_ALGO_ECDH:
258           return use == PK_USE_ENCRYPTION;
259
260         case PUBKEY_ALGO_ECDSA:
261           {
262             int result = 0;
263             char *curve = NULL;
264
265             if (! curvename && key)
266               {
267                 curve = openpgp_oid_to_str (key[0]);
268                 curvename = openpgp_oid_to_curve (curve, 0);
269                 if (!curvename)
270                   curvename = curve;
271               }
272
273             result = ((use == PK_USE_SIGNING
274                        && curvename
275                        && (!strcmp (curvename, "brainpoolP256r1")
276                            || !strcmp (curvename, "brainpoolP384r1")
277                            || !strcmp (curvename, "brainpoolP512r1")))
278                       || use == PK_USE_VERIFICATION);
279
280             xfree (curve);
281             return result;
282           }
283
284         case PUBKEY_ALGO_EDDSA:
285           return 0;
286
287         default:
288           return 0;
289         }
290       log_assert (!"reached");
291
292     default:
293       /* The default policy is to allow all algorithms.  */
294       return 1;
295     }
296
297   log_assert (!"reached");
298 }
299
300
301 /* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode.  */
302 int
303 gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
304                            cipher_algo_t cipher,
305                            enum gcry_cipher_modes mode)
306 {
307   if (! initialized)
308     return 0;
309
310   switch (compliance)
311     {
312     case CO_DE_VS:
313       switch (cipher)
314         {
315         case CIPHER_ALGO_AES:
316         case CIPHER_ALGO_AES192:
317         case CIPHER_ALGO_AES256:
318         case CIPHER_ALGO_3DES:
319           switch (module)
320             {
321             case GNUPG_MODULE_NAME_GPG:
322               return mode == GCRY_CIPHER_MODE_CFB;
323             case GNUPG_MODULE_NAME_GPGSM:
324               return mode == GCRY_CIPHER_MODE_CBC;
325             }
326           log_assert (!"reached");
327
328         default:
329           return 0;
330         }
331       log_assert (!"reached");
332
333     default:
334       return 0;
335     }
336
337   log_assert (!"reached");
338 }
339
340
341 /* Return true if CIPHER is allowed in the given COMPLIANCE mode.  If
342  * PRODUCER is true, the predicate is evaluated for the producer, if
343  * false for the consumer.  This way policies can be strict in what
344  * they produce, and liberal in what they accept.  */
345 int
346 gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
347                          cipher_algo_t cipher,
348                          enum gcry_cipher_modes mode)
349 {
350   if (! initialized)
351     return 1;
352
353   switch (compliance)
354     {
355     case CO_DE_VS:
356       switch (cipher)
357         {
358         case CIPHER_ALGO_AES:
359         case CIPHER_ALGO_AES192:
360         case CIPHER_ALGO_AES256:
361         case CIPHER_ALGO_3DES:
362           switch (module)
363             {
364             case GNUPG_MODULE_NAME_GPG:
365               return (mode == GCRY_CIPHER_MODE_NONE
366                       || mode == GCRY_CIPHER_MODE_CFB);
367             case GNUPG_MODULE_NAME_GPGSM:
368               return (mode == GCRY_CIPHER_MODE_NONE
369                       || mode == GCRY_CIPHER_MODE_CBC);
370             }
371           log_assert (!"reached");
372
373         case CIPHER_ALGO_BLOWFISH:
374         case CIPHER_ALGO_CAMELLIA128:
375         case CIPHER_ALGO_CAMELLIA192:
376         case CIPHER_ALGO_CAMELLIA256:
377         case CIPHER_ALGO_CAST5:
378         case CIPHER_ALGO_IDEA:
379         case CIPHER_ALGO_TWOFISH:
380           return (module == GNUPG_MODULE_NAME_GPG
381                   && (mode == GCRY_CIPHER_MODE_NONE
382                       || mode == GCRY_CIPHER_MODE_CFB)
383                   && ! producer);
384         default:
385           return 0;
386         }
387       log_assert (!"reached");
388
389     default:
390       /* The default policy is to allow all algorithms.  */
391       return 1;
392     }
393
394   log_assert (!"reached");
395 }
396
397
398 /* Return true if DIGEST is compliant to the given COMPLIANCE mode.  */
399 int
400 gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance,
401                            digest_algo_t digest)
402 {
403   if (! initialized)
404     return 0;
405
406   switch (compliance)
407     {
408     case CO_DE_VS:
409       switch (digest)
410         {
411         case DIGEST_ALGO_SHA256:
412         case DIGEST_ALGO_SHA384:
413         case DIGEST_ALGO_SHA512:
414           return 1;
415         default:
416           return 0;
417         }
418       log_assert (!"reached");
419
420     default:
421       return 0;
422     }
423
424   log_assert (!"reached");
425 }
426
427
428 /* Return true if DIGEST is allowed in the given COMPLIANCE mode.  If
429  * PRODUCER is true, the predicate is evaluated for the producer, if
430  * false for the consumer.  This way policies can be strict in what
431  * they produce, and liberal in what they accept.  */
432 int
433 gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
434                          digest_algo_t digest)
435 {
436   if (! initialized)
437     return 1;
438
439   switch (compliance)
440     {
441     case CO_DE_VS:
442       switch (digest)
443         {
444         case DIGEST_ALGO_SHA256:
445         case DIGEST_ALGO_SHA384:
446         case DIGEST_ALGO_SHA512:
447           return 1;
448         case DIGEST_ALGO_SHA1:
449         case DIGEST_ALGO_SHA224:
450         case DIGEST_ALGO_RMD160:
451           return ! producer;
452         case DIGEST_ALGO_MD5:
453           return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
454         default:
455           return 0;
456         }
457       log_assert (!"reached");
458
459     default:
460       /* The default policy is to allow all algorithms.  */
461       return 1;
462     }
463
464   log_assert (!"reached");
465 }
466
467
468 const char *
469 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
470 {
471   switch (compliance)
472     {
473     case CO_GNUPG:
474       return "8";
475     case CO_RFC4880:
476     case CO_RFC2440:
477     case CO_PGP6:
478     case CO_PGP7:
479     case CO_PGP8:
480       log_assert (!"no status code assigned for this compliance mode");
481     case CO_DE_VS:
482       return "23";
483     }
484   log_assert (!"invalid compliance mode");
485 }
486
487
488 /* Parse the value of --compliance.  Returns the value corresponding
489  * to the given STRING according to OPTIONS of size LENGTH, or -1
490  * indicating that the lookup was unsuccessful, or the list of options
491  * was printed.  If quiet is false, an additional hint to use 'help'
492  * is printed on unsuccessful lookups.  */
493 int
494 gnupg_parse_compliance_option (const char *string,
495                                struct gnupg_compliance_option options[],
496                                size_t length,
497                                int quiet)
498 {
499   size_t i;
500
501   if (! ascii_strcasecmp (string, "help"))
502     {
503       log_info (_("valid values for option '%s':\n"), "--compliance");
504       for (i = 0; i < length; i++)
505         log_info ("  %s\n", options[i].keyword);
506       return -1;
507     }
508
509   for (i = 0; i < length; i++)
510     if (! ascii_strcasecmp (string, options[i].keyword))
511       return options[i].value;
512
513   log_error (_("invalid value for option '%s'\n"), "--compliance");
514   if (! quiet)
515     log_info (_("(use \"help\" to list choices)\n"));
516   return -1;
517 }
518
519
520 /* Return the command line option for the given COMPLIANCE mode.  */
521 const char *
522 gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
523 {
524   switch (compliance)
525     {
526     case CO_GNUPG:   return "--compliance=gnupg";
527     case CO_RFC4880: return "--compliance=openpgp";
528     case CO_RFC2440: return "--compliance=rfc2440";
529     case CO_PGP6:    return "--compliance=pgp6";
530     case CO_PGP7:    return "--compliance=pgp7";
531     case CO_PGP8:    return "--compliance=pgp8";
532     case CO_DE_VS:   return "--compliance=de-vs";
533     }
534
535   log_assert (!"invalid compliance mode");
536 }