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