6d3a7b82ff812ce6261a77b636ce77ab3522ab8a
[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     case CIPHER_ALGO_IDEA:        return GCRY_CIPHER_IDEA;
352     case CIPHER_ALGO_3DES:        return GCRY_CIPHER_3DES;
353     case CIPHER_ALGO_CAST5:       return GCRY_CIPHER_CAST5;
354     case CIPHER_ALGO_BLOWFISH:    return GCRY_CIPHER_BLOWFISH;
355     case CIPHER_ALGO_AES:         return GCRY_CIPHER_AES;
356     case CIPHER_ALGO_AES192:      return GCRY_CIPHER_AES192;
357     case CIPHER_ALGO_AES256:      return GCRY_CIPHER_AES256;
358     case CIPHER_ALGO_TWOFISH:     return GCRY_CIPHER_TWOFISH;
359     case CIPHER_ALGO_CAMELLIA128: return GCRY_CIPHER_CAMELLIA128;
360     case CIPHER_ALGO_CAMELLIA192: return GCRY_CIPHER_CAMELLIA192;
361     case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
362     }
363   return 0;
364 }
365
366 /* The inverse function of above.  */
367 static cipher_algo_t
368 map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
369 {
370   switch (algo)
371     {
372     case GCRY_CIPHER_NONE:        return CIPHER_ALGO_NONE;
373     case GCRY_CIPHER_IDEA:        return CIPHER_ALGO_IDEA;
374     case GCRY_CIPHER_3DES:        return CIPHER_ALGO_3DES;
375     case GCRY_CIPHER_CAST5:       return CIPHER_ALGO_CAST5;
376     case GCRY_CIPHER_BLOWFISH:    return CIPHER_ALGO_BLOWFISH;
377     case GCRY_CIPHER_AES:         return CIPHER_ALGO_AES;
378     case GCRY_CIPHER_AES192:      return CIPHER_ALGO_AES192;
379     case GCRY_CIPHER_AES256:      return CIPHER_ALGO_AES256;
380     case GCRY_CIPHER_TWOFISH:     return CIPHER_ALGO_TWOFISH;
381     case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
382     case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
383     case GCRY_CIPHER_CAMELLIA256: return CIPHER_ALGO_CAMELLIA256;
384     default: return 0;
385     }
386 }
387
388 /* Map Gcrypt public key algorithm numbers to those used by OpenPGP.
389    FIXME: This mapping is used at only two places - we should get rid
390    of it.  */
391 pubkey_algo_t
392 map_pk_gcry_to_openpgp (enum gcry_pk_algos algo)
393 {
394   switch (algo)
395     {
396     case GCRY_PK_ECDSA:  return PUBKEY_ALGO_ECDSA;
397     case GCRY_PK_ECDH:   return PUBKEY_ALGO_ECDH;
398     default: return algo < 110 ? algo : 0;
399     }
400 }
401
402
403 /* Return the block length of an OpenPGP cipher algorithm.  */
404 int
405 openpgp_cipher_blocklen (cipher_algo_t algo)
406 {
407   /* We use the numbers from OpenPGP to be sure that we get the right
408      block length.  This is so that the packet parsing code works even
409      for unknown algorithms (for which we assume 8 due to tradition).
410
411      NOTE: If you change the the returned blocklen above 16, check
412      the callers because they may use a fixed size buffer of that
413      size. */
414   switch (algo)
415     {
416     case CIPHER_ALGO_AES:
417     case CIPHER_ALGO_AES192:
418     case CIPHER_ALGO_AES256:
419     case CIPHER_ALGO_TWOFISH:
420     case CIPHER_ALGO_CAMELLIA128:
421     case CIPHER_ALGO_CAMELLIA192:
422     case CIPHER_ALGO_CAMELLIA256:
423       return 16;
424
425     default:
426       return 8;
427     }
428 }
429
430 /****************
431  * Wrapper around the libgcrypt function with additonal checks on
432  * the OpenPGP contraints for the algo ID.
433  */
434 int
435 openpgp_cipher_test_algo (cipher_algo_t algo)
436 {
437   enum gcry_cipher_algos ga;
438
439   ga = map_cipher_openpgp_to_gcry (algo);
440
441   /* Use this explicit list to disable certain algorithms. */
442   switch (algo)
443     {
444     /* case CIPHER_ALGO_IDEA:         */
445     /*   ga = 0; */
446     /*   break; */
447     default:
448       break;
449     }
450
451   if (!ga)
452     return gpg_error (GPG_ERR_CIPHER_ALGO);
453
454   return gcry_cipher_test_algo (ga);
455 }
456
457 /* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
458    string representation of the algorithm name.  For unknown algorithm
459    IDs this function returns "?".  */
460 const char *
461 openpgp_cipher_algo_name (cipher_algo_t algo)
462 {
463   switch (algo)
464     {
465     case CIPHER_ALGO_NONE:        break;
466     case CIPHER_ALGO_IDEA:        return "IDEA";
467     case CIPHER_ALGO_3DES:        return "3DES";
468     case CIPHER_ALGO_CAST5:       return "CAST5";
469     case CIPHER_ALGO_BLOWFISH:    return "BLOWFISH";
470     case CIPHER_ALGO_AES:         return "AES";
471     case CIPHER_ALGO_AES192:      return "AES192";
472     case CIPHER_ALGO_AES256:      return "AES256";
473     case CIPHER_ALGO_TWOFISH:     return "TWOFISH";
474     case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
475     case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
476     case CIPHER_ALGO_CAMELLIA256: return "CAMELLIA256";
477     }
478   return "?";
479 }
480
481
482 /* Return 0 if ALGO is a supported OpenPGP public key algorithm.  */
483 int
484 openpgp_pk_test_algo (pubkey_algo_t algo)
485 {
486   return openpgp_pk_test_algo2 (algo, 0);
487 }
488
489
490 /* Return 0 if ALGO is a supported OpenPGP public key algorithm and
491    allows the usage USE.  */
492 int
493 openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
494 {
495   enum gcry_pk_algos ga = 0;
496   size_t use_buf = use;
497
498   switch (algo)
499     {
500     case PUBKEY_ALGO_RSA:       ga = GCRY_PK_RSA;   break;
501     case PUBKEY_ALGO_RSA_E:     ga = GCRY_PK_RSA_E; break;
502     case PUBKEY_ALGO_RSA_S:     ga = GCRY_PK_RSA_S; break;
503     case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG;   break;
504     case PUBKEY_ALGO_DSA:       ga = GCRY_PK_DSA;   break;
505
506     case PUBKEY_ALGO_ECDH:
507     case PUBKEY_ALGO_ECDSA:
508     case PUBKEY_ALGO_EDDSA:     ga = GCRY_PK_ECC;   break;
509
510     case PUBKEY_ALGO_ELGAMAL:
511       /* Dont't allow type 20 keys unless in rfc2440 mode.  */
512       if (RFC2440)
513         ga = GCRY_PK_ELG;
514       break;
515     }
516   if (!ga)
517     return gpg_error (GPG_ERR_PUBKEY_ALGO);
518
519   /* No check whether Libgcrypt has support for the algorithm.  */
520   return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
521 }
522
523
524 int
525 openpgp_pk_algo_usage ( int algo )
526 {
527     int use = 0;
528
529     /* They are hardwired in gpg 1.0. */
530     switch ( algo ) {
531       case PUBKEY_ALGO_RSA:
532           use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
533                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
534           break;
535       case PUBKEY_ALGO_RSA_E:
536       case PUBKEY_ALGO_ECDH:
537           use = PUBKEY_USAGE_ENC;
538           break;
539       case PUBKEY_ALGO_RSA_S:
540           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
541           break;
542       case PUBKEY_ALGO_ELGAMAL:
543           if (RFC2440)
544              use = PUBKEY_USAGE_ENC;
545           break;
546       case PUBKEY_ALGO_ELGAMAL_E:
547           use = PUBKEY_USAGE_ENC;
548           break;
549       case PUBKEY_ALGO_DSA:
550           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
551           break;
552       case PUBKEY_ALGO_ECDSA:
553       case PUBKEY_ALGO_EDDSA:
554           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
555       default:
556           break;
557     }
558     return use;
559 }
560
561 /* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
562    string representation of the algorithm name.  For unknown algorithm
563    IDs this function returns "?".  */
564 const char *
565 openpgp_pk_algo_name (pubkey_algo_t algo)
566 {
567   switch (algo)
568     {
569     case PUBKEY_ALGO_RSA:
570     case PUBKEY_ALGO_RSA_E:
571     case PUBKEY_ALGO_RSA_S:     return "RSA";
572     case PUBKEY_ALGO_ELGAMAL:
573     case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
574     case PUBKEY_ALGO_DSA:       return "DSA";
575     case PUBKEY_ALGO_ECDH:      return "ECDH";
576     case PUBKEY_ALGO_ECDSA:     return "ECDSA";
577     case PUBKEY_ALGO_EDDSA:     return "EDDSA";
578     }
579   return "?";
580 }
581
582
583 /* Explicit mapping of OpenPGP digest algos to Libgcrypt.  */
584 /* FIXME: We do not yes use it everywhere.  */
585 enum gcry_md_algos
586 map_md_openpgp_to_gcry (digest_algo_t algo)
587 {
588   switch (algo)
589     {
590     case DIGEST_ALGO_MD5:    return GCRY_MD_MD5;
591     case DIGEST_ALGO_SHA1:   return GCRY_MD_SHA1;
592     case DIGEST_ALGO_RMD160: return GCRY_MD_RMD160;
593     case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
594     case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
595     case DIGEST_ALGO_SHA384: return GCRY_MD_SHA384;
596     case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
597     }
598   return 0;
599 }
600
601
602 /* Return 0 if ALGO is suitable and implemented OpenPGP hash
603    algorithm.  Note: To only test for a valid OpenPGP hash algorithm,
604    it is better to use map_md_openpgp_to_gcry. */
605 int
606 openpgp_md_test_algo (digest_algo_t algo)
607 {
608   enum gcry_md_algos ga;
609
610   ga = map_md_openpgp_to_gcry (algo);
611   switch (algo)
612     {
613     default:
614       break;
615     }
616   if (!ga)
617     return gpg_error (GPG_ERR_DIGEST_ALGO);
618
619   return gcry_md_test_algo (ga);
620 }
621
622
623 /* Map the OpenPGP digest algorithm whose ID is contained in ALGO to a
624    string representation of the algorithm name.  For unknown algorithm
625    IDs this function returns "?".  */
626 const char *
627 openpgp_md_algo_name (int algo)
628 {
629   switch (algo)
630     {
631     case DIGEST_ALGO_MD5:    return "MD5";
632     case DIGEST_ALGO_SHA1:   return "SHA1";
633     case DIGEST_ALGO_RMD160: return "RIPEMD160";
634     case DIGEST_ALGO_SHA256: return "SHA256";
635     case DIGEST_ALGO_SHA384: return "SHA384";
636     case DIGEST_ALGO_SHA512: return "SHA512";
637     case DIGEST_ALGO_SHA224: return "SHA224";
638     }
639   return "?";
640 }
641
642
643 static unsigned long
644 get_signature_count (PKT_public_key *pk)
645 {
646 #ifdef ENABLE_CARD_SUPPORT
647   struct agent_card_info_s info;
648
649   (void)pk;
650   if (!agent_scd_getattr ("SIG-COUNTER",&info))
651     return info.sig_counter;
652   else
653     return 0;
654 #else
655   (void)pk;
656   return 0;
657 #endif
658 }
659
660 /* Expand %-strings.  Returns a string which must be xfreed.  Returns
661    NULL if the string cannot be expanded (too large). */
662 char *
663 pct_expando(const char *string,struct expando_args *args)
664 {
665   const char *ch=string;
666   int idx=0,maxlen=0,done=0;
667   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
668   char *ret=NULL;
669
670   if(args->pk)
671     keyid_from_pk(args->pk,pk_keyid);
672
673   if(args->pksk)
674     keyid_from_pk (args->pksk, sk_keyid);
675
676   /* This is used so that %k works in photoid command strings in
677      --list-secret-keys (which of course has a sk, but no pk). */
678   if(!args->pk && args->pksk)
679     keyid_from_pk (args->pksk, pk_keyid);
680
681   while(*ch!='\0')
682     {
683       if(!done)
684         {
685           /* 8192 is way bigger than we'll need here */
686           if(maxlen>=8192)
687             goto fail;
688
689           maxlen+=1024;
690           ret=xrealloc(ret,maxlen);
691         }
692
693       done=0;
694
695       if(*ch=='%')
696         {
697           switch(*(ch+1))
698             {
699             case 's': /* short key id */
700               if(idx+8<maxlen)
701                 {
702                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
703                   idx+=8;
704                   done=1;
705                 }
706               break;
707
708             case 'S': /* long key id */
709               if(idx+16<maxlen)
710                 {
711                   sprintf(&ret[idx],"%08lX%08lX",
712                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
713                   idx+=16;
714                   done=1;
715                 }
716               break;
717
718             case 'k': /* short key id */
719               if(idx+8<maxlen)
720                 {
721                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
722                   idx+=8;
723                   done=1;
724                 }
725               break;
726
727             case 'K': /* long key id */
728               if(idx+16<maxlen)
729                 {
730                   sprintf(&ret[idx],"%08lX%08lX",
731                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
732                   idx+=16;
733                   done=1;
734                 }
735               break;
736
737             case 'c': /* signature count from card, if any. */
738               if(idx+10<maxlen)
739                 {
740                   sprintf (&ret[idx],"%lu", get_signature_count (args->pksk));
741                   idx+=strlen(&ret[idx]);
742                   done=1;
743                 }
744               break;
745
746             case 'p': /* primary pk fingerprint of a sk */
747             case 'f': /* pk fingerprint */
748             case 'g': /* sk fingerprint */
749               {
750                 byte array[MAX_FINGERPRINT_LEN];
751                 size_t len;
752                 int i;
753
754                 if((*(ch+1))=='p' && args->pksk)
755                   {
756                     if(args->pksk->flags.primary)
757                       fingerprint_from_pk (args->pksk, array, &len);
758                     else if (args->pksk->main_keyid[0]
759                              || args->pksk->main_keyid[1])
760                       {
761                         /* FIXME: Document teh code and check whether
762                            it is still needed.  */
763                         PKT_public_key *pk=
764                           xmalloc_clear(sizeof(PKT_public_key));
765
766                         if (!get_pubkey_fast (pk,args->pksk->main_keyid))
767                           fingerprint_from_pk (pk, array, &len);
768                         else
769                           memset (array, 0, (len=MAX_FINGERPRINT_LEN));
770                         free_public_key (pk);
771                       }
772                     else
773                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
774                   }
775                 else if((*(ch+1))=='f' && args->pk)
776                   fingerprint_from_pk (args->pk, array, &len);
777                 else if((*(ch+1))=='g' && args->pksk)
778                   fingerprint_from_pk (args->pksk, array, &len);
779                 else
780                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
781
782                 if(idx+(len*2)<maxlen)
783                   {
784                     for(i=0;i<len;i++)
785                       {
786                         sprintf(&ret[idx],"%02X",array[i]);
787                         idx+=2;
788                       }
789                     done=1;
790                   }
791               }
792               break;
793
794             case 'v': /* validity letters */
795               if(args->validity_info && idx+1<maxlen)
796                 {
797                   ret[idx++]=args->validity_info;
798                   ret[idx]='\0';
799                   done=1;
800                 }
801               break;
802
803               /* The text string types */
804             case 't':
805             case 'T':
806             case 'V':
807               {
808                 const char *str=NULL;
809
810                 switch(*(ch+1))
811                   {
812                   case 't': /* e.g. "jpg" */
813                     str=image_type_to_string(args->imagetype,0);
814                     break;
815
816                   case 'T': /* e.g. "image/jpeg" */
817                     str=image_type_to_string(args->imagetype,2);
818                     break;
819
820                   case 'V': /* e.g. "full", "expired", etc. */
821                     str=args->validity_string;
822                     break;
823                   }
824
825                 if(str && idx+strlen(str)<maxlen)
826                   {
827                     strcpy(&ret[idx],str);
828                     idx+=strlen(str);
829                     done=1;
830                   }
831               }
832               break;
833
834             case '%':
835               if(idx+1<maxlen)
836                 {
837                   ret[idx++]='%';
838                   ret[idx]='\0';
839                   done=1;
840                 }
841               break;
842
843               /* Any unknown %-keys (like %i, %o, %I, and %O) are
844                  passed through for later expansion.  Note this also
845                  handles the case where the last character in the
846                  string is a '%' - the terminating \0 will end up here
847                  and properly terminate the string. */
848             default:
849               if(idx+2<maxlen)
850                 {
851                   ret[idx++]='%';
852                   ret[idx++]=*(ch+1);
853                   ret[idx]='\0';
854                   done=1;
855                 }
856               break;
857               }
858
859           if(done)
860             ch++;
861         }
862       else
863         {
864           if(idx+1<maxlen)
865             {
866               ret[idx++]=*ch;
867               ret[idx]='\0';
868               done=1;
869             }
870         }
871
872       if(done)
873         ch++;
874     }
875
876   return ret;
877
878  fail:
879   xfree(ret);
880   return NULL;
881 }
882
883 void
884 deprecated_warning(const char *configname,unsigned int configlineno,
885                    const char *option,const char *repl1,const char *repl2)
886 {
887   if(configname)
888     {
889       if(strncmp("--",option,2)==0)
890         option+=2;
891
892       if(strncmp("--",repl1,2)==0)
893         repl1+=2;
894
895       log_info(_("%s:%d: deprecated option \"%s\"\n"),
896                configname,configlineno,option);
897     }
898   else
899     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
900
901   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
902 }
903
904
905 void
906 deprecated_command (const char *name)
907 {
908   log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
909            name);
910 }
911
912
913 void
914 obsolete_option (const char *configname, unsigned int configlineno,
915                  const char *name)
916 {
917   if(configname)
918     log_info (_("%s:%u: obsolete option \"%s\" - it has no effect\n"),
919               configname, configlineno, name);
920   else
921     log_info (_("WARNING: \"%s\" is an obsolete option - it has no effect\n"),
922               name);
923 }
924
925
926 /*
927  * Wrapper around gcry_cipher_map_name to provide a fallback using the
928  * "Sn" syntax as used by the preference strings.
929  */
930 int
931 string_to_cipher_algo (const char *string)
932 {
933   int val;
934
935   val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
936   if (!val && string && (string[0]=='S' || string[0]=='s'))
937     {
938       char *endptr;
939
940       string++;
941       val = strtol (string, &endptr, 10);
942       if (!*string || *endptr || openpgp_cipher_test_algo (val))
943         val = 0;
944     }
945
946   return val;
947 }
948
949 /*
950  * Wrapper around gcry_md_map_name to provide a fallback using the
951  * "Hn" syntax as used by the preference strings.
952  */
953 int
954 string_to_digest_algo (const char *string)
955 {
956   int val;
957
958   /* FIXME: We should make use of our wrapper fucntion and not assume
959      that there is a 1 to 1 mapping between OpenPGP and Libgcrypt.  */
960   val = gcry_md_map_name (string);
961   if (!val && string && (string[0]=='H' || string[0]=='h'))
962     {
963       char *endptr;
964
965       string++;
966       val = strtol (string, &endptr, 10);
967       if (!*string || *endptr || openpgp_md_test_algo (val))
968         val = 0;
969     }
970
971   return val;
972 }
973
974
975
976 const char *
977 compress_algo_to_string(int algo)
978 {
979   const char *s=NULL;
980
981   switch(algo)
982     {
983     case COMPRESS_ALGO_NONE:
984       s=_("Uncompressed");
985       break;
986
987     case COMPRESS_ALGO_ZIP:
988       s="ZIP";
989       break;
990
991     case COMPRESS_ALGO_ZLIB:
992       s="ZLIB";
993       break;
994
995 #ifdef HAVE_BZIP2
996     case COMPRESS_ALGO_BZIP2:
997       s="BZIP2";
998       break;
999 #endif
1000     }
1001
1002   return s;
1003 }
1004
1005 int
1006 string_to_compress_algo(const char *string)
1007 {
1008   /* TRANSLATORS: See doc/TRANSLATE about this string. */
1009   if(match_multistr(_("uncompressed|none"),string))
1010     return 0;
1011   else if(ascii_strcasecmp(string,"uncompressed")==0)
1012     return 0;
1013   else if(ascii_strcasecmp(string,"none")==0)
1014     return 0;
1015   else if(ascii_strcasecmp(string,"zip")==0)
1016     return 1;
1017   else if(ascii_strcasecmp(string,"zlib")==0)
1018     return 2;
1019 #ifdef HAVE_BZIP2
1020   else if(ascii_strcasecmp(string,"bzip2")==0)
1021     return 3;
1022 #endif
1023   else if(ascii_strcasecmp(string,"z0")==0)
1024     return 0;
1025   else if(ascii_strcasecmp(string,"z1")==0)
1026     return 1;
1027   else if(ascii_strcasecmp(string,"z2")==0)
1028     return 2;
1029 #ifdef HAVE_BZIP2
1030   else if(ascii_strcasecmp(string,"z3")==0)
1031     return 3;
1032 #endif
1033   else
1034     return -1;
1035 }
1036
1037 int
1038 check_compress_algo(int algo)
1039 {
1040   switch (algo)
1041     {
1042     case 0: return 0;
1043 #ifdef HAVE_ZIP
1044     case 1:
1045     case 2: return 0;
1046 #endif
1047 #ifdef HAVE_BZIP2
1048     case 3: return 0;
1049 #endif
1050     default: return G10ERR_COMPR_ALGO;
1051     }
1052 }
1053
1054 int
1055 default_cipher_algo(void)
1056 {
1057   if(opt.def_cipher_algo)
1058     return opt.def_cipher_algo;
1059   else if(opt.personal_cipher_prefs)
1060     return opt.personal_cipher_prefs[0].value;
1061   else
1062     return opt.s2k_cipher_algo;
1063 }
1064
1065 /* There is no default_digest_algo function, but see
1066    sign.c:hash_for() */
1067
1068 int
1069 default_compress_algo(void)
1070 {
1071   if(opt.compress_algo!=-1)
1072     return opt.compress_algo;
1073   else if(opt.personal_compress_prefs)
1074     return opt.personal_compress_prefs[0].value;
1075   else
1076     return DEFAULT_COMPRESS_ALGO;
1077 }
1078
1079 const char *
1080 compliance_option_string(void)
1081 {
1082   char *ver="???";
1083
1084   switch(opt.compliance)
1085     {
1086     case CO_GNUPG:   return "--gnupg";
1087     case CO_RFC4880: return "--openpgp";
1088     case CO_RFC2440: return "--rfc2440";
1089     case CO_RFC1991: return "--rfc1991";
1090     case CO_PGP2:    return "--pgp2";
1091     case CO_PGP6:    return "--pgp6";
1092     case CO_PGP7:    return "--pgp7";
1093     case CO_PGP8:    return "--pgp8";
1094     }
1095
1096   return ver;
1097 }
1098
1099 void
1100 compliance_failure(void)
1101 {
1102   char *ver="???";
1103
1104   switch(opt.compliance)
1105     {
1106     case CO_GNUPG:
1107       ver="GnuPG";
1108       break;
1109
1110     case CO_RFC4880:
1111       ver="OpenPGP";
1112       break;
1113
1114     case CO_RFC2440:
1115       ver="OpenPGP (older)";
1116       break;
1117
1118     case CO_RFC1991:
1119       ver="old PGP";
1120       break;
1121
1122     case CO_PGP2:
1123       ver="PGP 2.x";
1124       break;
1125
1126     case CO_PGP6:
1127       ver="PGP 6.x";
1128       break;
1129
1130     case CO_PGP7:
1131       ver="PGP 7.x";
1132       break;
1133
1134     case CO_PGP8:
1135       ver="PGP 8.x";
1136       break;
1137     }
1138
1139   log_info(_("this message may not be usable by %s\n"),ver);
1140   opt.compliance=CO_GNUPG;
1141 }
1142
1143 /* Break a string into successive option pieces.  Accepts single word
1144    options and key=value argument options. */
1145 char *
1146 optsep(char **stringp)
1147 {
1148   char *tok,*end;
1149
1150   tok=*stringp;
1151   if(tok)
1152     {
1153       end=strpbrk(tok," ,=");
1154       if(end)
1155         {
1156           int sawequals=0;
1157           char *ptr=end;
1158
1159           /* what we need to do now is scan along starting with *end,
1160              If the next character we see (ignoring spaces) is an =
1161              sign, then there is an argument. */
1162
1163           while(*ptr)
1164             {
1165               if(*ptr=='=')
1166                 sawequals=1;
1167               else if(*ptr!=' ')
1168                 break;
1169               ptr++;
1170             }
1171
1172           /* There is an argument, so grab that too.  At this point,
1173              ptr points to the first character of the argument. */
1174           if(sawequals)
1175             {
1176               /* Is it a quoted argument? */
1177               if(*ptr=='"')
1178                 {
1179                   ptr++;
1180                   end=strchr(ptr,'"');
1181                   if(end)
1182                     end++;
1183                 }
1184               else
1185                 end=strpbrk(ptr," ,");
1186             }
1187
1188           if(end && *end)
1189             {
1190               *end='\0';
1191               *stringp=end+1;
1192             }
1193           else
1194             *stringp=NULL;
1195         }
1196       else
1197         *stringp=NULL;
1198     }
1199
1200   return tok;
1201 }
1202
1203 /* Breaks an option value into key and value.  Returns NULL if there
1204    is no value.  Note that "string" is modified to remove the =value
1205    part. */
1206 char *
1207 argsplit(char *string)
1208 {
1209   char *equals,*arg=NULL;
1210
1211   equals=strchr(string,'=');
1212   if(equals)
1213     {
1214       char *quote,*space;
1215
1216       *equals='\0';
1217       arg=equals+1;
1218
1219       /* Quoted arg? */
1220       quote=strchr(arg,'"');
1221       if(quote)
1222         {
1223           arg=quote+1;
1224
1225           quote=strchr(arg,'"');
1226           if(quote)
1227             *quote='\0';
1228         }
1229       else
1230         {
1231           size_t spaces;
1232
1233           /* Trim leading spaces off of the arg */
1234           spaces=strspn(arg," ");
1235           arg+=spaces;
1236         }
1237
1238       /* Trim tailing spaces off of the tag */
1239       space=strchr(string,' ');
1240       if(space)
1241         *space='\0';
1242     }
1243
1244   return arg;
1245 }
1246
1247 /* Return the length of the initial token, leaving off any
1248    argument. */
1249 static size_t
1250 optlen(const char *s)
1251 {
1252   char *end=strpbrk(s," =");
1253
1254   if(end)
1255     return end-s;
1256   else
1257     return strlen(s);
1258 }
1259
1260 int
1261 parse_options(char *str,unsigned int *options,
1262               struct parse_options *opts,int noisy)
1263 {
1264   char *tok;
1265
1266   if (str && !strcmp (str, "help"))
1267     {
1268       int i,maxlen=0;
1269
1270       /* Figure out the longest option name so we can line these up
1271          neatly. */
1272       for(i=0;opts[i].name;i++)
1273         if(opts[i].help && maxlen<strlen(opts[i].name))
1274           maxlen=strlen(opts[i].name);
1275
1276       for(i=0;opts[i].name;i++)
1277         if(opts[i].help)
1278           printf("%s%*s%s\n",opts[i].name,
1279                  maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
1280
1281       g10_exit(0);
1282     }
1283
1284   while((tok=optsep(&str)))
1285     {
1286       int i,rev=0;
1287       char *otok=tok;
1288
1289       if(tok[0]=='\0')
1290         continue;
1291
1292       if(ascii_strncasecmp("no-",tok,3)==0)
1293         {
1294           rev=1;
1295           tok+=3;
1296         }
1297
1298       for(i=0;opts[i].name;i++)
1299         {
1300           size_t toklen=optlen(tok);
1301
1302           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1303             {
1304               /* We have a match, but it might be incomplete */
1305               if(toklen!=strlen(opts[i].name))
1306                 {
1307                   int j;
1308
1309                   for(j=i+1;opts[j].name;j++)
1310                     {
1311                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1312                         {
1313                           if(noisy)
1314                             log_info(_("ambiguous option '%s'\n"),otok);
1315                           return 0;
1316                         }
1317                     }
1318                 }
1319
1320               if(rev)
1321                 {
1322                   *options&=~opts[i].bit;
1323                   if(opts[i].value)
1324                     *opts[i].value=NULL;
1325                 }
1326               else
1327                 {
1328                   *options|=opts[i].bit;
1329                   if(opts[i].value)
1330                     *opts[i].value=argsplit(tok);
1331                 }
1332               break;
1333             }
1334         }
1335
1336       if(!opts[i].name)
1337         {
1338           if(noisy)
1339             log_info(_("unknown option '%s'\n"),otok);
1340           return 0;
1341         }
1342     }
1343
1344   return 1;
1345 }
1346
1347
1348 /* Check whether the string has characters not valid in an RFC-822
1349    address.  To cope with OpenPGP we ignore non-ascii characters
1350    so that for example umlauts are legal in an email address.  An
1351    OpenPGP user ID must be utf-8 encoded but there is no strict
1352    requirement for RFC-822.  Thus to avoid IDNA encoding we put the
1353    address verbatim as utf-8 into the user ID under the assumption
1354    that mail programs handle IDNA at a lower level and take OpenPGP
1355    user IDs as utf-8.  Note that we can't do an utf-8 encoding
1356    checking here because in keygen.c this function is called with the
1357    native encoding and native to utf-8 encoding is only done  later.  */
1358 int
1359 has_invalid_email_chars (const char *s)
1360 {
1361   int at_seen=0;
1362   const char *valid_chars=
1363     "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1364
1365   for ( ; *s; s++ )
1366     {
1367       if ( (*s & 0x80) )
1368         continue; /* We only care about ASCII.  */
1369       if ( *s == '@' )
1370         at_seen=1;
1371       else if ( !at_seen && !(strchr (valid_chars, *s)
1372                               || strchr ("!#$%&'*+/=?^`{|}~", *s)))
1373         return 1;
1374       else if ( at_seen && !strchr( valid_chars, *s ) )
1375         return 1;
1376     }
1377   return 0;
1378 }
1379
1380
1381 /* Check whether NAME represents a valid mailbox according to
1382    RFC822. Returns true if so. */
1383 int
1384 is_valid_mailbox (const char *name)
1385 {
1386   return !( !name
1387             || !*name
1388             || has_invalid_email_chars (name)
1389             || string_count_chr (name,'@') != 1
1390             || *name == '@'
1391             || name[strlen(name)-1] == '@'
1392             || name[strlen(name)-1] == '.'
1393             || strstr (name, "..") );
1394 }
1395
1396
1397 /* Similar to access(2), but uses PATH to find the file. */
1398 int
1399 path_access(const char *file,int mode)
1400 {
1401   char *envpath;
1402   int ret=-1;
1403
1404   envpath=getenv("PATH");
1405
1406   if(!envpath
1407 #ifdef HAVE_DRIVE_LETTERS
1408      || (((file[0]>='A' && file[0]<='Z')
1409           || (file[0]>='a' && file[0]<='z'))
1410          && file[1]==':')
1411 #else
1412      || file[0]=='/'
1413 #endif
1414      )
1415     return access(file,mode);
1416   else
1417     {
1418       /* At least as large as, but most often larger than we need. */
1419       char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1420       char *split,*item,*path=xstrdup(envpath);
1421
1422       split=path;
1423
1424       while((item=strsep(&split,PATHSEP_S)))
1425         {
1426           strcpy(buffer,item);
1427           strcat(buffer,"/");
1428           strcat(buffer,file);
1429           ret=access(buffer,mode);
1430           if(ret==0)
1431             break;
1432         }
1433
1434       xfree(path);
1435       xfree(buffer);
1436     }
1437
1438   return ret;
1439 }
1440
1441
1442 \f
1443 /* Return the number of public key parameters as used by OpenPGP.  */
1444 int
1445 pubkey_get_npkey (pubkey_algo_t algo)
1446 {
1447   switch (algo)
1448     {
1449     case PUBKEY_ALGO_RSA:
1450     case PUBKEY_ALGO_RSA_E:
1451     case PUBKEY_ALGO_RSA_S:     return 2;
1452     case PUBKEY_ALGO_ELGAMAL_E: return 3;
1453     case PUBKEY_ALGO_DSA:       return 4;
1454     case PUBKEY_ALGO_ECDH:      return 3;
1455     case PUBKEY_ALGO_ECDSA:     return 2;
1456     case PUBKEY_ALGO_ELGAMAL:   return 3;
1457     case PUBKEY_ALGO_EDDSA:     return 2;
1458     }
1459   return 0;
1460 }
1461
1462
1463 /* Return the number of secret key parameters as used by OpenPGP.  */
1464 int
1465 pubkey_get_nskey (pubkey_algo_t algo)
1466 {
1467   switch (algo)
1468     {
1469     case PUBKEY_ALGO_RSA:
1470     case PUBKEY_ALGO_RSA_E:
1471     case PUBKEY_ALGO_RSA_S:     return 6;
1472     case PUBKEY_ALGO_ELGAMAL_E: return 4;
1473     case PUBKEY_ALGO_DSA:       return 5;
1474     case PUBKEY_ALGO_ECDH:      return 4;
1475     case PUBKEY_ALGO_ECDSA:     return 3;
1476     case PUBKEY_ALGO_ELGAMAL:   return 4;
1477     case PUBKEY_ALGO_EDDSA:     return 3;
1478     }
1479   return 0;
1480 }
1481
1482 /* Temporary helper. */
1483 int
1484 pubkey_get_nsig (pubkey_algo_t algo)
1485 {
1486   switch (algo)
1487     {
1488     case PUBKEY_ALGO_RSA:
1489     case PUBKEY_ALGO_RSA_E:
1490     case PUBKEY_ALGO_RSA_S:     return 1;
1491     case PUBKEY_ALGO_ELGAMAL_E: return 0;
1492     case PUBKEY_ALGO_DSA:       return 2;
1493     case PUBKEY_ALGO_ECDH:      return 0;
1494     case PUBKEY_ALGO_ECDSA:     return 2;
1495     case PUBKEY_ALGO_ELGAMAL:   return 2;
1496     case PUBKEY_ALGO_EDDSA:     return 2;
1497     }
1498   return 0;
1499 }
1500
1501
1502 /* Temporary helper. */
1503 int
1504 pubkey_get_nenc (pubkey_algo_t algo)
1505 {
1506   switch (algo)
1507     {
1508     case PUBKEY_ALGO_RSA:
1509     case PUBKEY_ALGO_RSA_E:
1510     case PUBKEY_ALGO_RSA_S:     return 1;
1511     case PUBKEY_ALGO_ELGAMAL_E: return 2;
1512     case PUBKEY_ALGO_DSA:       return 0;
1513     case PUBKEY_ALGO_ECDH:      return 2;
1514     case PUBKEY_ALGO_ECDSA:     return 0;
1515     case PUBKEY_ALGO_ELGAMAL:   return 2;
1516     case PUBKEY_ALGO_EDDSA:     return 0;
1517     }
1518   return 0;
1519 }
1520
1521
1522 /* Temporary helper. */
1523 unsigned int
1524 pubkey_nbits( int algo, gcry_mpi_t *key )
1525 {
1526     int rc, nbits;
1527     gcry_sexp_t sexp;
1528
1529     if( algo == PUBKEY_ALGO_DSA ) {
1530         rc = gcry_sexp_build ( &sexp, NULL,
1531                               "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1532                                   key[0], key[1], key[2], key[3] );
1533     }
1534     else if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) {
1535         rc = gcry_sexp_build ( &sexp, NULL,
1536                               "(public-key(elg(p%m)(g%m)(y%m)))",
1537                                   key[0], key[1], key[2] );
1538     }
1539     else if( is_RSA (algo) ) {
1540         rc = gcry_sexp_build ( &sexp, NULL,
1541                               "(public-key(rsa(n%m)(e%m)))",
1542                                   key[0], key[1] );
1543     }
1544     else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
1545              || algo == PUBKEY_ALGO_EDDSA) {
1546         char *curve = openpgp_oid_to_str (key[0]);
1547         if (!curve)
1548           rc = gpg_error_from_syserror ();
1549         else
1550           {
1551             rc = gcry_sexp_build (&sexp, NULL,
1552                                   "(public-key(ecc(curve%s)(q%m)))",
1553                                   curve, key[1]);
1554             xfree (curve);
1555           }
1556     }
1557     else
1558         return 0;
1559
1560     if ( rc )
1561         BUG ();
1562
1563     nbits = gcry_pk_get_nbits( sexp );
1564     gcry_sexp_release( sexp );
1565     return nbits;
1566 }
1567
1568
1569
1570 int
1571 mpi_print (estream_t fp, gcry_mpi_t a, int mode)
1572 {
1573   int n=0;
1574
1575   if (!a)
1576     return es_fprintf (fp, "[MPI_NULL]");
1577   if (!mode)
1578     {
1579       unsigned int n1;
1580       n1 = gcry_mpi_get_nbits(a);
1581       n += es_fprintf (fp, "[%u bits]", n1);
1582     }
1583   else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
1584     {
1585       unsigned int nbits;
1586       unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
1587       if (!p)
1588         n += es_fprintf (fp, "[invalid opaque value]");
1589       else
1590         {
1591           nbits = (nbits + 7)/8;
1592           for (; nbits; nbits--, p++)
1593             n += es_fprintf (fp, "%02X", *p);
1594         }
1595     }
1596   else
1597     {
1598       unsigned char *buffer;
1599
1600       if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
1601         BUG ();
1602       es_fputs (buffer, fp);
1603       n += strlen (buffer);
1604       gcry_free (buffer);
1605     }
1606   return n;
1607 }
1608
1609
1610 /* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
1611    i.e.  04 <x> <y> */
1612 unsigned int
1613 ecdsa_qbits_from_Q (unsigned int qbits)
1614 {
1615   if ((qbits%8) > 3)
1616     {
1617       log_error (_("ECDSA public key is expected to be in SEC encoding "
1618                    "multiple of 8 bits\n"));
1619       return 0;
1620     }
1621   qbits -= qbits%8;
1622   qbits /= 2;
1623   return qbits;
1624 }