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