gpg: Add configure options to disable algorithms
[gnupg.git] / g10 / misc.c
1 /* misc.c - miscellaneous functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3  *               2008, 2009, 2010 Free Software Foundation, Inc.
4  * Copyright (C) 2014 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
29 #include <asm/sysinfo.h>
30 #include <asm/unistd.h>
31 #endif
32 #ifdef HAVE_SETRLIMIT
33 #include <time.h>
34 #include <sys/time.h>
35 #include <sys/resource.h>
36 #endif
37 #ifdef ENABLE_SELINUX_HACKS
38 #include <sys/stat.h>
39 #endif
40
41 #ifdef HAVE_W32_SYSTEM
42 #include <time.h>
43 #include <process.h>
44 #include <windows.h>
45 #include <shlobj.h>
46 #ifndef CSIDL_APPDATA
47 #define CSIDL_APPDATA 0x001a
48 #endif
49 #ifndef CSIDL_LOCAL_APPDATA
50 #define CSIDL_LOCAL_APPDATA 0x001c
51 #endif
52 #ifndef CSIDL_FLAG_CREATE
53 #define CSIDL_FLAG_CREATE 0x8000
54 #endif
55 #endif /*HAVE_W32_SYSTEM*/
56
57 #include "gpg.h"
58 #ifdef HAVE_W32_SYSTEM
59 # include "status.h"
60 #endif /*HAVE_W32_SYSTEM*/
61 #include "util.h"
62 #include "main.h"
63 #include "photoid.h"
64 #include "options.h"
65 #include "call-agent.h"
66 #include "i18n.h"
67
68 #include <assert.h>
69
70 static int
71 string_count_chr (const char *string, int c)
72 {
73   int count;
74
75   for (count=0; *string; string++ )
76     if ( *string == c )
77       count++;
78   return count;
79 }
80
81
82
83 #ifdef ENABLE_SELINUX_HACKS
84 /* A object and a global variable to keep track of files marked as
85    secured. */
86 struct secured_file_item
87 {
88   struct secured_file_item *next;
89   ino_t ino;
90   dev_t dev;
91 };
92 static struct secured_file_item *secured_files;
93 #endif /*ENABLE_SELINUX_HACKS*/
94
95
96
97
98 /* For the sake of SELinux we want to restrict access through gpg to
99    certain files we keep under our own control.  This function
100    registers such a file and is_secured_file may then be used to
101    check whether a file has ben registered as secured. */
102 void
103 register_secured_file (const char *fname)
104 {
105 #ifdef ENABLE_SELINUX_HACKS
106   struct stat buf;
107   struct secured_file_item *sf;
108
109   /* Note that we stop immediatley if something goes wrong here. */
110   if (stat (fname, &buf))
111     log_fatal (_("fstat of '%s' failed in %s: %s\n"), fname,
112                "register_secured_file", strerror (errno));
113 /*   log_debug ("registering '%s' i=%lu.%lu\n", fname, */
114 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
115   for (sf=secured_files; sf; sf = sf->next)
116     {
117       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
118         return; /* Already registered.  */
119     }
120
121   sf = xmalloc (sizeof *sf);
122   sf->ino = buf.st_ino;
123   sf->dev = buf.st_dev;
124   sf->next = secured_files;
125   secured_files = sf;
126 #else /*!ENABLE_SELINUX_HACKS*/
127   (void)fname;
128 #endif /*!ENABLE_SELINUX_HACKS*/
129 }
130
131 /* Remove a file registered as secure. */
132 void
133 unregister_secured_file (const char *fname)
134 {
135 #ifdef ENABLE_SELINUX_HACKS
136   struct stat buf;
137   struct secured_file_item *sf, *sfprev;
138
139   if (stat (fname, &buf))
140     {
141       log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
142                  "unregister_secured_file", strerror (errno));
143       return;
144     }
145 /*   log_debug ("unregistering '%s' i=%lu.%lu\n", fname,  */
146 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
147   for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
148     {
149       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
150         {
151           if (sfprev)
152             sfprev->next = sf->next;
153           else
154             secured_files = sf->next;
155           xfree (sf);
156           return;
157         }
158     }
159 #else /*!ENABLE_SELINUX_HACKS*/
160   (void)fname;
161 #endif /*!ENABLE_SELINUX_HACKS*/
162 }
163
164 /* Return true if FD is corresponds to a secured file.  Using -1 for
165    FS is allowed and will return false. */
166 int
167 is_secured_file (int fd)
168 {
169 #ifdef ENABLE_SELINUX_HACKS
170   struct stat buf;
171   struct secured_file_item *sf;
172
173   if (fd == -1)
174     return 0; /* No file descriptor so it can't be secured either.  */
175
176   /* Note that we print out a error here and claim that a file is
177      secure if something went wrong. */
178   if (fstat (fd, &buf))
179     {
180       log_error (_("fstat(%d) failed in %s: %s\n"), fd,
181                  "is_secured_file", strerror (errno));
182       return 1;
183     }
184 /*   log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
185 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
186   for (sf=secured_files; sf; sf = sf->next)
187     {
188       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
189         return 1; /* Yes.  */
190     }
191 #else /*!ENABLE_SELINUX_HACKS*/
192   (void)fd;
193 #endif /*!ENABLE_SELINUX_HACKS*/
194   return 0; /* No. */
195 }
196
197 /* Return true if FNAME is corresponds to a secured file.  Using NULL,
198    "" or "-" for FS is allowed and will return false. This function is
199    used before creating a file, thus it won't fail if the file does
200    not exist. */
201 int
202 is_secured_filename (const char *fname)
203 {
204 #ifdef ENABLE_SELINUX_HACKS
205   struct stat buf;
206   struct secured_file_item *sf;
207
208   if (iobuf_is_pipe_filename (fname) || !*fname)
209     return 0;
210
211   /* Note that we print out a error here and claim that a file is
212      secure if something went wrong. */
213   if (stat (fname, &buf))
214     {
215       if (errno == ENOENT || errno == EPERM || errno == EACCES)
216         return 0;
217       log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
218                  "is_secured_filename", strerror (errno));
219       return 1;
220     }
221 /*   log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
222 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
223   for (sf=secured_files; sf; sf = sf->next)
224     {
225       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
226         return 1; /* Yes.  */
227     }
228 #else /*!ENABLE_SELINUX_HACKS*/
229   (void)fname;
230 #endif /*!ENABLE_SELINUX_HACKS*/
231   return 0; /* No. */
232 }
233
234
235
236 u16
237 checksum_u16( unsigned n )
238 {
239     u16 a;
240
241     a  = (n >> 8) & 0xff;
242     a += n & 0xff;
243     return a;
244 }
245
246
247 u16
248 checksum( byte *p, unsigned n )
249 {
250     u16 a;
251
252     for(a=0; n; n-- )
253         a += *p++;
254     return a;
255 }
256
257 u16
258 checksum_mpi (gcry_mpi_t a)
259 {
260   u16 csum;
261   byte *buffer;
262   size_t nbytes;
263
264   if ( gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a) )
265     BUG ();
266   /* Fixme: For numbers not in secure memory we should use a stack
267    * based buffer and only allocate a larger one if mpi_print returns
268    * an error. */
269   buffer = (gcry_is_secure(a)?
270             gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes));
271   if ( gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a) )
272     BUG ();
273   csum = checksum (buffer, nbytes);
274   xfree (buffer);
275   return csum;
276 }
277
278 u32
279 buffer_to_u32( const byte *buffer )
280 {
281     unsigned long a;
282     a =  *buffer << 24;
283     a |= buffer[1] << 16;
284     a |= buffer[2] << 8;
285     a |= buffer[3];
286     return a;
287 }
288
289 void
290 print_pubkey_algo_note (pubkey_algo_t algo)
291 {
292   if(algo >= 100 && algo <= 110)
293     {
294       static int warn=0;
295       if(!warn)
296         {
297           warn=1;
298           log_info (_("WARNING: using experimental public key algorithm %s\n"),
299                     openpgp_cipher_algo_name (algo));
300         }
301     }
302   else if (algo == 20)
303     {
304       log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
305     }
306 }
307
308 void
309 print_cipher_algo_note (cipher_algo_t algo)
310 {
311   if(algo >= 100 && algo <= 110)
312     {
313       static int warn=0;
314       if(!warn)
315         {
316           warn=1;
317           log_info (_("WARNING: using experimental cipher algorithm %s\n"),
318                     openpgp_cipher_algo_name (algo));
319         }
320     }
321 }
322
323 void
324 print_digest_algo_note (digest_algo_t algo)
325 {
326   if(algo >= 100 && algo <= 110)
327     {
328       static int warn=0;
329       if(!warn)
330         {
331           warn=1;
332           log_info (_("WARNING: using experimental digest algorithm %s\n"),
333                     gcry_md_algo_name (algo));
334         }
335     }
336   else if(algo==DIGEST_ALGO_MD5)
337     log_info (_("WARNING: digest algorithm %s is deprecated\n"),
338               gcry_md_algo_name (algo));
339 }
340
341
342 /* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
343    this for algorithms we implemented in Libgcrypt after they become
344    part of OpenPGP.  */
345 enum gcry_cipher_algos
346 map_cipher_openpgp_to_gcry (cipher_algo_t algo)
347 {
348   switch (algo)
349     {
350     case CIPHER_ALGO_NONE:        return GCRY_CIPHER_NONE;
351 #ifdef GPG_USE_IDEA
352     case CIPHER_ALGO_IDEA:        return GCRY_CIPHER_IDEA;
353 #endif
354     case CIPHER_ALGO_3DES:        return GCRY_CIPHER_3DES;
355 #ifdef GPG_USE_CAST5
356     case CIPHER_ALGO_CAST5:       return GCRY_CIPHER_CAST5;
357 #endif
358 #ifdef GPG_USE_BLOWFISH
359     case CIPHER_ALGO_BLOWFISH:    return GCRY_CIPHER_BLOWFISH;
360 #endif
361 #ifdef GPG_USE_AES128
362     case CIPHER_ALGO_AES:         return GCRY_CIPHER_AES;
363 #endif
364 #ifdef GPG_USE_AES192
365     case CIPHER_ALGO_AES192:      return GCRY_CIPHER_AES192;
366 #endif
367 #ifdef GPG_USE_AES256
368     case CIPHER_ALGO_AES256:      return GCRY_CIPHER_AES256;
369 #endif
370 #ifdef GPG_USE_TWOFISH
371     case CIPHER_ALGO_TWOFISH:     return GCRY_CIPHER_TWOFISH;
372 #endif
373 #ifdef GPG_USE_CAMELLIA128
374     case CIPHER_ALGO_CAMELLIA128: return GCRY_CIPHER_CAMELLIA128;
375 #endif
376 #ifdef GPG_USE_CAMELLIA192
377     case CIPHER_ALGO_CAMELLIA192: return GCRY_CIPHER_CAMELLIA192;
378 #endif
379 #ifdef GPG_USE_CAMELLIA256
380     case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
381 #endif
382     }
383   return 0;
384 }
385
386 /* The inverse function of above.  */
387 static cipher_algo_t
388 map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
389 {
390   switch (algo)
391     {
392     case GCRY_CIPHER_NONE:        return CIPHER_ALGO_NONE;
393     case GCRY_CIPHER_IDEA:        return CIPHER_ALGO_IDEA;
394     case GCRY_CIPHER_3DES:        return CIPHER_ALGO_3DES;
395     case GCRY_CIPHER_CAST5:       return CIPHER_ALGO_CAST5;
396     case GCRY_CIPHER_BLOWFISH:    return CIPHER_ALGO_BLOWFISH;
397     case GCRY_CIPHER_AES:         return CIPHER_ALGO_AES;
398     case GCRY_CIPHER_AES192:      return CIPHER_ALGO_AES192;
399     case GCRY_CIPHER_AES256:      return CIPHER_ALGO_AES256;
400     case GCRY_CIPHER_TWOFISH:     return CIPHER_ALGO_TWOFISH;
401     case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
402     case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
403     case GCRY_CIPHER_CAMELLIA256: return CIPHER_ALGO_CAMELLIA256;
404     default: return 0;
405     }
406 }
407
408 /* Map Gcrypt public key algorithm numbers to those used by OpenPGP.
409    FIXME: This mapping is used at only two places - we should get rid
410    of it.  */
411 pubkey_algo_t
412 map_pk_gcry_to_openpgp (enum gcry_pk_algos algo)
413 {
414   switch (algo)
415     {
416     case GCRY_PK_ECDSA:  return PUBKEY_ALGO_ECDSA;
417     case GCRY_PK_ECDH:   return PUBKEY_ALGO_ECDH;
418     default: return algo < 110 ? algo : 0;
419     }
420 }
421
422
423 /* Return the block length of an OpenPGP cipher algorithm.  */
424 int
425 openpgp_cipher_blocklen (cipher_algo_t algo)
426 {
427   /* We use the numbers from OpenPGP to be sure that we get the right
428      block length.  This is so that the packet parsing code works even
429      for unknown algorithms (for which we assume 8 due to tradition).
430
431      NOTE: If you change the the returned blocklen above 16, check
432      the callers because they may use a fixed size buffer of that
433      size. */
434   switch (algo)
435     {
436     case CIPHER_ALGO_AES:
437     case CIPHER_ALGO_AES192:
438     case CIPHER_ALGO_AES256:
439     case CIPHER_ALGO_TWOFISH:
440     case CIPHER_ALGO_CAMELLIA128:
441     case CIPHER_ALGO_CAMELLIA192:
442     case CIPHER_ALGO_CAMELLIA256:
443       return 16;
444
445     default:
446       return 8;
447     }
448 }
449
450 /****************
451  * Wrapper around the libgcrypt function with additonal checks on
452  * the OpenPGP contraints for the algo ID.
453  */
454 int
455 openpgp_cipher_test_algo (cipher_algo_t algo)
456 {
457   enum gcry_cipher_algos ga;
458
459   ga = map_cipher_openpgp_to_gcry (algo);
460   if (!ga)
461     return gpg_error (GPG_ERR_CIPHER_ALGO);
462
463   return gcry_cipher_test_algo (ga);
464 }
465
466 /* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
467    string representation of the algorithm name.  For unknown algorithm
468    IDs this function returns "?".  */
469 const char *
470 openpgp_cipher_algo_name (cipher_algo_t algo)
471 {
472   switch (algo)
473     {
474     case CIPHER_ALGO_NONE:        break;
475     case CIPHER_ALGO_IDEA:        return "IDEA";
476     case CIPHER_ALGO_3DES:        return "3DES";
477     case CIPHER_ALGO_CAST5:       return "CAST5";
478     case CIPHER_ALGO_BLOWFISH:    return "BLOWFISH";
479     case CIPHER_ALGO_AES:         return "AES";
480     case CIPHER_ALGO_AES192:      return "AES192";
481     case CIPHER_ALGO_AES256:      return "AES256";
482     case CIPHER_ALGO_TWOFISH:     return "TWOFISH";
483     case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
484     case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
485     case CIPHER_ALGO_CAMELLIA256: return "CAMELLIA256";
486     }
487   return "?";
488 }
489
490
491 /* Return 0 if ALGO is a supported OpenPGP public key algorithm.  */
492 int
493 openpgp_pk_test_algo (pubkey_algo_t algo)
494 {
495   return openpgp_pk_test_algo2 (algo, 0);
496 }
497
498
499 /* Return 0 if ALGO is a supported OpenPGP public key algorithm and
500    allows the usage USE.  */
501 int
502 openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
503 {
504   enum gcry_pk_algos ga = 0;
505   size_t use_buf = use;
506
507   switch (algo)
508     {
509 #ifdef GPG_USE_RSA
510     case PUBKEY_ALGO_RSA:       ga = GCRY_PK_RSA;   break;
511     case PUBKEY_ALGO_RSA_E:     ga = GCRY_PK_RSA_E; break;
512     case PUBKEY_ALGO_RSA_S:     ga = GCRY_PK_RSA_S; break;
513 #endif
514     case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG;   break;
515     case PUBKEY_ALGO_DSA:       ga = GCRY_PK_DSA;   break;
516
517 #ifdef GPG_USE_ECDH
518     case PUBKEY_ALGO_ECDH:      ga = GCRY_PK_ECC;   break;
519 #endif
520 #ifdef GPG_USE_ECDSA
521     case PUBKEY_ALGO_ECDSA:     ga = GCRY_PK_ECC;   break;
522 #endif
523 #ifdef GPG_USE_EDDSA
524     case PUBKEY_ALGO_EDDSA:     ga = GCRY_PK_ECC;   break;
525 #endif
526
527     case PUBKEY_ALGO_ELGAMAL:
528       /* Dont't allow type 20 keys unless in rfc2440 mode.  */
529       if (RFC2440)
530         ga = GCRY_PK_ELG;
531       break;
532     }
533   if (!ga)
534     return gpg_error (GPG_ERR_PUBKEY_ALGO);
535
536   /* No check whether Libgcrypt has support for the algorithm.  */
537   return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
538 }
539
540
541 int
542 openpgp_pk_algo_usage ( int algo )
543 {
544     int use = 0;
545
546     /* They are hardwired in gpg 1.0. */
547     switch ( algo ) {
548       case PUBKEY_ALGO_RSA:
549           use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
550                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
551           break;
552       case PUBKEY_ALGO_RSA_E:
553       case PUBKEY_ALGO_ECDH:
554           use = PUBKEY_USAGE_ENC;
555           break;
556       case PUBKEY_ALGO_RSA_S:
557           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
558           break;
559       case PUBKEY_ALGO_ELGAMAL:
560           if (RFC2440)
561              use = PUBKEY_USAGE_ENC;
562           break;
563       case PUBKEY_ALGO_ELGAMAL_E:
564           use = PUBKEY_USAGE_ENC;
565           break;
566       case PUBKEY_ALGO_DSA:
567           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
568           break;
569       case PUBKEY_ALGO_ECDSA:
570       case PUBKEY_ALGO_EDDSA:
571           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
572       default:
573           break;
574     }
575     return use;
576 }
577
578 /* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
579    string representation of the algorithm name.  For unknown algorithm
580    IDs this function returns "?".  */
581 const char *
582 openpgp_pk_algo_name (pubkey_algo_t algo)
583 {
584   switch (algo)
585     {
586     case PUBKEY_ALGO_RSA:
587     case PUBKEY_ALGO_RSA_E:
588     case PUBKEY_ALGO_RSA_S:     return "RSA";
589     case PUBKEY_ALGO_ELGAMAL:
590     case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
591     case PUBKEY_ALGO_DSA:       return "DSA";
592     case PUBKEY_ALGO_ECDH:      return "ECDH";
593     case PUBKEY_ALGO_ECDSA:     return "ECDSA";
594     case PUBKEY_ALGO_EDDSA:     return "EDDSA";
595     }
596   return "?";
597 }
598
599
600 /* Explicit mapping of OpenPGP digest algos to Libgcrypt.  */
601 /* FIXME: We do not yes use it everywhere.  */
602 enum gcry_md_algos
603 map_md_openpgp_to_gcry (digest_algo_t algo)
604 {
605   switch (algo)
606     {
607 #ifdef GPG_USE_MD5
608     case DIGEST_ALGO_MD5:    return GCRY_MD_MD5;
609 #endif
610     case DIGEST_ALGO_SHA1:   return GCRY_MD_SHA1;
611 #ifdef GPG_USE_RMD160
612     case DIGEST_ALGO_RMD160: return GCRY_MD_RMD160;
613 #endif
614 #ifdef GPG_USE_SHA224
615     case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
616 #endif
617 #ifdef GPG_USE_SHA256
618     case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
619 #endif
620 #ifdef GPG_USE_SHA384
621     case DIGEST_ALGO_SHA384: return GCRY_MD_SHA384;
622 #endif
623 #ifdef GPG_USE_512
624     case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
625 #endif
626     }
627   return 0;
628 }
629
630
631 /* Return 0 if ALGO is suitable and implemented OpenPGP hash
632    algorithm.  */
633 int
634 openpgp_md_test_algo (digest_algo_t algo)
635 {
636   enum gcry_md_algos ga;
637
638   ga = map_md_openpgp_to_gcry (algo);
639   if (!ga)
640     return gpg_error (GPG_ERR_DIGEST_ALGO);
641
642   return gcry_md_test_algo (ga);
643 }
644
645
646 /* Map the OpenPGP digest algorithm whose ID is contained in ALGO to a
647    string representation of the algorithm name.  For unknown algorithm
648    IDs this function returns "?".  */
649 const char *
650 openpgp_md_algo_name (int algo)
651 {
652   switch (algo)
653     {
654     case DIGEST_ALGO_MD5:    return "MD5";
655     case DIGEST_ALGO_SHA1:   return "SHA1";
656     case DIGEST_ALGO_RMD160: return "RIPEMD160";
657     case DIGEST_ALGO_SHA256: return "SHA256";
658     case DIGEST_ALGO_SHA384: return "SHA384";
659     case DIGEST_ALGO_SHA512: return "SHA512";
660     case DIGEST_ALGO_SHA224: return "SHA224";
661     }
662   return "?";
663 }
664
665
666 static unsigned long
667 get_signature_count (PKT_public_key *pk)
668 {
669 #ifdef ENABLE_CARD_SUPPORT
670   struct agent_card_info_s info;
671
672   (void)pk;
673   if (!agent_scd_getattr ("SIG-COUNTER",&info))
674     return info.sig_counter;
675   else
676     return 0;
677 #else
678   (void)pk;
679   return 0;
680 #endif
681 }
682
683 /* Expand %-strings.  Returns a string which must be xfreed.  Returns
684    NULL if the string cannot be expanded (too large). */
685 char *
686 pct_expando(const char *string,struct expando_args *args)
687 {
688   const char *ch=string;
689   int idx=0,maxlen=0,done=0;
690   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
691   char *ret=NULL;
692
693   if(args->pk)
694     keyid_from_pk(args->pk,pk_keyid);
695
696   if(args->pksk)
697     keyid_from_pk (args->pksk, sk_keyid);
698
699   /* This is used so that %k works in photoid command strings in
700      --list-secret-keys (which of course has a sk, but no pk). */
701   if(!args->pk && args->pksk)
702     keyid_from_pk (args->pksk, pk_keyid);
703
704   while(*ch!='\0')
705     {
706       if(!done)
707         {
708           /* 8192 is way bigger than we'll need here */
709           if(maxlen>=8192)
710             goto fail;
711
712           maxlen+=1024;
713           ret=xrealloc(ret,maxlen);
714         }
715
716       done=0;
717
718       if(*ch=='%')
719         {
720           switch(*(ch+1))
721             {
722             case 's': /* short key id */
723               if(idx+8<maxlen)
724                 {
725                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
726                   idx+=8;
727                   done=1;
728                 }
729               break;
730
731             case 'S': /* long key id */
732               if(idx+16<maxlen)
733                 {
734                   sprintf(&ret[idx],"%08lX%08lX",
735                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
736                   idx+=16;
737                   done=1;
738                 }
739               break;
740
741             case 'k': /* short key id */
742               if(idx+8<maxlen)
743                 {
744                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
745                   idx+=8;
746                   done=1;
747                 }
748               break;
749
750             case 'K': /* long key id */
751               if(idx+16<maxlen)
752                 {
753                   sprintf(&ret[idx],"%08lX%08lX",
754                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
755                   idx+=16;
756                   done=1;
757                 }
758               break;
759
760             case 'c': /* signature count from card, if any. */
761               if(idx+10<maxlen)
762                 {
763                   sprintf (&ret[idx],"%lu", get_signature_count (args->pksk));
764                   idx+=strlen(&ret[idx]);
765                   done=1;
766                 }
767               break;
768
769             case 'p': /* primary pk fingerprint of a sk */
770             case 'f': /* pk fingerprint */
771             case 'g': /* sk fingerprint */
772               {
773                 byte array[MAX_FINGERPRINT_LEN];
774                 size_t len;
775                 int i;
776
777                 if((*(ch+1))=='p' && args->pksk)
778                   {
779                     if(args->pksk->flags.primary)
780                       fingerprint_from_pk (args->pksk, array, &len);
781                     else if (args->pksk->main_keyid[0]
782                              || args->pksk->main_keyid[1])
783                       {
784                         /* FIXME: Document teh code and check whether
785                            it is still needed.  */
786                         PKT_public_key *pk=
787                           xmalloc_clear(sizeof(PKT_public_key));
788
789                         if (!get_pubkey_fast (pk,args->pksk->main_keyid))
790                           fingerprint_from_pk (pk, array, &len);
791                         else
792                           memset (array, 0, (len=MAX_FINGERPRINT_LEN));
793                         free_public_key (pk);
794                       }
795                     else
796                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
797                   }
798                 else if((*(ch+1))=='f' && args->pk)
799                   fingerprint_from_pk (args->pk, array, &len);
800                 else if((*(ch+1))=='g' && args->pksk)
801                   fingerprint_from_pk (args->pksk, array, &len);
802                 else
803                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
804
805                 if(idx+(len*2)<maxlen)
806                   {
807                     for(i=0;i<len;i++)
808                       {
809                         sprintf(&ret[idx],"%02X",array[i]);
810                         idx+=2;
811                       }
812                     done=1;
813                   }
814               }
815               break;
816
817             case 'v': /* validity letters */
818               if(args->validity_info && idx+1<maxlen)
819                 {
820                   ret[idx++]=args->validity_info;
821                   ret[idx]='\0';
822                   done=1;
823                 }
824               break;
825
826               /* The text string types */
827             case 't':
828             case 'T':
829             case 'V':
830               {
831                 const char *str=NULL;
832
833                 switch(*(ch+1))
834                   {
835                   case 't': /* e.g. "jpg" */
836                     str=image_type_to_string(args->imagetype,0);
837                     break;
838
839                   case 'T': /* e.g. "image/jpeg" */
840                     str=image_type_to_string(args->imagetype,2);
841                     break;
842
843                   case 'V': /* e.g. "full", "expired", etc. */
844                     str=args->validity_string;
845                     break;
846                   }
847
848                 if(str && idx+strlen(str)<maxlen)
849                   {
850                     strcpy(&ret[idx],str);
851                     idx+=strlen(str);
852                     done=1;
853                   }
854               }
855               break;
856
857             case '%':
858               if(idx+1<maxlen)
859                 {
860                   ret[idx++]='%';
861                   ret[idx]='\0';
862                   done=1;
863                 }
864               break;
865
866               /* Any unknown %-keys (like %i, %o, %I, and %O) are
867                  passed through for later expansion.  Note this also
868                  handles the case where the last character in the
869                  string is a '%' - the terminating \0 will end up here
870                  and properly terminate the string. */
871             default:
872               if(idx+2<maxlen)
873                 {
874                   ret[idx++]='%';
875                   ret[idx++]=*(ch+1);
876                   ret[idx]='\0';
877                   done=1;
878                 }
879               break;
880               }
881
882           if(done)
883             ch++;
884         }
885       else
886         {
887           if(idx+1<maxlen)
888             {
889               ret[idx++]=*ch;
890               ret[idx]='\0';
891               done=1;
892             }
893         }
894
895       if(done)
896         ch++;
897     }
898
899   return ret;
900
901  fail:
902   xfree(ret);
903   return NULL;
904 }
905
906 void
907 deprecated_warning(const char *configname,unsigned int configlineno,
908                    const char *option,const char *repl1,const char *repl2)
909 {
910   if(configname)
911     {
912       if(strncmp("--",option,2)==0)
913         option+=2;
914
915       if(strncmp("--",repl1,2)==0)
916         repl1+=2;
917
918       log_info(_("%s:%d: deprecated option \"%s\"\n"),
919                configname,configlineno,option);
920     }
921   else
922     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
923
924   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
925 }
926
927
928 void
929 deprecated_command (const char *name)
930 {
931   log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
932            name);
933 }
934
935
936 void
937 obsolete_option (const char *configname, unsigned int configlineno,
938                  const char *name)
939 {
940   if(configname)
941     log_info (_("%s:%u: obsolete option \"%s\" - it has no effect\n"),
942               configname, configlineno, name);
943   else
944     log_info (_("WARNING: \"%s\" is an obsolete option - it has no effect\n"),
945               name);
946 }
947
948
949 /*
950  * Wrapper around gcry_cipher_map_name to provide a fallback using the
951  * "Sn" syntax as used by the preference strings.
952  */
953 int
954 string_to_cipher_algo (const char *string)
955 {
956   int val;
957
958   val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
959   if (!val && string && (string[0]=='S' || string[0]=='s'))
960     {
961       char *endptr;
962
963       string++;
964       val = strtol (string, &endptr, 10);
965       if (!*string || *endptr || openpgp_cipher_test_algo (val))
966         val = 0;
967     }
968
969   return val;
970 }
971
972 /*
973  * Wrapper around gcry_md_map_name to provide a fallback using the
974  * "Hn" syntax as used by the preference strings.
975  */
976 int
977 string_to_digest_algo (const char *string)
978 {
979   int val;
980
981   /* FIXME: We should make use of our wrapper fucntion and not assume
982      that there is a 1 to 1 mapping between OpenPGP and Libgcrypt.  */
983   val = gcry_md_map_name (string);
984   if (!val && string && (string[0]=='H' || string[0]=='h'))
985     {
986       char *endptr;
987
988       string++;
989       val = strtol (string, &endptr, 10);
990       if (!*string || *endptr || openpgp_md_test_algo (val))
991         val = 0;
992     }
993
994   return val;
995 }
996
997
998
999 const char *
1000 compress_algo_to_string(int algo)
1001 {
1002   const char *s=NULL;
1003
1004   switch(algo)
1005     {
1006     case COMPRESS_ALGO_NONE:
1007       s=_("Uncompressed");
1008       break;
1009
1010     case COMPRESS_ALGO_ZIP:
1011       s="ZIP";
1012       break;
1013
1014     case COMPRESS_ALGO_ZLIB:
1015       s="ZLIB";
1016       break;
1017
1018 #ifdef HAVE_BZIP2
1019     case COMPRESS_ALGO_BZIP2:
1020       s="BZIP2";
1021       break;
1022 #endif
1023     }
1024
1025   return s;
1026 }
1027
1028 int
1029 string_to_compress_algo(const char *string)
1030 {
1031   /* TRANSLATORS: See doc/TRANSLATE about this string. */
1032   if(match_multistr(_("uncompressed|none"),string))
1033     return 0;
1034   else if(ascii_strcasecmp(string,"uncompressed")==0)
1035     return 0;
1036   else if(ascii_strcasecmp(string,"none")==0)
1037     return 0;
1038   else if(ascii_strcasecmp(string,"zip")==0)
1039     return 1;
1040   else if(ascii_strcasecmp(string,"zlib")==0)
1041     return 2;
1042 #ifdef HAVE_BZIP2
1043   else if(ascii_strcasecmp(string,"bzip2")==0)
1044     return 3;
1045 #endif
1046   else if(ascii_strcasecmp(string,"z0")==0)
1047     return 0;
1048   else if(ascii_strcasecmp(string,"z1")==0)
1049     return 1;
1050   else if(ascii_strcasecmp(string,"z2")==0)
1051     return 2;
1052 #ifdef HAVE_BZIP2
1053   else if(ascii_strcasecmp(string,"z3")==0)
1054     return 3;
1055 #endif
1056   else
1057     return -1;
1058 }
1059
1060 int
1061 check_compress_algo(int algo)
1062 {
1063   switch (algo)
1064     {
1065     case 0: return 0;
1066 #ifdef HAVE_ZIP
1067     case 1:
1068     case 2: return 0;
1069 #endif
1070 #ifdef HAVE_BZIP2
1071     case 3: return 0;
1072 #endif
1073     default: return G10ERR_COMPR_ALGO;
1074     }
1075 }
1076
1077 int
1078 default_cipher_algo(void)
1079 {
1080   if(opt.def_cipher_algo)
1081     return opt.def_cipher_algo;
1082   else if(opt.personal_cipher_prefs)
1083     return opt.personal_cipher_prefs[0].value;
1084   else
1085     return opt.s2k_cipher_algo;
1086 }
1087
1088 /* There is no default_digest_algo function, but see
1089    sign.c:hash_for() */
1090
1091 int
1092 default_compress_algo(void)
1093 {
1094   if(opt.compress_algo!=-1)
1095     return opt.compress_algo;
1096   else if(opt.personal_compress_prefs)
1097     return opt.personal_compress_prefs[0].value;
1098   else
1099     return DEFAULT_COMPRESS_ALGO;
1100 }
1101
1102 const char *
1103 compliance_option_string(void)
1104 {
1105   char *ver="???";
1106
1107   switch(opt.compliance)
1108     {
1109     case CO_GNUPG:   return "--gnupg";
1110     case CO_RFC4880: return "--openpgp";
1111     case CO_RFC2440: return "--rfc2440";
1112     case CO_RFC1991: return "--rfc1991";
1113     case CO_PGP2:    return "--pgp2";
1114     case CO_PGP6:    return "--pgp6";
1115     case CO_PGP7:    return "--pgp7";
1116     case CO_PGP8:    return "--pgp8";
1117     }
1118
1119   return ver;
1120 }
1121
1122 void
1123 compliance_failure(void)
1124 {
1125   char *ver="???";
1126
1127   switch(opt.compliance)
1128     {
1129     case CO_GNUPG:
1130       ver="GnuPG";
1131       break;
1132
1133     case CO_RFC4880:
1134       ver="OpenPGP";
1135       break;
1136
1137     case CO_RFC2440:
1138       ver="OpenPGP (older)";
1139       break;
1140
1141     case CO_RFC1991:
1142       ver="old PGP";
1143       break;
1144
1145     case CO_PGP2:
1146       ver="PGP 2.x";
1147       break;
1148
1149     case CO_PGP6:
1150       ver="PGP 6.x";
1151       break;
1152
1153     case CO_PGP7:
1154       ver="PGP 7.x";
1155       break;
1156
1157     case CO_PGP8:
1158       ver="PGP 8.x";
1159       break;
1160     }
1161
1162   log_info(_("this message may not be usable by %s\n"),ver);
1163   opt.compliance=CO_GNUPG;
1164 }
1165
1166 /* Break a string into successive option pieces.  Accepts single word
1167    options and key=value argument options. */
1168 char *
1169 optsep(char **stringp)
1170 {
1171   char *tok,*end;
1172
1173   tok=*stringp;
1174   if(tok)
1175     {
1176       end=strpbrk(tok," ,=");
1177       if(end)
1178         {
1179           int sawequals=0;
1180           char *ptr=end;
1181
1182           /* what we need to do now is scan along starting with *end,
1183              If the next character we see (ignoring spaces) is an =
1184              sign, then there is an argument. */
1185
1186           while(*ptr)
1187             {
1188               if(*ptr=='=')
1189                 sawequals=1;
1190               else if(*ptr!=' ')
1191                 break;
1192               ptr++;
1193             }
1194
1195           /* There is an argument, so grab that too.  At this point,
1196              ptr points to the first character of the argument. */
1197           if(sawequals)
1198             {
1199               /* Is it a quoted argument? */
1200               if(*ptr=='"')
1201                 {
1202                   ptr++;
1203                   end=strchr(ptr,'"');
1204                   if(end)
1205                     end++;
1206                 }
1207               else
1208                 end=strpbrk(ptr," ,");
1209             }
1210
1211           if(end && *end)
1212             {
1213               *end='\0';
1214               *stringp=end+1;
1215             }
1216           else
1217             *stringp=NULL;
1218         }
1219       else
1220         *stringp=NULL;
1221     }
1222
1223   return tok;
1224 }
1225
1226 /* Breaks an option value into key and value.  Returns NULL if there
1227    is no value.  Note that "string" is modified to remove the =value
1228    part. */
1229 char *
1230 argsplit(char *string)
1231 {
1232   char *equals,*arg=NULL;
1233
1234   equals=strchr(string,'=');
1235   if(equals)
1236     {
1237       char *quote,*space;
1238
1239       *equals='\0';
1240       arg=equals+1;
1241
1242       /* Quoted arg? */
1243       quote=strchr(arg,'"');
1244       if(quote)
1245         {
1246           arg=quote+1;
1247
1248           quote=strchr(arg,'"');
1249           if(quote)
1250             *quote='\0';
1251         }
1252       else
1253         {
1254           size_t spaces;
1255
1256           /* Trim leading spaces off of the arg */
1257           spaces=strspn(arg," ");
1258           arg+=spaces;
1259         }
1260
1261       /* Trim tailing spaces off of the tag */
1262       space=strchr(string,' ');
1263       if(space)
1264         *space='\0';
1265     }
1266
1267   return arg;
1268 }
1269
1270 /* Return the length of the initial token, leaving off any
1271    argument. */
1272 static size_t
1273 optlen(const char *s)
1274 {
1275   char *end=strpbrk(s," =");
1276
1277   if(end)
1278     return end-s;
1279   else
1280     return strlen(s);
1281 }
1282
1283 int
1284 parse_options(char *str,unsigned int *options,
1285               struct parse_options *opts,int noisy)
1286 {
1287   char *tok;
1288
1289   if (str && !strcmp (str, "help"))
1290     {
1291       int i,maxlen=0;
1292
1293       /* Figure out the longest option name so we can line these up
1294          neatly. */
1295       for(i=0;opts[i].name;i++)
1296         if(opts[i].help && maxlen<strlen(opts[i].name))
1297           maxlen=strlen(opts[i].name);
1298
1299       for(i=0;opts[i].name;i++)
1300         if(opts[i].help)
1301           printf("%s%*s%s\n",opts[i].name,
1302                  maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
1303
1304       g10_exit(0);
1305     }
1306
1307   while((tok=optsep(&str)))
1308     {
1309       int i,rev=0;
1310       char *otok=tok;
1311
1312       if(tok[0]=='\0')
1313         continue;
1314
1315       if(ascii_strncasecmp("no-",tok,3)==0)
1316         {
1317           rev=1;
1318           tok+=3;
1319         }
1320
1321       for(i=0;opts[i].name;i++)
1322         {
1323           size_t toklen=optlen(tok);
1324
1325           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1326             {
1327               /* We have a match, but it might be incomplete */
1328               if(toklen!=strlen(opts[i].name))
1329                 {
1330                   int j;
1331
1332                   for(j=i+1;opts[j].name;j++)
1333                     {
1334                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1335                         {
1336                           if(noisy)
1337                             log_info(_("ambiguous option '%s'\n"),otok);
1338                           return 0;
1339                         }
1340                     }
1341                 }
1342
1343               if(rev)
1344                 {
1345                   *options&=~opts[i].bit;
1346                   if(opts[i].value)
1347                     *opts[i].value=NULL;
1348                 }
1349               else
1350                 {
1351                   *options|=opts[i].bit;
1352                   if(opts[i].value)
1353                     *opts[i].value=argsplit(tok);
1354                 }
1355               break;
1356             }
1357         }
1358
1359       if(!opts[i].name)
1360         {
1361           if(noisy)
1362             log_info(_("unknown option '%s'\n"),otok);
1363           return 0;
1364         }
1365     }
1366
1367   return 1;
1368 }
1369
1370
1371 /* Check whether the string has characters not valid in an RFC-822
1372    address.  To cope with OpenPGP we ignore non-ascii characters
1373    so that for example umlauts are legal in an email address.  An
1374    OpenPGP user ID must be utf-8 encoded but there is no strict
1375    requirement for RFC-822.  Thus to avoid IDNA encoding we put the
1376    address verbatim as utf-8 into the user ID under the assumption
1377    that mail programs handle IDNA at a lower level and take OpenPGP
1378    user IDs as utf-8.  Note that we can't do an utf-8 encoding
1379    checking here because in keygen.c this function is called with the
1380    native encoding and native to utf-8 encoding is only done  later.  */
1381 int
1382 has_invalid_email_chars (const char *s)
1383 {
1384   int at_seen=0;
1385   const char *valid_chars=
1386     "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1387
1388   for ( ; *s; s++ )
1389     {
1390       if ( (*s & 0x80) )
1391         continue; /* We only care about ASCII.  */
1392       if ( *s == '@' )
1393         at_seen=1;
1394       else if ( !at_seen && !(strchr (valid_chars, *s)
1395                               || strchr ("!#$%&'*+/=?^`{|}~", *s)))
1396         return 1;
1397       else if ( at_seen && !strchr( valid_chars, *s ) )
1398         return 1;
1399     }
1400   return 0;
1401 }
1402
1403
1404 /* Check whether NAME represents a valid mailbox according to
1405    RFC822. Returns true if so. */
1406 int
1407 is_valid_mailbox (const char *name)
1408 {
1409   return !( !name
1410             || !*name
1411             || has_invalid_email_chars (name)
1412             || string_count_chr (name,'@') != 1
1413             || *name == '@'
1414             || name[strlen(name)-1] == '@'
1415             || name[strlen(name)-1] == '.'
1416             || strstr (name, "..") );
1417 }
1418
1419
1420 /* Similar to access(2), but uses PATH to find the file. */
1421 int
1422 path_access(const char *file,int mode)
1423 {
1424   char *envpath;
1425   int ret=-1;
1426
1427   envpath=getenv("PATH");
1428
1429   if(!envpath
1430 #ifdef HAVE_DRIVE_LETTERS
1431      || (((file[0]>='A' && file[0]<='Z')
1432           || (file[0]>='a' && file[0]<='z'))
1433          && file[1]==':')
1434 #else
1435      || file[0]=='/'
1436 #endif
1437      )
1438     return access(file,mode);
1439   else
1440     {
1441       /* At least as large as, but most often larger than we need. */
1442       char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1443       char *split,*item,*path=xstrdup(envpath);
1444
1445       split=path;
1446
1447       while((item=strsep(&split,PATHSEP_S)))
1448         {
1449           strcpy(buffer,item);
1450           strcat(buffer,"/");
1451           strcat(buffer,file);
1452           ret=access(buffer,mode);
1453           if(ret==0)
1454             break;
1455         }
1456
1457       xfree(path);
1458       xfree(buffer);
1459     }
1460
1461   return ret;
1462 }
1463
1464
1465 \f
1466 /* Return the number of public key parameters as used by OpenPGP.  */
1467 int
1468 pubkey_get_npkey (pubkey_algo_t algo)
1469 {
1470   switch (algo)
1471     {
1472     case PUBKEY_ALGO_RSA:
1473     case PUBKEY_ALGO_RSA_E:
1474     case PUBKEY_ALGO_RSA_S:     return 2;
1475     case PUBKEY_ALGO_ELGAMAL_E: return 3;
1476     case PUBKEY_ALGO_DSA:       return 4;
1477     case PUBKEY_ALGO_ECDH:      return 3;
1478     case PUBKEY_ALGO_ECDSA:     return 2;
1479     case PUBKEY_ALGO_ELGAMAL:   return 3;
1480     case PUBKEY_ALGO_EDDSA:     return 2;
1481     }
1482   return 0;
1483 }
1484
1485
1486 /* Return the number of secret key parameters as used by OpenPGP.  */
1487 int
1488 pubkey_get_nskey (pubkey_algo_t algo)
1489 {
1490   switch (algo)
1491     {
1492     case PUBKEY_ALGO_RSA:
1493     case PUBKEY_ALGO_RSA_E:
1494     case PUBKEY_ALGO_RSA_S:     return 6;
1495     case PUBKEY_ALGO_ELGAMAL_E: return 4;
1496     case PUBKEY_ALGO_DSA:       return 5;
1497     case PUBKEY_ALGO_ECDH:      return 4;
1498     case PUBKEY_ALGO_ECDSA:     return 3;
1499     case PUBKEY_ALGO_ELGAMAL:   return 4;
1500     case PUBKEY_ALGO_EDDSA:     return 3;
1501     }
1502   return 0;
1503 }
1504
1505 /* Temporary helper. */
1506 int
1507 pubkey_get_nsig (pubkey_algo_t algo)
1508 {
1509   switch (algo)
1510     {
1511     case PUBKEY_ALGO_RSA:
1512     case PUBKEY_ALGO_RSA_E:
1513     case PUBKEY_ALGO_RSA_S:     return 1;
1514     case PUBKEY_ALGO_ELGAMAL_E: return 0;
1515     case PUBKEY_ALGO_DSA:       return 2;
1516     case PUBKEY_ALGO_ECDH:      return 0;
1517     case PUBKEY_ALGO_ECDSA:     return 2;
1518     case PUBKEY_ALGO_ELGAMAL:   return 2;
1519     case PUBKEY_ALGO_EDDSA:     return 2;
1520     }
1521   return 0;
1522 }
1523
1524
1525 /* Temporary helper. */
1526 int
1527 pubkey_get_nenc (pubkey_algo_t algo)
1528 {
1529   switch (algo)
1530     {
1531     case PUBKEY_ALGO_RSA:
1532     case PUBKEY_ALGO_RSA_E:
1533     case PUBKEY_ALGO_RSA_S:     return 1;
1534     case PUBKEY_ALGO_ELGAMAL_E: return 2;
1535     case PUBKEY_ALGO_DSA:       return 0;
1536     case PUBKEY_ALGO_ECDH:      return 2;
1537     case PUBKEY_ALGO_ECDSA:     return 0;
1538     case PUBKEY_ALGO_ELGAMAL:   return 2;
1539     case PUBKEY_ALGO_EDDSA:     return 0;
1540     }
1541   return 0;
1542 }
1543
1544
1545 /* Temporary helper. */
1546 unsigned int
1547 pubkey_nbits( int algo, gcry_mpi_t *key )
1548 {
1549     int rc, nbits;
1550     gcry_sexp_t sexp;
1551
1552     if( algo == PUBKEY_ALGO_DSA ) {
1553         rc = gcry_sexp_build ( &sexp, NULL,
1554                               "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1555                                   key[0], key[1], key[2], key[3] );
1556     }
1557     else if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) {
1558         rc = gcry_sexp_build ( &sexp, NULL,
1559                               "(public-key(elg(p%m)(g%m)(y%m)))",
1560                                   key[0], key[1], key[2] );
1561     }
1562     else if( is_RSA (algo) ) {
1563         rc = gcry_sexp_build ( &sexp, NULL,
1564                               "(public-key(rsa(n%m)(e%m)))",
1565                                   key[0], key[1] );
1566     }
1567     else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
1568              || algo == PUBKEY_ALGO_EDDSA) {
1569         char *curve = openpgp_oid_to_str (key[0]);
1570         if (!curve)
1571           rc = gpg_error_from_syserror ();
1572         else
1573           {
1574             rc = gcry_sexp_build (&sexp, NULL,
1575                                   "(public-key(ecc(curve%s)(q%m)))",
1576                                   curve, key[1]);
1577             xfree (curve);
1578           }
1579     }
1580     else
1581         return 0;
1582
1583     if ( rc )
1584         BUG ();
1585
1586     nbits = gcry_pk_get_nbits( sexp );
1587     gcry_sexp_release( sexp );
1588     return nbits;
1589 }
1590
1591
1592
1593 int
1594 mpi_print (estream_t fp, gcry_mpi_t a, int mode)
1595 {
1596   int n=0;
1597
1598   if (!a)
1599     return es_fprintf (fp, "[MPI_NULL]");
1600   if (!mode)
1601     {
1602       unsigned int n1;
1603       n1 = gcry_mpi_get_nbits(a);
1604       n += es_fprintf (fp, "[%u bits]", n1);
1605     }
1606   else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
1607     {
1608       unsigned int nbits;
1609       unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
1610       if (!p)
1611         n += es_fprintf (fp, "[invalid opaque value]");
1612       else
1613         {
1614           nbits = (nbits + 7)/8;
1615           for (; nbits; nbits--, p++)
1616             n += es_fprintf (fp, "%02X", *p);
1617         }
1618     }
1619   else
1620     {
1621       unsigned char *buffer;
1622
1623       if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
1624         BUG ();
1625       es_fputs (buffer, fp);
1626       n += strlen (buffer);
1627       gcry_free (buffer);
1628     }
1629   return n;
1630 }
1631
1632
1633 /* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
1634    i.e.  04 <x> <y> */
1635 unsigned int
1636 ecdsa_qbits_from_Q (unsigned int qbits)
1637 {
1638   if ((qbits%8) > 3)
1639     {
1640       log_error (_("ECDSA public key is expected to be in SEC encoding "
1641                    "multiple of 8 bits\n"));
1642       return 0;
1643     }
1644   qbits -= qbits%8;
1645   qbits /= 2;
1646   return qbits;
1647 }