Line data Source code
1 : /* gpgme.c - GnuPG Made Easy.
2 : Copyright (C) 2000 Werner Koch (dd9jn)
3 : Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012,
4 : 2014, 2015 g10 Code GmbH
5 :
6 : This file is part of GPGME.
7 :
8 : GPGME is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as
10 : published by the Free Software Foundation; either version 2.1 of
11 : the License, or (at your option) any later version.
12 :
13 : GPGME is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public
19 : License along with this program; if not, see <https://www.gnu.org/licenses/>.
20 : */
21 :
22 : #if HAVE_CONFIG_H
23 : #include <config.h>
24 : #endif
25 : #include <stdio.h>
26 : #include <stdlib.h>
27 : #include <string.h>
28 : #include <assert.h>
29 : #include <errno.h>
30 : #ifdef HAVE_LOCALE_H
31 : #include <locale.h>
32 : #endif
33 :
34 : #include "util.h"
35 : #include "context.h"
36 : #include "ops.h"
37 : #include "wait.h"
38 : #include "debug.h"
39 : #include "priv-io.h"
40 : #include "sys-util.h"
41 : #include "mbox-util.h"
42 :
43 :
44 : /* The default locale. */
45 : DEFINE_STATIC_LOCK (def_lc_lock);
46 : static char *def_lc_ctype;
47 : static char *def_lc_messages;
48 :
49 :
50 : gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
51 :
52 : /* Protects all reference counters in result structures. All other
53 : accesses to a result structure are read only. */
54 : DEFINE_STATIC_LOCK (result_ref_lock);
55 :
56 :
57 : /* Set the global flag NAME to VALUE. Return 0 on success. Note that
58 : this function does not use gpgme_error and thus a non-zero return
59 : value merely means "error". Certain flags may be set before
60 : gpgme_check_version is called. See the manual for a description of
61 : supported flags. The caller must assure that this function is
62 : called only by one thread at a time. */
63 : int
64 0 : gpgme_set_global_flag (const char *name, const char *value)
65 : {
66 0 : if (!name || !value)
67 0 : return -1;
68 0 : else if (!strcmp (name, "debug"))
69 0 : return _gpgme_debug_set_debug_envvar (value);
70 0 : else if (!strcmp (name, "disable-gpgconf"))
71 : {
72 0 : _gpgme_dirinfo_disable_gpgconf ();
73 0 : return 0;
74 : }
75 0 : else if (!strcmp (name, "require-gnupg"))
76 0 : return _gpgme_set_engine_minimal_version (value);
77 0 : else if (!strcmp (name, "gpgconf-name"))
78 0 : return _gpgme_set_default_gpgconf_name (value);
79 0 : else if (!strcmp (name, "gpg-name"))
80 0 : return _gpgme_set_default_gpg_name (value);
81 0 : else if (!strcmp (name, "w32-inst-dir"))
82 0 : return _gpgme_set_override_inst_dir (value);
83 : else
84 0 : return -1;
85 : }
86 :
87 :
88 :
89 : /* Create a new context as an environment for GPGME crypto
90 : operations. */
91 : gpgme_error_t
92 763 : gpgme_new (gpgme_ctx_t *r_ctx)
93 : {
94 : gpgme_error_t err;
95 : gpgme_ctx_t ctx;
96 763 : TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
97 :
98 763 : if (_gpgme_selftest)
99 0 : return TRACE_ERR (_gpgme_selftest);
100 :
101 763 : if (!r_ctx)
102 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
103 :
104 763 : ctx = calloc (1, sizeof *ctx);
105 763 : if (!ctx)
106 0 : return TRACE_ERR (gpg_error_from_syserror ());
107 :
108 763 : INIT_LOCK (ctx->lock);
109 :
110 763 : err = _gpgme_engine_info_copy (&ctx->engine_info);
111 763 : if (!err && !ctx->engine_info)
112 0 : err = gpg_error (GPG_ERR_NO_ENGINE);
113 763 : if (err)
114 : {
115 0 : free (ctx);
116 0 : return TRACE_ERR (err);
117 : }
118 :
119 763 : ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
120 763 : ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
121 763 : ctx->protocol = GPGME_PROTOCOL_OpenPGP;
122 763 : ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT;
123 763 : _gpgme_fd_table_init (&ctx->fdt);
124 :
125 763 : LOCK (def_lc_lock);
126 763 : if (def_lc_ctype)
127 : {
128 186 : ctx->lc_ctype = strdup (def_lc_ctype);
129 186 : if (!ctx->lc_ctype)
130 : {
131 0 : int saved_err = gpg_error_from_syserror ();
132 0 : UNLOCK (def_lc_lock);
133 0 : _gpgme_engine_info_release (ctx->engine_info);
134 0 : free (ctx);
135 0 : return TRACE_ERR (saved_err);
136 : }
137 : }
138 : else
139 577 : def_lc_ctype = NULL;
140 :
141 763 : if (def_lc_messages)
142 : {
143 186 : ctx->lc_messages = strdup (def_lc_messages);
144 186 : if (!ctx->lc_messages)
145 : {
146 0 : int saved_err = gpg_error_from_syserror ();
147 0 : UNLOCK (def_lc_lock);
148 0 : if (ctx->lc_ctype)
149 0 : free (ctx->lc_ctype);
150 0 : _gpgme_engine_info_release (ctx->engine_info);
151 0 : free (ctx);
152 0 : return TRACE_ERR (saved_err);
153 : }
154 : }
155 : else
156 577 : def_lc_messages = NULL;
157 763 : UNLOCK (def_lc_lock);
158 :
159 763 : *r_ctx = ctx;
160 :
161 763 : return TRACE_SUC1 ("ctx=%p", ctx);
162 : }
163 :
164 :
165 : gpgme_error_t
166 32 : _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err,
167 : gpg_error_t op_err)
168 : {
169 : gpgme_error_t err;
170 : struct gpgme_io_event_done_data data;
171 :
172 32 : TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i",
173 : ctx_err, op_err);
174 :
175 32 : if (ctx_err)
176 : {
177 30 : err = _gpgme_engine_cancel (ctx->engine);
178 30 : if (err)
179 0 : return TRACE_ERR (err);
180 : }
181 : else
182 : {
183 2 : err = _gpgme_engine_cancel_op (ctx->engine);
184 2 : if (err)
185 0 : return TRACE_ERR (err);
186 : }
187 :
188 32 : data.err = ctx_err;
189 32 : data.op_err = op_err;
190 :
191 32 : _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
192 :
193 32 : return TRACE_ERR (0);
194 : }
195 :
196 :
197 : /* Cancel a pending asynchronous operation. */
198 : gpgme_error_t
199 0 : gpgme_cancel (gpgme_ctx_t ctx)
200 : {
201 : gpg_error_t err;
202 :
203 0 : TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx);
204 :
205 0 : if (!ctx)
206 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
207 :
208 0 : err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0);
209 :
210 0 : return TRACE_ERR (err);
211 : }
212 :
213 :
214 : /* Cancel a pending operation asynchronously. */
215 : gpgme_error_t
216 17 : gpgme_cancel_async (gpgme_ctx_t ctx)
217 : {
218 17 : TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
219 :
220 17 : if (!ctx)
221 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
222 :
223 17 : LOCK (ctx->lock);
224 17 : ctx->canceled = 1;
225 17 : UNLOCK (ctx->lock);
226 :
227 17 : return TRACE_ERR (0);
228 : }
229 :
230 :
231 : /* Release all resources associated with the given context. */
232 : void
233 731 : gpgme_release (gpgme_ctx_t ctx)
234 : {
235 731 : TRACE (DEBUG_CTX, "gpgme_release", ctx);
236 :
237 730 : if (!ctx)
238 3 : return;
239 :
240 727 : _gpgme_engine_release (ctx->engine);
241 727 : ctx->engine = NULL;
242 727 : _gpgme_fd_table_deinit (&ctx->fdt);
243 727 : _gpgme_release_result (ctx);
244 727 : _gpgme_signers_clear (ctx);
245 726 : _gpgme_sig_notation_clear (ctx);
246 726 : free (ctx->sender);
247 726 : free (ctx->signers);
248 726 : free (ctx->lc_ctype);
249 726 : free (ctx->lc_messages);
250 726 : free (ctx->override_session_key);
251 726 : free (ctx->request_origin);
252 726 : free (ctx->auto_key_locate);
253 726 : free (ctx->trust_model);
254 726 : _gpgme_engine_info_release (ctx->engine_info);
255 727 : ctx->engine_info = NULL;
256 727 : DESTROY_LOCK (ctx->lock);
257 726 : free (ctx);
258 : }
259 :
260 :
261 : void
262 0 : gpgme_result_ref (void *result)
263 : {
264 : struct ctx_op_data *data;
265 :
266 0 : if (! result)
267 0 : return;
268 :
269 0 : data = (void*)((char*)result - sizeof (struct ctx_op_data));
270 :
271 0 : assert (data->magic == CTX_OP_DATA_MAGIC);
272 :
273 0 : LOCK (result_ref_lock);
274 0 : data->references++;
275 0 : UNLOCK (result_ref_lock);
276 : }
277 :
278 :
279 : void
280 930 : gpgme_result_unref (void *result)
281 : {
282 : struct ctx_op_data *data;
283 :
284 930 : if (! result)
285 0 : return;
286 :
287 930 : data = (void*)((char*)result - sizeof (struct ctx_op_data));
288 :
289 930 : assert (data->magic == CTX_OP_DATA_MAGIC);
290 :
291 930 : LOCK (result_ref_lock);
292 930 : if (--data->references)
293 : {
294 0 : UNLOCK (result_ref_lock);
295 0 : return;
296 : }
297 930 : UNLOCK (result_ref_lock);
298 :
299 930 : if (data->cleanup)
300 886 : (*data->cleanup) (data->hook);
301 930 : free (data);
302 : }
303 :
304 :
305 : void
306 1738 : _gpgme_release_result (gpgme_ctx_t ctx)
307 : {
308 1738 : struct ctx_op_data *data = ctx->op_data;
309 :
310 4406 : while (data)
311 : {
312 930 : struct ctx_op_data *next_data = data->next;
313 930 : data->next = NULL;
314 930 : gpgme_result_unref (data->hook);
315 930 : data = next_data;
316 : }
317 1738 : ctx->op_data = NULL;
318 1738 : }
319 :
320 :
321 : gpgme_error_t
322 531 : gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
323 : {
324 531 : TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
325 : protocol, gpgme_get_protocol_name (protocol)
326 : ? gpgme_get_protocol_name (protocol) : "invalid");
327 :
328 531 : if (protocol != GPGME_PROTOCOL_OpenPGP
329 42 : && protocol != GPGME_PROTOCOL_CMS
330 34 : && protocol != GPGME_PROTOCOL_GPGCONF
331 32 : && protocol != GPGME_PROTOCOL_ASSUAN
332 18 : && protocol != GPGME_PROTOCOL_G13
333 18 : && protocol != GPGME_PROTOCOL_UISERVER
334 18 : && protocol != GPGME_PROTOCOL_SPAWN)
335 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
336 :
337 531 : if (!ctx)
338 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
339 :
340 531 : if (ctx->protocol != protocol)
341 : {
342 : /* Shut down the engine when switching protocols. */
343 42 : if (ctx->engine)
344 : {
345 12 : TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
346 12 : _gpgme_engine_release (ctx->engine);
347 12 : ctx->engine = NULL;
348 : }
349 :
350 42 : ctx->protocol = protocol;
351 : }
352 531 : return TRACE_ERR (0);
353 : }
354 :
355 :
356 : gpgme_protocol_t
357 538 : gpgme_get_protocol (gpgme_ctx_t ctx)
358 : {
359 538 : TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
360 : "ctx->protocol=%i (%s)", ctx->protocol,
361 : gpgme_get_protocol_name (ctx->protocol)
362 : ? gpgme_get_protocol_name (ctx->protocol) : "invalid");
363 :
364 538 : return ctx->protocol;
365 : }
366 :
367 :
368 : gpgme_error_t
369 0 : gpgme_set_sub_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
370 : {
371 0 : TRACE2 (DEBUG_CTX, "gpgme_set_sub_protocol", ctx, "protocol=%i (%s)",
372 : protocol, gpgme_get_protocol_name (protocol)
373 : ? gpgme_get_protocol_name (protocol) : "invalid");
374 :
375 0 : if (!ctx)
376 0 : return gpg_error (GPG_ERR_INV_VALUE);
377 :
378 0 : ctx->sub_protocol = protocol;
379 0 : return 0;
380 : }
381 :
382 :
383 : gpgme_protocol_t
384 0 : gpgme_get_sub_protocol (gpgme_ctx_t ctx)
385 : {
386 0 : TRACE2 (DEBUG_CTX, "gpgme_get_sub_protocol", ctx,
387 : "ctx->sub_protocol=%i (%s)", ctx->sub_protocol,
388 : gpgme_get_protocol_name (ctx->sub_protocol)
389 : ? gpgme_get_protocol_name (ctx->sub_protocol) : "invalid");
390 :
391 0 : return ctx->sub_protocol;
392 : }
393 :
394 :
395 : const char *
396 2992 : gpgme_get_protocol_name (gpgme_protocol_t protocol)
397 : {
398 2992 : switch (protocol)
399 : {
400 : case GPGME_PROTOCOL_OpenPGP:
401 2844 : return "OpenPGP";
402 :
403 : case GPGME_PROTOCOL_CMS:
404 20 : return "CMS";
405 :
406 : case GPGME_PROTOCOL_GPGCONF:
407 8 : return "GPGCONF";
408 :
409 : case GPGME_PROTOCOL_ASSUAN:
410 84 : return "Assuan";
411 :
412 : case GPGME_PROTOCOL_G13:
413 0 : return "G13";
414 :
415 : case GPGME_PROTOCOL_UISERVER:
416 0 : return "UIServer";
417 :
418 : case GPGME_PROTOCOL_SPAWN:
419 36 : return "Spawn";
420 :
421 : case GPGME_PROTOCOL_DEFAULT:
422 0 : return "default";
423 :
424 : case GPGME_PROTOCOL_UNKNOWN:
425 0 : return "unknown";
426 :
427 : default:
428 0 : return NULL;
429 : }
430 : }
431 :
432 :
433 : /* Store the sender's address in the context. ADDRESS is addr-spec of
434 : * mailbox but my also be a complete mailbox, in which case this
435 : * function extracts the addr-spec from it. Returns 0 on success or
436 : * an error code if no valid addr-spec could be extracted from
437 : * ADDRESS. */
438 : gpgme_error_t
439 8 : gpgme_set_sender (gpgme_ctx_t ctx, const char *address)
440 : {
441 8 : char *p = NULL;
442 :
443 8 : TRACE_BEG1 (DEBUG_CTX, "gpgme_set_sender", ctx, "sender='%s'",
444 : address?address:"(null)");
445 :
446 8 : if (!ctx || (address && !(p = _gpgme_mailbox_from_userid (address))))
447 1 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
448 :
449 7 : free (ctx->sender);
450 7 : ctx->sender = p;
451 7 : return TRACE_ERR (0);
452 : }
453 :
454 :
455 : /* Return the sender's address (addr-spec part) from the context or
456 : * NULL if none was set. The returned value is valid as long as the
457 : * CTX is valid and gpgme_set_sender has not been used. */
458 : const char *
459 4 : gpgme_get_sender (gpgme_ctx_t ctx)
460 : {
461 4 : TRACE1 (DEBUG_CTX, "gpgme_get_sender", ctx, "sender='%s'",
462 : ctx?ctx->sender:"");
463 :
464 4 : return ctx->sender;
465 : }
466 :
467 :
468 : /* Enable or disable the use of an ascii armor for all output. */
469 : void
470 242 : gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
471 : {
472 242 : TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
473 : use_armor, use_armor ? "yes" : "no");
474 :
475 242 : if (!ctx)
476 0 : return;
477 :
478 242 : ctx->use_armor = !!use_armor;
479 : }
480 :
481 :
482 : /* Return the state of the armor flag. */
483 : int
484 5 : gpgme_get_armor (gpgme_ctx_t ctx)
485 : {
486 5 : TRACE2 (DEBUG_CTX, "gpgme_get_armor", ctx, "ctx->use_armor=%i (%s)",
487 : ctx->use_armor, ctx->use_armor ? "yes" : "no");
488 5 : return ctx->use_armor;
489 : }
490 :
491 :
492 : /* Set the flag NAME for CTX to VALUE. Please consult the manual for
493 : * a description of the flags.
494 : */
495 : gpgme_error_t
496 23 : gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
497 : {
498 23 : gpgme_error_t err = 0;
499 : int abool;
500 :
501 23 : TRACE2 (DEBUG_CTX, "gpgme_set_ctx_flag", ctx,
502 : "name='%s' value='%s'",
503 : name? name:"(null)", value?value:"(null)");
504 :
505 23 : abool = (value && *value)? !!atoi (value) : 0;
506 :
507 23 : if (!ctx || !name || !value)
508 0 : err = gpg_error (GPG_ERR_INV_VALUE);
509 23 : else if (!strcmp (name, "redraw"))
510 : {
511 0 : ctx->redraw_suggested = abool;
512 : }
513 23 : else if (!strcmp (name, "full-status"))
514 : {
515 4 : ctx->full_status = abool;
516 : }
517 19 : else if (!strcmp (name, "raw-description"))
518 : {
519 0 : ctx->raw_description = abool;
520 : }
521 19 : else if (!strcmp (name, "export-session-key"))
522 : {
523 0 : ctx->export_session_keys = abool;
524 : }
525 19 : else if (!strcmp (name, "override-session-key"))
526 : {
527 0 : free (ctx->override_session_key);
528 0 : ctx->override_session_key = strdup (value);
529 0 : if (!ctx->override_session_key)
530 0 : err = gpg_error_from_syserror ();
531 : }
532 19 : else if (!strcmp (name, "auto-key-retrieve"))
533 : {
534 0 : ctx->auto_key_retrieve = abool;
535 : }
536 19 : else if (!strcmp (name, "request-origin"))
537 : {
538 19 : free (ctx->request_origin);
539 19 : ctx->request_origin = strdup (value);
540 19 : if (!ctx->request_origin)
541 0 : err = gpg_error_from_syserror ();
542 : }
543 0 : else if (!strcmp (name, "no-symkey-cache"))
544 : {
545 0 : ctx->no_symkey_cache = abool;
546 : }
547 0 : else if (!strcmp (name, "ignore-mdc-error"))
548 : {
549 0 : ctx->ignore_mdc_error = abool;
550 : }
551 0 : else if (!strcmp (name, "auto-key-locate"))
552 : {
553 0 : free (ctx->auto_key_locate);
554 0 : ctx->auto_key_locate = strdup (value);
555 0 : if (!ctx->auto_key_locate)
556 0 : err = gpg_error_from_syserror ();
557 : }
558 0 : else if (!strcmp (name, "trust-model"))
559 : {
560 0 : free (ctx->trust_model);
561 0 : ctx->trust_model = strdup (value);
562 0 : if (!ctx->trust_model)
563 0 : err = gpg_error_from_syserror ();
564 : }
565 : else
566 0 : err = gpg_error (GPG_ERR_UNKNOWN_NAME);
567 :
568 23 : return err;
569 : }
570 :
571 :
572 : /* Get the context flag named NAME. See gpgme_set_ctx_flag for a list
573 : * of valid names. If the NAME is unknown NULL is returned. For a
574 : * boolean flag an empty string is returned for False and the string
575 : * "1" for True; thus either atoi or a simple string test can be
576 : * used. */
577 : const char *
578 0 : gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
579 : {
580 0 : if (!ctx || !name)
581 0 : return NULL;
582 0 : else if (!strcmp (name, "redraw"))
583 : {
584 0 : return ctx->redraw_suggested? "1":"";
585 : }
586 0 : else if (!strcmp (name, "full-status"))
587 : {
588 0 : return ctx->full_status? "1":"";
589 : }
590 0 : else if (!strcmp (name, "raw-description"))
591 : {
592 0 : return ctx->raw_description? "1":"";
593 : }
594 0 : else if (!strcmp (name, "export-session-key"))
595 : {
596 0 : return ctx->export_session_keys? "1":"";
597 : }
598 0 : else if (!strcmp (name, "override-session-key"))
599 : {
600 0 : return ctx->override_session_key? ctx->override_session_key : "";
601 : }
602 0 : else if (!strcmp (name, "auto-key-retrieve"))
603 : {
604 0 : return ctx->auto_key_retrieve? "1":"";
605 : }
606 0 : else if (!strcmp (name, "request-origin"))
607 : {
608 0 : return ctx->request_origin? ctx->request_origin : "";
609 : }
610 0 : else if (!strcmp (name, "no-symkey-cache"))
611 : {
612 0 : return ctx->no_symkey_cache? "1":"";
613 : }
614 0 : else if (!strcmp (name, "ignore-mdc-error"))
615 : {
616 0 : return ctx->ignore_mdc_error? "1":"";
617 : }
618 0 : else if (!strcmp (name, "auto-key-locate"))
619 : {
620 0 : return ctx->auto_key_locate? ctx->auto_key_locate : "";
621 : }
622 : else
623 0 : return NULL;
624 : }
625 :
626 :
627 : /* Enable or disable the use of the special textmode. Textmode is for
628 : example used for the RFC2015 signatures; note that the updated RFC
629 : 3156 mandates that the MUA does some preparations so that textmode
630 : is not needed anymore. */
631 : void
632 199 : gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
633 : {
634 199 : TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
635 : use_textmode, use_textmode ? "yes" : "no");
636 :
637 199 : if (!ctx)
638 0 : return;
639 :
640 199 : ctx->use_textmode = !!use_textmode;
641 : }
642 :
643 : /* Return the state of the textmode flag. */
644 : int
645 0 : gpgme_get_textmode (gpgme_ctx_t ctx)
646 : {
647 0 : TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
648 : ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
649 0 : return ctx->use_textmode;
650 : }
651 :
652 :
653 : /* Enable offline mode for this context. In offline mode dirmngr
654 : will be disabled. */
655 : void
656 167 : gpgme_set_offline (gpgme_ctx_t ctx, int offline)
657 : {
658 167 : TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)",
659 : offline, offline ? "yes" : "no");
660 :
661 167 : if (!ctx)
662 0 : return;
663 :
664 167 : ctx->offline = !!offline;
665 : }
666 :
667 : /* Return the state of the offline flag. */
668 : int
669 0 : gpgme_get_offline (gpgme_ctx_t ctx)
670 : {
671 0 : TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)",
672 : ctx->offline, ctx->offline ? "yes" : "no");
673 0 : return ctx->offline;
674 : }
675 :
676 :
677 : /* Set the number of certifications to include in an S/MIME message.
678 : The default is GPGME_INCLUDE_CERTS_DEFAULT. -1 means all certs,
679 : and -2 means all certs except the root cert. */
680 : void
681 0 : gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
682 : {
683 0 : if (!ctx)
684 0 : return;
685 :
686 0 : if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
687 0 : ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
688 0 : else if (nr_of_certs < -2)
689 0 : ctx->include_certs = -2;
690 : else
691 0 : ctx->include_certs = nr_of_certs;
692 :
693 0 : TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
694 : nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
695 : }
696 :
697 :
698 : /* Get the number of certifications to include in an S/MIME
699 : message. */
700 : int
701 0 : gpgme_get_include_certs (gpgme_ctx_t ctx)
702 : {
703 0 : TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
704 : ctx->include_certs);
705 0 : return ctx->include_certs;
706 : }
707 :
708 :
709 : /* This function changes the default behaviour of the keylisting
710 : functions. MODE is a bitwise-OR of the GPGME_KEYLIST_* flags. The
711 : default mode is GPGME_KEYLIST_MODE_LOCAL. */
712 : gpgme_error_t
713 314 : gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
714 : {
715 314 : TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
716 : mode);
717 :
718 314 : if (!ctx)
719 0 : return gpg_error (GPG_ERR_INV_VALUE);
720 :
721 314 : ctx->keylist_mode = mode;
722 314 : return 0;
723 : }
724 :
725 : /* This function returns the default behaviour of the keylisting
726 : functions. */
727 : gpgme_keylist_mode_t
728 265 : gpgme_get_keylist_mode (gpgme_ctx_t ctx)
729 : {
730 265 : TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
731 : "ctx->keylist_mode=0x%x", ctx->keylist_mode);
732 265 : return ctx->keylist_mode;
733 : }
734 :
735 :
736 : /* Set the pinentry mode for CTX to MODE. */
737 : gpgme_error_t
738 223 : gpgme_set_pinentry_mode (gpgme_ctx_t ctx, gpgme_pinentry_mode_t mode)
739 : {
740 223 : TRACE1 (DEBUG_CTX, "gpgme_set_pinentry_mode", ctx, "pinentry_mode=%u",
741 : (unsigned int)mode);
742 :
743 223 : if (!ctx)
744 0 : return gpg_error (GPG_ERR_INV_VALUE);
745 :
746 223 : switch (mode)
747 : {
748 : case GPGME_PINENTRY_MODE_DEFAULT:
749 : case GPGME_PINENTRY_MODE_ASK:
750 : case GPGME_PINENTRY_MODE_CANCEL:
751 : case GPGME_PINENTRY_MODE_ERROR:
752 : case GPGME_PINENTRY_MODE_LOOPBACK:
753 223 : break;
754 : default:
755 0 : return gpg_error (GPG_ERR_INV_VALUE);
756 : }
757 :
758 223 : ctx->pinentry_mode = mode;
759 223 : return 0;
760 : }
761 :
762 :
763 : /* Get the pinentry mode of CTX. */
764 : gpgme_pinentry_mode_t
765 12 : gpgme_get_pinentry_mode (gpgme_ctx_t ctx)
766 : {
767 12 : TRACE1 (DEBUG_CTX, "gpgme_get_pinentry_mode", ctx,
768 : "ctx->pinentry_mode=%u", (unsigned int)ctx->pinentry_mode);
769 12 : return ctx->pinentry_mode;
770 : }
771 :
772 :
773 : /* This function sets a callback function to be used to pass a
774 : passphrase to gpg. */
775 : void
776 252 : gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
777 : void *cb_value)
778 : {
779 252 : TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
780 : "passphrase_cb=%p/%p", cb, cb_value);
781 :
782 252 : if (!ctx)
783 0 : return;
784 :
785 252 : ctx->passphrase_cb = cb;
786 252 : ctx->passphrase_cb_value = cb_value;
787 : }
788 :
789 :
790 : /* This function returns the callback function to be used to pass a
791 : passphrase to the crypto engine. */
792 : void
793 0 : gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
794 : void **r_cb_value)
795 : {
796 0 : TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
797 : "ctx->passphrase_cb=%p/%p",
798 : ctx->passphrase_cb, ctx->passphrase_cb_value);
799 0 : if (r_cb)
800 0 : *r_cb = ctx->passphrase_cb;
801 0 : if (r_cb_value)
802 0 : *r_cb_value = ctx->passphrase_cb_value;
803 0 : }
804 :
805 :
806 : /* This function sets a callback function to be used as a progress
807 : indicator. */
808 : void
809 210 : gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
810 : {
811 210 : TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
812 : cb, cb_value);
813 :
814 210 : if (!ctx)
815 0 : return;
816 :
817 210 : ctx->progress_cb = cb;
818 210 : ctx->progress_cb_value = cb_value;
819 : }
820 :
821 :
822 : /* This function returns the callback function to be used as a
823 : progress indicator. */
824 : void
825 0 : gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
826 : void **r_cb_value)
827 : {
828 0 : TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
829 : ctx->progress_cb, ctx->progress_cb_value);
830 0 : if (r_cb)
831 0 : *r_cb = ctx->progress_cb;
832 0 : if (r_cb_value)
833 0 : *r_cb_value = ctx->progress_cb_value;
834 0 : }
835 :
836 :
837 : /* This function sets a callback function to be used as a status
838 : message forwarder. */
839 : void
840 163 : gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value)
841 : {
842 163 : TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p",
843 : cb, cb_value);
844 :
845 163 : if (!ctx)
846 0 : return;
847 :
848 163 : ctx->status_cb = cb;
849 163 : ctx->status_cb_value = cb_value;
850 : }
851 :
852 :
853 : /* This function returns the callback function to be used as a
854 : status message forwarder. */
855 : void
856 0 : gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb,
857 : void **r_cb_value)
858 : {
859 0 : TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p",
860 : ctx ? ctx->status_cb : NULL, ctx ? ctx->status_cb_value : NULL);
861 :
862 0 : if (r_cb)
863 0 : *r_cb = NULL;
864 :
865 0 : if (r_cb_value)
866 0 : *r_cb_value = NULL;
867 :
868 0 : if (!ctx || !ctx->status_cb)
869 0 : return;
870 :
871 0 : if (r_cb)
872 0 : *r_cb = ctx->status_cb;
873 0 : if (r_cb_value)
874 0 : *r_cb_value = ctx->status_cb_value;
875 : }
876 :
877 :
878 : /* Set the I/O callback functions for CTX to IO_CBS. */
879 : void
880 1 : gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
881 : {
882 1 : if (!ctx)
883 0 : return;
884 :
885 1 : if (io_cbs)
886 : {
887 1 : TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
888 : "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
889 : io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
890 : io_cbs->event, io_cbs->event_priv);
891 1 : ctx->io_cbs = *io_cbs;
892 : }
893 : else
894 : {
895 0 : TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
896 : "io_cbs=%p (default)", io_cbs);
897 0 : ctx->io_cbs.add = NULL;
898 0 : ctx->io_cbs.add_priv = NULL;
899 0 : ctx->io_cbs.remove = NULL;
900 0 : ctx->io_cbs.event = NULL;
901 0 : ctx->io_cbs.event_priv = NULL;
902 : }
903 : }
904 :
905 :
906 : /* This function provides access to the internal read function; it is
907 : normally not used. */
908 : gpgme_ssize_t
909 0 : gpgme_io_read (int fd, void *buffer, size_t count)
910 : {
911 : int ret;
912 0 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
913 : "buffer=%p, count=%u", buffer, count);
914 :
915 0 : ret = _gpgme_io_read (fd, buffer, count);
916 :
917 0 : return TRACE_SYSRES (ret);
918 : }
919 :
920 :
921 : /* This function provides access to the internal write function. It
922 : is to be used by user callbacks to return data to gpgme. See
923 : gpgme_passphrase_cb_t and gpgme_edit_cb_t. */
924 : gpgme_ssize_t
925 26 : gpgme_io_write (int fd, const void *buffer, size_t count)
926 : {
927 : int ret;
928 26 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd,
929 : "buffer=%p, count=%u", buffer, count);
930 :
931 26 : ret = _gpgme_io_write (fd, buffer, count);
932 :
933 26 : return TRACE_SYSRES (ret);
934 : }
935 :
936 : /* This function provides access to the internal write function. It
937 : is to be used by user callbacks to return data to gpgme. See
938 : gpgme_passphrase_cb_t and gpgme_edit_cb_t. Note that this is a
939 : variant of gpgme_io_write which guarantees that all COUNT bytes are
940 : written or an error is return. Returns: 0 on success or -1 on
941 : error and the sets errno. */
942 : int
943 14 : gpgme_io_writen (int fd, const void *buffer_arg, size_t count)
944 : {
945 14 : const char *buffer = buffer_arg;
946 14 : int ret = 0;
947 14 : TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_writen", fd,
948 : "buffer=%p, count=%u", buffer, count);
949 42 : while (count)
950 : {
951 14 : ret = _gpgme_io_write (fd, buffer, count);
952 14 : if (ret < 0)
953 0 : break;
954 14 : buffer += ret;
955 14 : count -= ret;
956 14 : ret = 0;
957 : }
958 14 : return TRACE_SYSRES (ret);
959 : }
960 :
961 :
962 : /* This function returns the callback function for I/O. */
963 : void
964 0 : gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
965 : {
966 0 : TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
967 : "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
968 : io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
969 : io_cbs->event, io_cbs->event_priv);
970 :
971 0 : *io_cbs = ctx->io_cbs;
972 0 : }
973 :
974 :
975 : /* This function sets the locale for the context CTX, or the default
976 : locale if CTX is a null pointer. */
977 : gpgme_error_t
978 142 : gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
979 : {
980 142 : int failed = 0;
981 142 : char *new_lc_ctype = NULL;
982 142 : char *new_lc_messages = NULL;
983 :
984 142 : TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
985 : "category=%i, value=%s", category, value ? value : "(null)");
986 :
987 : #define PREPARE_ONE_LOCALE(lcat, ucat) \
988 : if (!failed && value \
989 : && (category == LC_ALL || category == LC_ ## ucat)) \
990 : { \
991 : new_lc_ ## lcat = strdup (value); \
992 : if (!new_lc_ ## lcat) \
993 : failed = 1; \
994 : }
995 :
996 : #ifdef LC_CTYPE
997 142 : PREPARE_ONE_LOCALE (ctype, CTYPE);
998 : #endif
999 : #ifdef LC_MESSAGES
1000 142 : PREPARE_ONE_LOCALE (messages, MESSAGES);
1001 : #endif
1002 :
1003 142 : if (failed)
1004 : {
1005 0 : int saved_err = gpg_error_from_syserror ();
1006 :
1007 0 : if (new_lc_ctype)
1008 0 : free (new_lc_ctype);
1009 0 : if (new_lc_messages)
1010 0 : free (new_lc_messages);
1011 :
1012 0 : return TRACE_ERR (saved_err);
1013 : }
1014 :
1015 : #define SET_ONE_LOCALE(lcat, ucat) \
1016 : if (category == LC_ALL || category == LC_ ## ucat) \
1017 : { \
1018 : if (ctx) \
1019 : { \
1020 : if (ctx->lc_ ## lcat) \
1021 : free (ctx->lc_ ## lcat); \
1022 : ctx->lc_ ## lcat = new_lc_ ## lcat; \
1023 : } \
1024 : else \
1025 : { \
1026 : if (def_lc_ ## lcat) \
1027 : free (def_lc_ ## lcat); \
1028 : def_lc_ ## lcat = new_lc_ ## lcat; \
1029 : } \
1030 : }
1031 :
1032 142 : if (!ctx)
1033 142 : LOCK (def_lc_lock);
1034 : #ifdef LC_CTYPE
1035 142 : SET_ONE_LOCALE (ctype, CTYPE);
1036 : #endif
1037 : #ifdef LC_MESSAGES
1038 142 : SET_ONE_LOCALE (messages, MESSAGES);
1039 : #endif
1040 142 : if (!ctx)
1041 142 : UNLOCK (def_lc_lock);
1042 :
1043 142 : return TRACE_ERR (0);
1044 : }
1045 :
1046 :
1047 : /* Get the information about the configured engines. A pointer to the
1048 : first engine in the statically allocated linked list is returned.
1049 : The returned data is valid until the next gpgme_ctx_set_engine_info. */
1050 : gpgme_engine_info_t
1051 318 : gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
1052 : {
1053 318 : TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
1054 : "ctx->engine_info=%p", ctx->engine_info);
1055 318 : return ctx->engine_info;
1056 : }
1057 :
1058 :
1059 : /* Set the engine info for the context CTX, protocol PROTO, to the
1060 : file name FILE_NAME and the home directory HOME_DIR. */
1061 : gpgme_error_t
1062 427 : gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
1063 : const char *file_name, const char *home_dir)
1064 : {
1065 : gpgme_error_t err;
1066 427 : TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
1067 : "protocol=%i (%s), file_name=%s, home_dir=%s",
1068 : proto, gpgme_get_protocol_name (proto)
1069 : ? gpgme_get_protocol_name (proto) : "unknown",
1070 : file_name ? file_name : "(default)",
1071 : home_dir ? home_dir : "(default)");
1072 :
1073 427 : if (!ctx)
1074 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1075 :
1076 : /* Shut down the engine when changing engine info. */
1077 427 : if (ctx->engine)
1078 : {
1079 1 : TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
1080 1 : _gpgme_engine_release (ctx->engine);
1081 1 : ctx->engine = NULL;
1082 : }
1083 427 : err = _gpgme_set_engine_info (ctx->engine_info, proto,
1084 : file_name, home_dir);
1085 428 : return TRACE_ERR (err);
1086 : }
1087 :
1088 :
1089 : /* Clear all notation data from the context. */
1090 : void
1091 727 : _gpgme_sig_notation_clear (gpgme_ctx_t ctx)
1092 : {
1093 : gpgme_sig_notation_t notation;
1094 :
1095 727 : if (!ctx)
1096 0 : return;
1097 :
1098 727 : notation = ctx->sig_notations;
1099 1463 : while (notation)
1100 : {
1101 9 : gpgme_sig_notation_t next_notation = notation->next;
1102 9 : _gpgme_sig_notation_free (notation);
1103 9 : notation = next_notation;
1104 : }
1105 727 : ctx->sig_notations = NULL;
1106 : }
1107 :
1108 : void
1109 0 : gpgme_sig_notation_clear (gpgme_ctx_t ctx)
1110 : {
1111 0 : TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
1112 :
1113 0 : if (!ctx)
1114 0 : return;
1115 :
1116 0 : _gpgme_sig_notation_clear (ctx);
1117 : }
1118 :
1119 :
1120 : /* Add the human-readable notation data with name NAME and value VALUE
1121 : to the context CTX, using the flags FLAGS. If NAME is NULL, then
1122 : VALUE should be a policy URL. The flag
1123 : GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
1124 : data, and false for policy URLs. */
1125 : gpgme_error_t
1126 9 : gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
1127 : const char *value, gpgme_sig_notation_flags_t flags)
1128 : {
1129 : gpgme_error_t err;
1130 : gpgme_sig_notation_t notation;
1131 : gpgme_sig_notation_t *lastp;
1132 :
1133 9 : TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
1134 : "name=%s, value=%s, flags=0x%x",
1135 : name ? name : "(null)", value ? value : "(null)",
1136 : flags);
1137 :
1138 9 : if (!ctx)
1139 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1140 :
1141 9 : if (name)
1142 6 : flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
1143 : else
1144 3 : flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
1145 :
1146 18 : err = _gpgme_sig_notation_create (¬ation, name, name ? strlen (name) : 0,
1147 9 : value, value ? strlen (value) : 0, flags);
1148 9 : if (err)
1149 0 : return TRACE_ERR (err);
1150 :
1151 9 : lastp = &ctx->sig_notations;
1152 27 : while (*lastp)
1153 9 : lastp = &(*lastp)->next;
1154 :
1155 9 : *lastp = notation;
1156 9 : return TRACE_ERR (0);
1157 : }
1158 :
1159 :
1160 : /* Get the sig notations for this context. */
1161 : gpgme_sig_notation_t
1162 65 : gpgme_sig_notation_get (gpgme_ctx_t ctx)
1163 : {
1164 65 : if (!ctx)
1165 : {
1166 0 : TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
1167 0 : return NULL;
1168 : }
1169 65 : TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
1170 : "ctx->sig_notations=%p", ctx->sig_notations);
1171 :
1172 65 : return ctx->sig_notations;
1173 : }
1174 :
1175 :
1176 :
1177 : /* Return a public key algorithm string made of the algorithm and size
1178 : or the curve name. May return NULL on error. Caller must free the
1179 : result using gpgme_free. */
1180 : char *
1181 10 : gpgme_pubkey_algo_string (gpgme_subkey_t subkey)
1182 : {
1183 10 : const char *prefix = NULL;
1184 : char *result;
1185 :
1186 10 : if (!subkey)
1187 : {
1188 0 : gpg_err_set_errno (EINVAL);
1189 0 : return NULL;
1190 : }
1191 :
1192 10 : switch (subkey->pubkey_algo)
1193 : {
1194 : case GPGME_PK_RSA:
1195 : case GPGME_PK_RSA_E:
1196 0 : case GPGME_PK_RSA_S: prefix = "rsa"; break;
1197 5 : case GPGME_PK_ELG_E: prefix = "elg"; break;
1198 5 : case GPGME_PK_DSA: prefix = "dsa"; break;
1199 0 : case GPGME_PK_ELG: prefix = "xxx"; break;
1200 : case GPGME_PK_ECC:
1201 : case GPGME_PK_ECDH:
1202 : case GPGME_PK_ECDSA:
1203 0 : case GPGME_PK_EDDSA: prefix = ""; break;
1204 : }
1205 :
1206 10 : if (prefix && *prefix)
1207 10 : {
1208 : char buffer[40];
1209 10 : snprintf (buffer, sizeof buffer, "%s%u", prefix, subkey->length);
1210 10 : result = strdup (buffer);
1211 : }
1212 0 : else if (prefix && subkey->curve && *subkey->curve)
1213 0 : result = strdup (subkey->curve);
1214 0 : else if (prefix)
1215 0 : result = strdup ("E_error");
1216 : else
1217 0 : result = strdup ("unknown");
1218 :
1219 10 : return result;
1220 : }
1221 :
1222 :
1223 : const char *
1224 91 : gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
1225 : {
1226 91 : switch (algo)
1227 : {
1228 6 : case GPGME_PK_RSA: return "RSA";
1229 1 : case GPGME_PK_RSA_E: return "RSA-E";
1230 1 : case GPGME_PK_RSA_S: return "RSA-S";
1231 9 : case GPGME_PK_ELG_E: return "ELG-E";
1232 60 : case GPGME_PK_DSA: return "DSA";
1233 1 : case GPGME_PK_ECC: return "ECC";
1234 1 : case GPGME_PK_ELG: return "ELG";
1235 1 : case GPGME_PK_ECDSA: return "ECDSA";
1236 1 : case GPGME_PK_ECDH: return "ECDH";
1237 4 : case GPGME_PK_EDDSA: return "EdDSA";
1238 6 : default: return NULL;
1239 : }
1240 : }
1241 :
1242 :
1243 : const char *
1244 68 : gpgme_hash_algo_name (gpgme_hash_algo_t algo)
1245 : {
1246 68 : switch (algo)
1247 : {
1248 : case GPGME_MD_MD5:
1249 0 : return "MD5";
1250 :
1251 : case GPGME_MD_SHA1:
1252 45 : return "SHA1";
1253 :
1254 : case GPGME_MD_RMD160:
1255 10 : return "RIPEMD160";
1256 :
1257 : case GPGME_MD_MD2:
1258 0 : return "MD2";
1259 :
1260 : case GPGME_MD_TIGER:
1261 0 : return "TIGER192";
1262 :
1263 : case GPGME_MD_HAVAL:
1264 0 : return "HAVAL";
1265 :
1266 : case GPGME_MD_SHA256:
1267 3 : return "SHA256";
1268 :
1269 : case GPGME_MD_SHA384:
1270 0 : return "SHA384";
1271 :
1272 : case GPGME_MD_SHA512:
1273 4 : return "SHA512";
1274 :
1275 : case GPGME_MD_SHA224:
1276 0 : return "SHA224";
1277 :
1278 : case GPGME_MD_MD4:
1279 0 : return "MD4";
1280 :
1281 : case GPGME_MD_CRC32:
1282 0 : return "CRC32";
1283 :
1284 : case GPGME_MD_CRC32_RFC1510:
1285 0 : return "CRC32RFC1510";
1286 :
1287 : case GPGME_MD_CRC24_RFC2440:
1288 0 : return "CRC24RFC2440";
1289 :
1290 : default:
1291 6 : return NULL;
1292 : }
1293 : }
|