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 <https://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 1324 : 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 1324 : }
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 2223 : 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 2223 : 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 779 : 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 779 : 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 396 : print_pubkey_algo_note (pubkey_algo_t algo)
271 : {
272 396 : 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 396 : 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 396 : }
289 :
290 : void
291 302 : print_cipher_algo_note (cipher_algo_t algo)
292 : {
293 302 : 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 302 : }
305 :
306 : void
307 141 : print_digest_algo_note (digest_algo_t algo)
308 : {
309 141 : const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo);
310 : const struct weakhash *weak;
311 :
312 141 : 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 282 : for (weak = opt.weak_digests; weak != NULL; weak = weak->next)
325 141 : 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 141 : }
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 94301 : map_cipher_openpgp_to_gcry (cipher_algo_t algo)
410 : {
411 94301 : switch (algo)
412 : {
413 6 : case CIPHER_ALGO_NONE: return GCRY_CIPHER_NONE;
414 :
415 : #ifdef GPG_USE_IDEA
416 794 : case CIPHER_ALGO_IDEA: return GCRY_CIPHER_IDEA;
417 : #else
418 : case CIPHER_ALGO_IDEA: return 0;
419 : #endif
420 :
421 387 : case CIPHER_ALGO_3DES: return GCRY_CIPHER_3DES;
422 :
423 : #ifdef GPG_USE_CAST5
424 1023 : 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 200 : 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 430 : 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 331 : 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 89761 : 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 202 : 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 191 : 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 191 : 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 191 : case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
473 : #else
474 : case CIPHER_ALGO_CAMELLIA256: return 0;
475 : #endif
476 : }
477 594 : return 0;
478 : }
479 :
480 : /* The inverse function of above. */
481 : static cipher_algo_t
482 247 : map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
483 : {
484 247 : switch (algo)
485 : {
486 48 : case GCRY_CIPHER_NONE: return CIPHER_ALGO_NONE;
487 19 : case GCRY_CIPHER_IDEA: return CIPHER_ALGO_IDEA;
488 18 : case GCRY_CIPHER_3DES: return CIPHER_ALGO_3DES;
489 18 : case GCRY_CIPHER_CAST5: return CIPHER_ALGO_CAST5;
490 18 : case GCRY_CIPHER_BLOWFISH: return CIPHER_ALGO_BLOWFISH;
491 18 : case GCRY_CIPHER_AES: return CIPHER_ALGO_AES;
492 18 : case GCRY_CIPHER_AES192: return CIPHER_ALGO_AES192;
493 18 : case GCRY_CIPHER_AES256: return CIPHER_ALGO_AES256;
494 18 : case GCRY_CIPHER_TWOFISH: return CIPHER_ALGO_TWOFISH;
495 18 : case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
496 18 : case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
497 18 : 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 33 : 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 33 : 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 27 : 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 3246 : openpgp_cipher_test_algo (cipher_algo_t algo)
550 : {
551 : enum gcry_cipher_algos ga;
552 :
553 3246 : ga = map_cipher_openpgp_to_gcry (algo);
554 3246 : if (!ga)
555 600 : return gpg_error (GPG_ERR_CIPHER_ALGO);
556 :
557 2646 : 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 349 : openpgp_cipher_algo_name (cipher_algo_t algo)
565 : {
566 349 : switch (algo)
567 : {
568 0 : case CIPHER_ALGO_NONE: break;
569 12 : case CIPHER_ALGO_IDEA: return "IDEA";
570 12 : case CIPHER_ALGO_3DES: return "3DES";
571 14 : case CIPHER_ALGO_CAST5: return "CAST5";
572 38 : case CIPHER_ALGO_BLOWFISH: return "BLOWFISH";
573 63 : case CIPHER_ALGO_AES: return "AES";
574 24 : case CIPHER_ALGO_AES192: return "AES192";
575 34 : case CIPHER_ALGO_AES256: return "AES256";
576 38 : case CIPHER_ALGO_TWOFISH: return "TWOFISH";
577 38 : case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
578 38 : case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
579 38 : 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 5732 : openpgp_pk_test_algo (pubkey_algo_t algo)
588 : {
589 5732 : 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 6378 : openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
597 : {
598 6378 : enum gcry_pk_algos ga = 0;
599 6378 : size_t use_buf = use;
600 :
601 6378 : switch (algo)
602 : {
603 : #ifdef GPG_USE_RSA
604 2479 : 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 2237 : case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG; break;
614 874 : case PUBKEY_ALGO_DSA: ga = GCRY_PK_DSA; break;
615 :
616 : #ifdef GPG_USE_ECDH
617 264 : 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 82 : 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 30 : 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 4 : if (RFC2440)
637 0 : ga = GCRY_PK_ELG;
638 4 : break;
639 : }
640 6378 : if (!ga)
641 412 : return gpg_error (GPG_ERR_PUBKEY_ALGO);
642 :
643 : /* No check whether Libgcrypt has support for the algorithm. */
644 5966 : return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
645 : }
646 :
647 :
648 : int
649 5393 : openpgp_pk_algo_usage ( int algo )
650 : {
651 5393 : int use = 0;
652 :
653 : /* They are hardwired in gpg 1.0. */
654 5393 : switch ( algo ) {
655 : case PUBKEY_ALGO_RSA:
656 1413 : use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
657 : | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
658 1413 : 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 1775 : use = PUBKEY_USAGE_ENC;
672 1775 : break;
673 : case PUBKEY_ALGO_DSA:
674 1775 : use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
675 1775 : 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 5393 : 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 962 : openpgp_pk_algo_name (pubkey_algo_t algo)
690 : {
691 962 : switch (algo)
692 : {
693 : case PUBKEY_ALGO_RSA:
694 : case PUBKEY_ALGO_RSA_E:
695 103 : case PUBKEY_ALGO_RSA_S: return "RSA";
696 : case PUBKEY_ALGO_ELGAMAL:
697 490 : case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
698 229 : case PUBKEY_ALGO_DSA: return "DSA";
699 70 : case PUBKEY_ALGO_ECDH: return "ECDH";
700 64 : case PUBKEY_ALGO_ECDSA: return "ECDSA";
701 6 : 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 17660 : map_md_openpgp_to_gcry (digest_algo_t algo)
711 : {
712 17660 : 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 1083 : case DIGEST_ALGO_SHA1: return GCRY_MD_SHA1;
721 :
722 : #ifdef GPG_USE_RMD160
723 173 : 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 161 : case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
730 : #else
731 : case DIGEST_ALGO_SHA224: return 0;
732 : #endif
733 :
734 1785 : case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
735 :
736 : #ifdef GPG_USE_SHA384
737 201 : 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 205 : case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
744 : #else
745 : case DIGEST_ALGO_SHA512: return 0;
746 : #endif
747 : }
748 13909 : return 0;
749 : }
750 :
751 :
752 : /* Return 0 if ALGO is suitable and implemented OpenPGP hash
753 : algorithm. */
754 : int
755 2926 : openpgp_md_test_algo (digest_algo_t algo)
756 : {
757 : enum gcry_md_algos ga;
758 :
759 2926 : ga = map_md_openpgp_to_gcry (algo);
760 2926 : if (!ga)
761 416 : return gpg_error (GPG_ERR_DIGEST_ALGO);
762 :
763 2510 : 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 55 : openpgp_md_algo_name (int algo)
772 : {
773 55 : switch (algo)
774 : {
775 0 : case DIGEST_ALGO_MD5: return "MD5";
776 35 : case DIGEST_ALGO_SHA1: return "SHA1";
777 4 : case DIGEST_ALGO_RMD160: return "RIPEMD160";
778 4 : case DIGEST_ALGO_SHA256: return "SHA256";
779 4 : case DIGEST_ALGO_SHA384: return "SHA384";
780 4 : case DIGEST_ALGO_SHA512: return "SHA512";
781 4 : 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 247 : string_to_cipher_algo (const char *string)
1095 : {
1096 : int val;
1097 :
1098 247 : val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
1099 247 : if (!val && string && (string[0]=='S' || string[0]=='s'))
1100 : {
1101 : char *endptr;
1102 :
1103 16 : string++;
1104 16 : val = strtol (string, &endptr, 10);
1105 16 : if (!*string || *endptr || openpgp_cipher_test_algo (val))
1106 0 : val = 0;
1107 : }
1108 :
1109 247 : 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 1276 : 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 1276 : val = gcry_md_map_name (string);
1124 1276 : if (!val && string && (string[0]=='H' || string[0]=='h'))
1125 : {
1126 : char *endptr;
1127 :
1128 20 : string++;
1129 20 : val = strtol (string, &endptr, 10);
1130 20 : if (!*string || *endptr || openpgp_md_test_algo (val))
1131 0 : val = 0;
1132 : }
1133 :
1134 1276 : 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 12 : string_to_compress_algo(const char *string)
1170 : {
1171 : /* TRANSLATORS: See doc/TRANSLATE about this string. */
1172 12 : if(match_multistr(_("uncompressed|none"),string))
1173 0 : return 0;
1174 12 : else if(ascii_strcasecmp(string,"uncompressed")==0)
1175 0 : return 0;
1176 12 : else if(ascii_strcasecmp(string,"none")==0)
1177 0 : return 0;
1178 12 : else if(ascii_strcasecmp(string,"zip")==0)
1179 0 : return 1;
1180 12 : else if(ascii_strcasecmp(string,"zlib")==0)
1181 0 : return 2;
1182 : #ifdef HAVE_BZIP2
1183 12 : else if(ascii_strcasecmp(string,"bzip2")==0)
1184 0 : return 3;
1185 : #endif
1186 12 : else if(ascii_strcasecmp(string,"z0")==0)
1187 0 : return 0;
1188 12 : else if(ascii_strcasecmp(string,"z1")==0)
1189 4 : return 1;
1190 8 : else if(ascii_strcasecmp(string,"z2")==0)
1191 4 : return 2;
1192 : #ifdef HAVE_BZIP2
1193 4 : else if(ascii_strcasecmp(string,"z3")==0)
1194 4 : return 3;
1195 : #endif
1196 : else
1197 0 : return -1;
1198 : }
1199 :
1200 : int
1201 1238 : check_compress_algo(int algo)
1202 : {
1203 1238 : switch (algo)
1204 : {
1205 248 : case 0: return 0;
1206 : #ifdef HAVE_ZIP
1207 : case 1:
1208 869 : case 2: return 0;
1209 : #endif
1210 : #ifdef HAVE_BZIP2
1211 14 : case 3: return 0;
1212 : #endif
1213 107 : default: return GPG_ERR_COMPR_ALGO;
1214 : }
1215 : }
1216 :
1217 : int
1218 55 : default_cipher_algo(void)
1219 : {
1220 55 : if(opt.def_cipher_algo)
1221 45 : 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 180 : default_compress_algo(void)
1233 : {
1234 180 : if(opt.compress_algo!=-1)
1235 0 : return opt.compress_algo;
1236 180 : else if(opt.personal_compress_prefs)
1237 0 : return opt.personal_compress_prefs[0].value;
1238 : else
1239 180 : 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 0 : case CO_DE_VS: return "--compliance=de-vs";
1256 : }
1257 :
1258 0 : return ver;
1259 : }
1260 :
1261 : void
1262 0 : compliance_failure(void)
1263 : {
1264 0 : char *ver="???";
1265 :
1266 0 : switch(opt.compliance)
1267 : {
1268 : case CO_GNUPG:
1269 0 : ver="GnuPG";
1270 0 : break;
1271 :
1272 : case CO_RFC4880:
1273 0 : ver="OpenPGP";
1274 0 : break;
1275 :
1276 : case CO_RFC2440:
1277 0 : ver="OpenPGP (older)";
1278 0 : break;
1279 :
1280 : case CO_PGP6:
1281 0 : ver="PGP 6.x";
1282 0 : break;
1283 :
1284 : case CO_PGP7:
1285 0 : ver="PGP 7.x";
1286 0 : break;
1287 :
1288 : case CO_PGP8:
1289 0 : ver="PGP 8.x";
1290 0 : break;
1291 :
1292 : case CO_DE_VS:
1293 0 : ver="DE-VS applications";
1294 0 : break;
1295 : }
1296 :
1297 0 : log_info(_("this message may not be usable by %s\n"),ver);
1298 0 : opt.compliance=CO_GNUPG;
1299 0 : }
1300 :
1301 : /* Break a string into successive option pieces. Accepts single word
1302 : options and key=value argument options. */
1303 : char *
1304 12 : optsep(char **stringp)
1305 : {
1306 : char *tok,*end;
1307 :
1308 12 : tok=*stringp;
1309 12 : if(tok)
1310 : {
1311 6 : end=strpbrk(tok," ,=");
1312 6 : if(end)
1313 : {
1314 0 : int sawequals=0;
1315 0 : char *ptr=end;
1316 :
1317 : /* what we need to do now is scan along starting with *end,
1318 : If the next character we see (ignoring spaces) is an =
1319 : sign, then there is an argument. */
1320 :
1321 0 : while(*ptr)
1322 : {
1323 0 : if(*ptr=='=')
1324 0 : sawequals=1;
1325 0 : else if(*ptr!=' ')
1326 0 : break;
1327 0 : ptr++;
1328 : }
1329 :
1330 : /* There is an argument, so grab that too. At this point,
1331 : ptr points to the first character of the argument. */
1332 0 : if(sawequals)
1333 : {
1334 : /* Is it a quoted argument? */
1335 0 : if(*ptr=='"')
1336 : {
1337 0 : ptr++;
1338 0 : end=strchr(ptr,'"');
1339 0 : if(end)
1340 0 : end++;
1341 : }
1342 : else
1343 0 : end=strpbrk(ptr," ,");
1344 : }
1345 :
1346 0 : if(end && *end)
1347 : {
1348 0 : *end='\0';
1349 0 : *stringp=end+1;
1350 : }
1351 : else
1352 0 : *stringp=NULL;
1353 : }
1354 : else
1355 6 : *stringp=NULL;
1356 : }
1357 :
1358 12 : return tok;
1359 : }
1360 :
1361 : /* Breaks an option value into key and value. Returns NULL if there
1362 : is no value. Note that "string" is modified to remove the =value
1363 : part. */
1364 : char *
1365 0 : argsplit(char *string)
1366 : {
1367 0 : char *equals,*arg=NULL;
1368 :
1369 0 : equals=strchr(string,'=');
1370 0 : if(equals)
1371 : {
1372 : char *quote,*space;
1373 :
1374 0 : *equals='\0';
1375 0 : arg=equals+1;
1376 :
1377 : /* Quoted arg? */
1378 0 : quote=strchr(arg,'"');
1379 0 : if(quote)
1380 : {
1381 0 : arg=quote+1;
1382 :
1383 0 : quote=strchr(arg,'"');
1384 0 : if(quote)
1385 0 : *quote='\0';
1386 : }
1387 : else
1388 : {
1389 : size_t spaces;
1390 :
1391 : /* Trim leading spaces off of the arg */
1392 0 : spaces=strspn(arg," ");
1393 0 : arg+=spaces;
1394 : }
1395 :
1396 : /* Trim tailing spaces off of the tag */
1397 0 : space=strchr(string,' ');
1398 0 : if(space)
1399 0 : *space='\0';
1400 : }
1401 :
1402 0 : return arg;
1403 : }
1404 :
1405 : /* Return the length of the initial token, leaving off any
1406 : argument. */
1407 : static size_t
1408 21 : optlen(const char *s)
1409 : {
1410 21 : char *end=strpbrk(s," =");
1411 :
1412 21 : if(end)
1413 0 : return end-s;
1414 : else
1415 21 : return strlen(s);
1416 : }
1417 :
1418 : int
1419 3 : parse_options(char *str,unsigned int *options,
1420 : struct parse_options *opts,int noisy)
1421 : {
1422 : char *tok;
1423 :
1424 3 : if (str && !strcmp (str, "help"))
1425 : {
1426 0 : int i,maxlen=0;
1427 :
1428 : /* Figure out the longest option name so we can line these up
1429 : neatly. */
1430 0 : for(i=0;opts[i].name;i++)
1431 0 : if(opts[i].help && maxlen<strlen(opts[i].name))
1432 0 : maxlen=strlen(opts[i].name);
1433 :
1434 0 : for(i=0;opts[i].name;i++)
1435 0 : if(opts[i].help)
1436 0 : es_printf("%s%*s%s\n",opts[i].name,
1437 0 : maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
1438 :
1439 0 : g10_exit(0);
1440 : }
1441 :
1442 9 : while((tok=optsep(&str)))
1443 : {
1444 3 : int i,rev=0;
1445 3 : char *otok=tok;
1446 :
1447 3 : if(tok[0]=='\0')
1448 0 : continue;
1449 :
1450 3 : if(ascii_strncasecmp("no-",tok,3)==0)
1451 : {
1452 0 : rev=1;
1453 0 : tok+=3;
1454 : }
1455 :
1456 21 : for(i=0;opts[i].name;i++)
1457 : {
1458 21 : size_t toklen=optlen(tok);
1459 :
1460 21 : if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1461 : {
1462 : /* We have a match, but it might be incomplete */
1463 3 : if(toklen!=strlen(opts[i].name))
1464 : {
1465 : int j;
1466 :
1467 0 : for(j=i+1;opts[j].name;j++)
1468 : {
1469 0 : if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1470 : {
1471 0 : if(noisy)
1472 0 : log_info(_("ambiguous option '%s'\n"),otok);
1473 0 : return 0;
1474 : }
1475 : }
1476 : }
1477 :
1478 3 : if(rev)
1479 : {
1480 0 : *options&=~opts[i].bit;
1481 0 : if(opts[i].value)
1482 0 : *opts[i].value=NULL;
1483 : }
1484 : else
1485 : {
1486 3 : *options|=opts[i].bit;
1487 3 : if(opts[i].value)
1488 0 : *opts[i].value=argsplit(tok);
1489 : }
1490 3 : break;
1491 : }
1492 : }
1493 :
1494 3 : if(!opts[i].name)
1495 : {
1496 0 : if(noisy)
1497 0 : log_info(_("unknown option '%s'\n"),otok);
1498 0 : return 0;
1499 : }
1500 : }
1501 :
1502 3 : return 1;
1503 : }
1504 :
1505 :
1506 : /* Similar to access(2), but uses PATH to find the file. */
1507 : int
1508 0 : path_access(const char *file,int mode)
1509 : {
1510 : char *envpath;
1511 0 : int ret=-1;
1512 :
1513 0 : envpath=getenv("PATH");
1514 :
1515 0 : if(!envpath
1516 : #ifdef HAVE_DRIVE_LETTERS
1517 : || (((file[0]>='A' && file[0]<='Z')
1518 : || (file[0]>='a' && file[0]<='z'))
1519 : && file[1]==':')
1520 : #else
1521 0 : || file[0]=='/'
1522 : #endif
1523 : )
1524 0 : return access(file,mode);
1525 : else
1526 : {
1527 : /* At least as large as, but most often larger than we need. */
1528 0 : char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1529 0 : char *split,*item,*path=xstrdup(envpath);
1530 :
1531 0 : split=path;
1532 :
1533 0 : while((item=strsep(&split,PATHSEP_S)))
1534 : {
1535 0 : strcpy(buffer,item);
1536 0 : strcat(buffer,"/");
1537 0 : strcat(buffer,file);
1538 0 : ret=access(buffer,mode);
1539 0 : if(ret==0)
1540 0 : break;
1541 : }
1542 :
1543 0 : xfree(path);
1544 0 : xfree(buffer);
1545 : }
1546 :
1547 0 : return ret;
1548 : }
1549 :
1550 :
1551 :
1552 : /* Return the number of public key parameters as used by OpenPGP. */
1553 : int
1554 29381 : pubkey_get_npkey (pubkey_algo_t algo)
1555 : {
1556 29381 : switch (algo)
1557 : {
1558 : case PUBKEY_ALGO_RSA:
1559 : case PUBKEY_ALGO_RSA_E:
1560 9165 : case PUBKEY_ALGO_RSA_S: return 2;
1561 7674 : case PUBKEY_ALGO_ELGAMAL_E: return 3;
1562 10140 : case PUBKEY_ALGO_DSA: return 4;
1563 917 : case PUBKEY_ALGO_ECDH: return 3;
1564 1249 : case PUBKEY_ALGO_ECDSA: return 2;
1565 0 : case PUBKEY_ALGO_ELGAMAL: return 3;
1566 52 : case PUBKEY_ALGO_EDDSA: return 2;
1567 : }
1568 184 : return 0;
1569 : }
1570 :
1571 :
1572 : /* Return the number of secret key parameters as used by OpenPGP. */
1573 : int
1574 7707 : pubkey_get_nskey (pubkey_algo_t algo)
1575 : {
1576 7707 : switch (algo)
1577 : {
1578 : case PUBKEY_ALGO_RSA:
1579 : case PUBKEY_ALGO_RSA_E:
1580 2511 : case PUBKEY_ALGO_RSA_S: return 6;
1581 2303 : case PUBKEY_ALGO_ELGAMAL_E: return 4;
1582 2339 : case PUBKEY_ALGO_DSA: return 5;
1583 274 : case PUBKEY_ALGO_ECDH: return 4;
1584 270 : case PUBKEY_ALGO_ECDSA: return 3;
1585 0 : case PUBKEY_ALGO_ELGAMAL: return 4;
1586 10 : case PUBKEY_ALGO_EDDSA: return 3;
1587 : }
1588 0 : return 0;
1589 : }
1590 :
1591 : /* Temporary helper. */
1592 : int
1593 19611 : pubkey_get_nsig (pubkey_algo_t algo)
1594 : {
1595 19611 : switch (algo)
1596 : {
1597 : case PUBKEY_ALGO_RSA:
1598 : case PUBKEY_ALGO_RSA_E:
1599 6471 : case PUBKEY_ALGO_RSA_S: return 1;
1600 0 : case PUBKEY_ALGO_ELGAMAL_E: return 0;
1601 12017 : case PUBKEY_ALGO_DSA: return 2;
1602 0 : case PUBKEY_ALGO_ECDH: return 0;
1603 1081 : case PUBKEY_ALGO_ECDSA: return 2;
1604 0 : case PUBKEY_ALGO_ELGAMAL: return 2;
1605 42 : case PUBKEY_ALGO_EDDSA: return 2;
1606 : }
1607 0 : return 0;
1608 : }
1609 :
1610 :
1611 : /* Temporary helper. */
1612 : int
1613 1052 : pubkey_get_nenc (pubkey_algo_t algo)
1614 : {
1615 1052 : switch (algo)
1616 : {
1617 : case PUBKEY_ALGO_RSA:
1618 : case PUBKEY_ALGO_RSA_E:
1619 34 : case PUBKEY_ALGO_RSA_S: return 1;
1620 916 : case PUBKEY_ALGO_ELGAMAL_E: return 2;
1621 0 : case PUBKEY_ALGO_DSA: return 0;
1622 102 : case PUBKEY_ALGO_ECDH: return 2;
1623 0 : case PUBKEY_ALGO_ECDSA: return 0;
1624 0 : case PUBKEY_ALGO_ELGAMAL: return 2;
1625 0 : case PUBKEY_ALGO_EDDSA: return 0;
1626 : }
1627 0 : return 0;
1628 : }
1629 :
1630 :
1631 : /* Temporary helper. */
1632 : unsigned int
1633 1291 : pubkey_nbits( int algo, gcry_mpi_t *key )
1634 : {
1635 : int rc, nbits;
1636 : gcry_sexp_t sexp;
1637 :
1638 1291 : if (algo == PUBKEY_ALGO_DSA
1639 121 : && key[0] && key[1] && key[2] && key[3])
1640 : {
1641 363 : rc = gcry_sexp_build (&sexp, NULL,
1642 : "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1643 363 : key[0], key[1], key[2], key[3] );
1644 : }
1645 1170 : else if ((algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
1646 716 : && key[0] && key[1] && key[2])
1647 : {
1648 1432 : rc = gcry_sexp_build (&sexp, NULL,
1649 : "(public-key(elg(p%m)(g%m)(y%m)))",
1650 1432 : key[0], key[1], key[2] );
1651 : }
1652 454 : else if (is_RSA (algo)
1653 277 : && key[0] && key[1])
1654 : {
1655 277 : rc = gcry_sexp_build (&sexp, NULL,
1656 : "(public-key(rsa(n%m)(e%m)))",
1657 277 : key[0], key[1] );
1658 : }
1659 177 : else if ((algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
1660 0 : || algo == PUBKEY_ALGO_EDDSA)
1661 177 : && key[0] && key[1])
1662 177 : {
1663 177 : char *curve = openpgp_oid_to_str (key[0]);
1664 177 : if (!curve)
1665 0 : rc = gpg_error_from_syserror ();
1666 : else
1667 : {
1668 177 : rc = gcry_sexp_build (&sexp, NULL,
1669 : "(public-key(ecc(curve%s)(q%m)))",
1670 177 : curve, key[1]);
1671 177 : xfree (curve);
1672 : }
1673 : }
1674 : else
1675 0 : return 0;
1676 :
1677 1291 : if (rc)
1678 0 : BUG ();
1679 :
1680 1291 : nbits = gcry_pk_get_nbits (sexp);
1681 1291 : gcry_sexp_release (sexp);
1682 1291 : return nbits;
1683 : }
1684 :
1685 :
1686 :
1687 : int
1688 76 : mpi_print (estream_t fp, gcry_mpi_t a, int mode)
1689 : {
1690 76 : int n = 0;
1691 : size_t nwritten;
1692 :
1693 76 : if (!a)
1694 0 : return es_fprintf (fp, "[MPI_NULL]");
1695 76 : if (!mode)
1696 : {
1697 : unsigned int n1;
1698 76 : n1 = gcry_mpi_get_nbits(a);
1699 76 : n += es_fprintf (fp, "[%u bits]", n1);
1700 : }
1701 0 : else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
1702 : {
1703 : unsigned int nbits;
1704 0 : unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
1705 0 : if (!p)
1706 0 : n += es_fprintf (fp, "[invalid opaque value]");
1707 : else
1708 : {
1709 0 : if (!es_write_hexstring (fp, p, (nbits + 7)/8, 0, &nwritten))
1710 0 : n += nwritten;
1711 : }
1712 : }
1713 : else
1714 : {
1715 : unsigned char *buffer;
1716 : size_t buflen;
1717 :
1718 0 : if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &buflen, a))
1719 0 : BUG ();
1720 0 : if (!es_write_hexstring (fp, buffer, buflen, 0, &nwritten))
1721 0 : n += nwritten;
1722 0 : gcry_free (buffer);
1723 : }
1724 76 : return n;
1725 : }
1726 :
1727 :
1728 : /* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
1729 : i.e. 04 <x> <y> */
1730 : unsigned int
1731 121 : ecdsa_qbits_from_Q (unsigned int qbits)
1732 : {
1733 121 : if ((qbits%8) > 3)
1734 : {
1735 0 : log_error (_("ECDSA public key is expected to be in SEC encoding "
1736 : "multiple of 8 bits\n"));
1737 0 : return 0;
1738 : }
1739 121 : qbits -= qbits%8;
1740 121 : qbits /= 2;
1741 121 : return qbits;
1742 : }
1743 :
1744 :
1745 : /* Ignore signatures and certifications made over certain digest
1746 : * algorithms by default, MD5 is considered weak. This allows users
1747 : * to deprecate support for other algorithms as well.
1748 : */
1749 : void
1750 1228 : additional_weak_digest (const char* digestname)
1751 : {
1752 1228 : struct weakhash *weak = NULL;
1753 1228 : const enum gcry_md_algos algo = string_to_digest_algo(digestname);
1754 :
1755 1228 : if (algo == GCRY_MD_NONE)
1756 : {
1757 0 : log_error (_("unknown weak digest '%s'\n"), digestname);
1758 0 : return;
1759 : }
1760 :
1761 : /* Check to ensure it's not already present. */
1762 1228 : for (weak = opt.weak_digests; weak; weak = weak->next)
1763 0 : if (algo == weak->algo)
1764 0 : return;
1765 :
1766 : /* Add it to the head of the list. */
1767 1228 : weak = xmalloc(sizeof(*weak));
1768 1228 : weak->algo = algo;
1769 1228 : weak->rejection_shown = 0;
1770 1228 : weak->next = opt.weak_digests;
1771 1228 : opt.weak_digests = weak;
1772 : }
|