gpg: Disable compliance module for other GnuPG components.
[gnupg.git] / common / compliance.c
1 /* compliance.c - Functions for compliance modi
2  * Copyright (C) 2017 g10 Code GmbH
3  *
4  * This file is part of GnuPG.
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  *   - the GNU Lesser General Public License as published by the Free
10  *     Software Foundation; either version 3 of the License, or (at
11  *     your option) any later version.
12  *
13  * or
14  *
15  *   - the GNU General Public License as published by the Free
16  *     Software Foundation; either version 2 of the License, or (at
17  *     your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * This file is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, see <https://www.gnu.org/licenses/>.
28  */
29
30 #include <config.h>
31 #include <gcrypt.h>
32
33 #include "openpgpdefs.h"
34 #include "logging.h"
35 #include "util.h"
36 #include "i18n.h"
37 #include "compliance.h"
38
39 static int initialized;
40 static int module;
41
42 /* Initializes the module.  Must be called with the current
43  * GNUPG_MODULE_NAME.  Checks a few invariants, and tunes the policies
44  * for the given module.  */
45 void
46 gnupg_initialize_compliance (int gnupg_module_name)
47 {
48   log_assert (! initialized);
49
50   /* We accept both OpenPGP-style and gcrypt-style algorithm ids.
51    * Assert that they are compatible.  */
52   log_assert ((int) GCRY_PK_RSA          == (int) PUBKEY_ALGO_RSA);
53   log_assert ((int) GCRY_PK_RSA_E        == (int) PUBKEY_ALGO_RSA_E);
54   log_assert ((int) GCRY_PK_RSA_S        == (int) PUBKEY_ALGO_RSA_S);
55   log_assert ((int) GCRY_PK_ELG_E        == (int) PUBKEY_ALGO_ELGAMAL_E);
56   log_assert ((int) GCRY_PK_DSA          == (int) PUBKEY_ALGO_DSA);
57   log_assert ((int) GCRY_PK_ECC          == (int) PUBKEY_ALGO_ECDH);
58   log_assert ((int) GCRY_PK_ELG          == (int) PUBKEY_ALGO_ELGAMAL);
59   log_assert ((int) GCRY_CIPHER_NONE     == (int) CIPHER_ALGO_NONE);
60   log_assert ((int) GCRY_CIPHER_IDEA     == (int) CIPHER_ALGO_IDEA);
61   log_assert ((int) GCRY_CIPHER_3DES     == (int) CIPHER_ALGO_3DES);
62   log_assert ((int) GCRY_CIPHER_CAST5    == (int) CIPHER_ALGO_CAST5);
63   log_assert ((int) GCRY_CIPHER_BLOWFISH == (int) CIPHER_ALGO_BLOWFISH);
64   log_assert ((int) GCRY_CIPHER_AES      == (int) CIPHER_ALGO_AES);
65   log_assert ((int) GCRY_CIPHER_AES192   == (int) CIPHER_ALGO_AES192);
66   log_assert ((int) GCRY_CIPHER_AES256   == (int) CIPHER_ALGO_AES256);
67   log_assert ((int) GCRY_CIPHER_TWOFISH  == (int) CIPHER_ALGO_TWOFISH);
68   log_assert ((int) GCRY_MD_MD5          == (int) DIGEST_ALGO_MD5);
69   log_assert ((int) GCRY_MD_SHA1         == (int) DIGEST_ALGO_SHA1);
70   log_assert ((int) GCRY_MD_RMD160       == (int) DIGEST_ALGO_RMD160);
71   log_assert ((int) GCRY_MD_SHA256       == (int) DIGEST_ALGO_SHA256);
72   log_assert ((int) GCRY_MD_SHA384       == (int) DIGEST_ALGO_SHA384);
73   log_assert ((int) GCRY_MD_SHA512       == (int) DIGEST_ALGO_SHA512);
74   log_assert ((int) GCRY_MD_SHA224       == (int) DIGEST_ALGO_SHA224);
75
76   switch (gnupg_module_name)
77     {
78     case GNUPG_MODULE_NAME_GPGSM:
79     case GNUPG_MODULE_NAME_GPG:
80       break;
81
82     default:
83       log_assert (!"no policies for this module");
84     }
85
86   module = gnupg_module_name;
87   initialized = 1;
88 }
89
90 /* Return true if ALGO with a key of KEYLENGTH is compliant to the
91  * given COMPLIANCE mode.  If KEY is not NULL, various bits of
92  * information will be extracted from it.  If CURVENAME is not NULL, it
93  * is assumed to be the already computed.  ALGO may be either an
94  * OpenPGP-style pubkey_algo_t, or a gcrypt-style enum gcry_pk_algos,
95  * both are compatible from the point of view of this function.  */
96 int
97 gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
98                        gcry_mpi_t key[], unsigned int keylength, const char *curvename)
99 {
100   enum { is_rsa, is_dsa, is_pgp5, is_elg_sign, is_ecc } algotype;
101   int result = 0;
102
103   if (! initialized)
104     return 0;
105
106   switch (algo)
107     {
108     case PUBKEY_ALGO_RSA:
109     case PUBKEY_ALGO_RSA_E:
110     case PUBKEY_ALGO_RSA_S:
111       algotype = is_rsa;
112       break;
113
114     case PUBKEY_ALGO_DSA:
115       algotype = is_dsa;
116       break;
117
118     case PUBKEY_ALGO_ELGAMAL_E:
119       algotype = is_pgp5;
120       break;
121
122     case PUBKEY_ALGO_ECDH:
123     case PUBKEY_ALGO_ECDSA:
124     case PUBKEY_ALGO_EDDSA:
125       algotype = is_ecc;
126       break;
127
128     case PUBKEY_ALGO_ELGAMAL:
129       algotype = is_elg_sign;
130       break;
131
132     default: /* Unknown.  */
133       return 0;
134     }
135
136   if (compliance == CO_DE_VS)
137     {
138       char *curve = NULL;
139
140       switch (algotype)
141         {
142         case is_pgp5:
143           result = 0;
144           break;
145
146         case is_rsa:
147           result = (keylength == 2048
148                     || keylength == 3072
149                     || keylength == 4096);
150           break;
151
152         case is_dsa:
153           if (key)
154             {
155               size_t L = gcry_mpi_get_nbits (key[0] /* p */);
156               size_t N = gcry_mpi_get_nbits (key[1] /* q */);
157               result = (L == 256
158                         && (N == 2048 || N == 3072));
159             }
160           break;
161
162         case is_ecc:
163           if (!curvename && key)
164             {
165               curve = openpgp_oid_to_str (key[0]);
166               curvename = openpgp_oid_to_curve (curve, 0);
167               if (!curvename)
168                 curvename = curve;
169             }
170
171           result = (curvename
172                     && algo != PUBKEY_ALGO_EDDSA
173                     && (!strcmp (curvename, "brainpoolP256r1")
174                         || !strcmp (curvename, "brainpoolP384r1")
175                         || !strcmp (curvename, "brainpoolP512r1")));
176           break;
177
178         default:
179           result = 0;
180         }
181       xfree (curve);
182     }
183   else if (algotype == is_elg_sign)
184     {
185       /* An Elgamal signing key is only RFC-2440 compliant.  */
186       result = (compliance == CO_RFC2440);
187     }
188   else
189     {
190       result = 1; /* Assume compliance.  */
191     }
192
193   return result;
194 }
195
196
197 /* Return true if ALGO with the given KEYLENGTH is allowed in the
198  * given COMPLIANCE mode.  USE specifies for which use case the
199  * predicate is evaluated.  This way policies can be strict in what
200  * they produce, and liberal in what they accept.  */
201 int
202 gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
203                      enum pk_use_case use, int algo, gcry_mpi_t key[],
204                      unsigned int keylength, const char *curvename)
205 {
206   if (! initialized)
207     return 1;
208
209   switch (compliance)
210     {
211     case CO_DE_VS:
212       switch (algo)
213         {
214         case PUBKEY_ALGO_RSA:
215         case PUBKEY_ALGO_RSA_E:
216         case PUBKEY_ALGO_RSA_S:
217           switch (use)
218             {
219             case PK_USE_ENCRYPTION:
220               return 1;
221             case PK_USE_DECRYPTION:
222             case PK_USE_SIGNING:
223               return (keylength == 2048
224                       || keylength == 3072
225                       || keylength == 4096);
226             case PK_USE_VERIFICATION:
227               return (keylength == 2048
228                       || keylength == 3072
229                       || keylength == 4096
230                       || keylength < 2048);
231             default:
232               log_assert (!"reached");
233             }
234           log_assert (!"reached");
235
236         case PUBKEY_ALGO_DSA:
237           if (key)
238             {
239               size_t L = gcry_mpi_get_nbits (key[0] /* p */);
240               size_t N = gcry_mpi_get_nbits (key[1] /* q */);
241               return ((use == PK_USE_SIGNING
242                        && L == 256
243                        && (N == 2048 || N == 3072))
244                       || (use == PK_USE_VERIFICATION
245                           && N < 2048));
246             }
247           else
248             return 0;
249           log_assert (!"reached");
250
251         case PUBKEY_ALGO_ELGAMAL:
252         case PUBKEY_ALGO_ELGAMAL_E:
253           return use == PK_USE_ENCRYPTION;
254
255         case PUBKEY_ALGO_ECDH:
256           return use == PK_USE_ENCRYPTION;
257
258         case PUBKEY_ALGO_ECDSA:
259           {
260             int result = 0;
261             char *curve = NULL;
262
263             if (! curvename && key)
264               {
265                 curve = openpgp_oid_to_str (key[0]);
266                 curvename = openpgp_oid_to_curve (curve, 0);
267                 if (!curvename)
268                   curvename = curve;
269               }
270
271             result = ((use == PK_USE_SIGNING
272                        && curvename
273                        && (!strcmp (curvename, "brainpoolP256r1")
274                            || !strcmp (curvename, "brainpoolP384r1")
275                            || !strcmp (curvename, "brainpoolP512r1")))
276                       || use == PK_USE_VERIFICATION);
277
278             xfree (curve);
279             return result;
280           }
281
282         case PUBKEY_ALGO_EDDSA:
283           return 0;
284
285         default:
286           return 0;
287         }
288       log_assert (!"reached");
289
290     default:
291       /* The default policy is to allow all algorithms.  */
292       return 1;
293     }
294
295   log_assert (!"reached");
296 }
297
298
299 /* Return true if (CIPHER, MODE) is compliant to the given COMPLIANCE mode.  */
300 int
301 gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
302                            cipher_algo_t cipher,
303                            enum gcry_cipher_modes mode)
304 {
305   if (! initialized)
306     return 0;
307
308   switch (compliance)
309     {
310     case CO_DE_VS:
311       switch (cipher)
312         {
313         case CIPHER_ALGO_AES:
314         case CIPHER_ALGO_AES192:
315         case CIPHER_ALGO_AES256:
316         case CIPHER_ALGO_3DES:
317           switch (module)
318             {
319             case GNUPG_MODULE_NAME_GPG:
320               return mode == GCRY_CIPHER_MODE_CFB;
321             case GNUPG_MODULE_NAME_GPGSM:
322               return mode == GCRY_CIPHER_MODE_CBC;
323             }
324           log_assert (!"reached");
325
326         default:
327           return 0;
328         }
329       log_assert (!"reached");
330
331     default:
332       return 0;
333     }
334
335   log_assert (!"reached");
336 }
337
338
339 /* Return true if CIPHER is allowed in the given COMPLIANCE mode.  If
340  * PRODUCER is true, the predicate is evaluated for the producer, if
341  * false for the consumer.  This way policies can be strict in what
342  * they produce, and liberal in what they accept.  */
343 int
344 gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer,
345                          cipher_algo_t cipher,
346                          enum gcry_cipher_modes mode)
347 {
348   if (! initialized)
349     return 1;
350
351   switch (compliance)
352     {
353     case CO_DE_VS:
354       switch (cipher)
355         {
356         case CIPHER_ALGO_AES:
357         case CIPHER_ALGO_AES192:
358         case CIPHER_ALGO_AES256:
359         case CIPHER_ALGO_3DES:
360           switch (module)
361             {
362             case GNUPG_MODULE_NAME_GPG:
363               return mode == GCRY_CIPHER_MODE_NONE || mode == GCRY_CIPHER_MODE_CFB;
364             case GNUPG_MODULE_NAME_GPGSM:
365               return mode == GCRY_CIPHER_MODE_NONE || mode == GCRY_CIPHER_MODE_CBC;
366             }
367           log_assert (!"reached");
368
369         case CIPHER_ALGO_BLOWFISH:
370         case CIPHER_ALGO_CAMELLIA128:
371         case CIPHER_ALGO_CAMELLIA192:
372         case CIPHER_ALGO_CAMELLIA256:
373         case CIPHER_ALGO_CAST5:
374         case CIPHER_ALGO_IDEA:
375         case CIPHER_ALGO_TWOFISH:
376           return (module == GNUPG_MODULE_NAME_GPG
377                   && (mode == GCRY_CIPHER_MODE_NONE || mode == GCRY_CIPHER_MODE_CFB)
378                   && ! producer);
379         default:
380           return 0;
381         }
382       log_assert (!"reached");
383
384     default:
385       /* The default policy is to allow all algorithms.  */
386       return 1;
387     }
388
389   log_assert (!"reached");
390 }
391
392
393 /* Return true if DIGEST is compliant to the given COMPLIANCE mode.  */
394 int
395 gnupg_digest_is_compliant (enum gnupg_compliance_mode compliance, digest_algo_t digest)
396 {
397   if (! initialized)
398     return 0;
399
400   switch (compliance)
401     {
402     case CO_DE_VS:
403       switch (digest)
404         {
405         case DIGEST_ALGO_SHA256:
406         case DIGEST_ALGO_SHA384:
407         case DIGEST_ALGO_SHA512:
408           return 1;
409         default:
410           return 0;
411         }
412       log_assert (!"reached");
413
414     default:
415       return 0;
416     }
417
418   log_assert (!"reached");
419 }
420
421
422 /* Return true if DIGEST is allowed in the given COMPLIANCE mode.  If
423  * PRODUCER is true, the predicate is evaluated for the producer, if
424  * false for the consumer.  This way policies can be strict in what
425  * they produce, and liberal in what they accept.  */
426 int
427 gnupg_digest_is_allowed (enum gnupg_compliance_mode compliance, int producer,
428                          digest_algo_t digest)
429 {
430   if (! initialized)
431     return 1;
432
433   switch (compliance)
434     {
435     case CO_DE_VS:
436       switch (digest)
437         {
438         case DIGEST_ALGO_SHA256:
439         case DIGEST_ALGO_SHA384:
440         case DIGEST_ALGO_SHA512:
441           return 1;
442         case DIGEST_ALGO_SHA1:
443         case DIGEST_ALGO_SHA224:
444         case DIGEST_ALGO_RMD160:
445           return ! producer;
446         case DIGEST_ALGO_MD5:
447           return ! producer && module == GNUPG_MODULE_NAME_GPGSM;
448         default:
449           return 0;
450         }
451       log_assert (!"reached");
452
453     default:
454       /* The default policy is to allow all algorithms.  */
455       return 1;
456     }
457
458   log_assert (!"reached");
459 }
460
461
462 const char *
463 gnupg_status_compliance_flag (enum gnupg_compliance_mode compliance)
464 {
465   switch (compliance)
466     {
467     case CO_GNUPG:
468       return "8";
469     case CO_RFC4880:
470     case CO_RFC2440:
471     case CO_PGP6:
472     case CO_PGP7:
473     case CO_PGP8:
474       log_assert (!"no status code assigned for this compliance mode");
475     case CO_DE_VS:
476       return "23";
477     }
478   log_assert (!"invalid compliance mode");
479 }
480
481
482 /* Parse the value of --compliance.  Returns the value corresponding
483  * to the given STRING according to OPTIONS of size LENGTH, or -1
484  * indicating that the lookup was unsuccessful, or the list of options
485  * was printed.  If quiet is false, an additional hint to use 'help'
486  * is printed on unsuccessful lookups.  */
487 int
488 gnupg_parse_compliance_option (const char *string,
489                                struct gnupg_compliance_option options[],
490                                size_t length,
491                                int quiet)
492 {
493   size_t i;
494
495   if (! ascii_strcasecmp (string, "help"))
496     {
497       log_info (_ ("valid values for option '%s':\n"), "--compliance");
498       for (i = 0; i < length; i++)
499         log_info ("  %s\n", options[i].keyword);
500       return -1;
501     }
502
503   for (i = 0; i < length; i++)
504     if (! ascii_strcasecmp (string, options[i].keyword))
505       return options[i].value;
506
507   log_error (_ ("invalid value for option '%s'\n"), "--compliance");
508   if (! quiet)
509     log_info (_ ("(use \"help\" to list choices)\n"));
510   return -1;
511 }
512
513
514 /* Return the command line option for the given COMPLIANCE mode.  */
515 const char *
516 gnupg_compliance_option_string (enum gnupg_compliance_mode compliance)
517 {
518   switch (compliance)
519     {
520     case CO_GNUPG:   return "--compliance=gnupg";
521     case CO_RFC4880: return "--compliance=openpgp";
522     case CO_RFC2440: return "--compliance=rfc2440";
523     case CO_PGP6:    return "--compliance=pgp6";
524     case CO_PGP7:    return "--compliance=pgp7";
525     case CO_PGP8:    return "--compliance=pgp8";
526     case CO_DE_VS:   return "--compliance=de-vs";
527     }
528
529   log_assert (!"invalid compliance mode");
530 }