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