2009-06-18 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / src / gpgme.c
1 /* gpgme.c - GnuPG Made Easy.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH
4
5    This file is part of GPGME.
6  
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11    
12    GPGME is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16    
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
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 #include <locale.h>
31
32 #include "util.h"
33 #include "context.h"
34 #include "ops.h"
35 #include "wait.h"
36 #include "debug.h"
37 #include "priv-io.h"
38
39 \f
40 /* The default locale.  */
41 DEFINE_STATIC_LOCK (def_lc_lock);
42 static char *def_lc_ctype;
43 static char *def_lc_messages;
44
45 \f
46 gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
47
48 /* Protects all reference counters in result structures.  All other
49    accesses to a key are read only.  */
50 DEFINE_STATIC_LOCK (result_ref_lock);
51
52 \f
53 /* Create a new context as an environment for GPGME crypto
54    operations.  */
55 gpgme_error_t
56 gpgme_new (gpgme_ctx_t *r_ctx)
57 {
58   gpgme_ctx_t ctx;
59   TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
60
61   if (_gpgme_selftest)
62     return TRACE_ERR (gpgme_error (_gpgme_selftest));
63
64   ctx = calloc (1, sizeof *ctx);
65   if (!ctx)
66     return TRACE_ERR (gpg_error_from_errno (errno));
67
68   INIT_LOCK (ctx->lock);
69   
70   _gpgme_engine_info_copy (&ctx->engine_info);
71   if (!ctx->engine_info)
72     {
73       free (ctx);
74       return TRACE_ERR (gpg_error_from_errno (errno));
75     }
76
77   ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
78   ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
79   ctx->protocol = GPGME_PROTOCOL_OpenPGP;
80   _gpgme_fd_table_init (&ctx->fdt);
81
82   LOCK (def_lc_lock);
83   if (def_lc_ctype)
84     {
85       ctx->lc_ctype = strdup (def_lc_ctype);
86       if (!ctx->lc_ctype)
87         {
88           UNLOCK (def_lc_lock);
89           _gpgme_engine_info_release (ctx->engine_info);
90           free (ctx);
91           return TRACE_ERR (gpg_error_from_errno (errno));
92         }
93     }
94   else
95     def_lc_ctype = NULL;
96
97   if (def_lc_messages)
98     {
99       ctx->lc_messages = strdup (def_lc_messages);
100       if (!ctx->lc_messages)
101         {
102           UNLOCK (def_lc_lock);
103           if (ctx->lc_ctype)
104             free (ctx->lc_ctype);
105           _gpgme_engine_info_release (ctx->engine_info);
106           free (ctx);
107           return TRACE_ERR (gpg_error_from_errno (errno));
108         }
109     }
110   else
111     def_lc_messages = NULL;
112   UNLOCK (def_lc_lock);
113
114   *r_ctx = ctx;
115
116   return TRACE_SUC1 ("ctx=%p", ctx);
117 }
118
119
120 gpgme_error_t
121 _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err)
122 {
123   gpgme_error_t err;
124   TRACE_BEG1 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i",
125               ctx_err);
126
127   err = _gpgme_engine_cancel (ctx->engine);
128   if (err)
129     return TRACE_ERR (err);
130
131   _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &ctx_err);
132
133   return TRACE_ERR (0);
134 }
135
136
137 /* Cancel a pending asynchronous operation.  */
138 gpgme_error_t
139 gpgme_cancel (gpgme_ctx_t ctx)
140 {
141   return _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED));
142 }
143
144
145 /* Cancel a pending operation asynchronously.  */
146 gpgme_error_t
147 gpgme_cancel_async (gpgme_ctx_t ctx)
148 {
149   TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
150
151   LOCK (ctx->lock);
152   ctx->canceled = 1;
153   UNLOCK (ctx->lock);
154
155   return TRACE_ERR (0);
156 }
157
158
159 /* Release all resources associated with the given context.  */
160 void
161 gpgme_release (gpgme_ctx_t ctx)
162 {
163   TRACE (DEBUG_CTX, "gpgme_release", ctx);
164
165   _gpgme_engine_release (ctx->engine);
166   _gpgme_fd_table_deinit (&ctx->fdt);
167   _gpgme_release_result (ctx);
168   gpgme_signers_clear (ctx);
169   gpgme_sig_notation_clear (ctx);
170   if (ctx->signers)
171     free (ctx->signers);
172   if (ctx->lc_ctype)
173     free (ctx->lc_ctype);
174   if (ctx->lc_messages)
175     free (ctx->lc_messages);
176   _gpgme_engine_info_release (ctx->engine_info);
177   DESTROY_LOCK (ctx->lock);
178   free (ctx);
179 }
180
181
182 void
183 gpgme_result_ref (void *result)
184 {
185   struct ctx_op_data *data;
186
187   if (! result)
188     return;
189
190   data = result - sizeof (struct ctx_op_data);
191
192   assert (data->magic == CTX_OP_DATA_MAGIC);
193
194   LOCK (result_ref_lock);
195   data->references++;
196   UNLOCK (result_ref_lock);
197 }
198
199
200 void
201 gpgme_result_unref (void *result)
202 {
203   struct ctx_op_data *data;
204
205   if (! result)
206     return;
207
208   data = result - sizeof (struct ctx_op_data);
209
210   assert (data->magic == CTX_OP_DATA_MAGIC);
211
212   LOCK (result_ref_lock);
213   if (--data->references)
214     {
215       UNLOCK (result_ref_lock);
216       return;
217     }
218   UNLOCK (result_ref_lock);
219
220   if (data->cleanup)
221     (*data->cleanup) (data->hook);
222   free (data);
223 }
224
225
226 void
227 _gpgme_release_result (gpgme_ctx_t ctx)
228 {
229   struct ctx_op_data *data = ctx->op_data;
230
231   while (data)
232     {
233       struct ctx_op_data *next_data = data->next;
234       data->next = NULL;
235       gpgme_result_unref (data->hook);
236       data = next_data;
237     }
238   ctx->op_data = NULL;
239 }
240
241
242 gpgme_error_t
243 gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
244 {
245   TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
246               protocol, gpgme_get_protocol_name (protocol)
247               ? gpgme_get_protocol_name (protocol) : "unknown");
248
249   if (protocol != GPGME_PROTOCOL_OpenPGP
250       && protocol != GPGME_PROTOCOL_CMS
251       && protocol != GPGME_PROTOCOL_ASSUAN)
252     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
253
254   if (ctx->protocol != protocol)
255     {
256       /* Shut down the engine when switching protocols.  */
257       if (ctx->engine)
258         {
259           TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
260           _gpgme_engine_release (ctx->engine);
261           ctx->engine = NULL;
262         }
263
264       ctx->protocol = protocol;
265     }
266   return TRACE_ERR (0);
267 }
268
269
270 gpgme_protocol_t
271 gpgme_get_protocol (gpgme_ctx_t ctx)
272 {
273   TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
274           "ctx->protocol=%i (%s)", ctx->protocol,
275           gpgme_get_protocol_name (ctx->protocol)
276           ? gpgme_get_protocol_name (ctx->protocol) : "unknown");
277   return ctx->protocol;
278 }
279
280
281 const char *
282 gpgme_get_protocol_name (gpgme_protocol_t protocol)
283 {
284   switch (protocol)
285     {
286     case GPGME_PROTOCOL_OpenPGP:
287       return "OpenPGP";
288
289     case GPGME_PROTOCOL_CMS:
290       return "CMS";
291
292     case GPGME_PROTOCOL_ASSUAN:
293       return "Assuan";
294
295     case GPGME_PROTOCOL_UNKNOWN:
296       return "unknown";
297
298     default:
299       return NULL;
300     }
301 }
302
303 /* Enable or disable the use of an ascii armor for all output.  */
304 void
305 gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
306 {
307   TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
308           use_armor, use_armor ? "yes" : "no");
309   ctx->use_armor = use_armor;
310 }
311
312
313 /* Return the state of the armor flag.  */
314 int
315 gpgme_get_armor (gpgme_ctx_t ctx)
316 {
317   TRACE2 (DEBUG_CTX, "gpgme_get_armor", ctx, "ctx->use_armor=%i (%s)",
318           ctx->use_armor, ctx->use_armor ? "yes" : "no");
319   return ctx->use_armor;
320 }
321
322
323 /* Enable or disable the use of the special textmode.  Textmode is for
324   example used for the RFC2015 signatures; note that the updated RFC
325   3156 mandates that the MUA does some preparations so that textmode
326   is not needed anymore.  */
327 void
328 gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
329 {
330   TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
331           use_textmode, use_textmode ? "yes" : "no");
332   ctx->use_textmode = use_textmode;
333 }
334
335 /* Return the state of the textmode flag.  */
336 int
337 gpgme_get_textmode (gpgme_ctx_t ctx)
338 {
339   TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
340           ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
341   return ctx->use_textmode;
342 }
343
344
345 /* Set the number of certifications to include in an S/MIME message.
346    The default is GPGME_INCLUDE_CERTS_DEFAULT.  -1 means all certs,
347    and -2 means all certs except the root cert.  */
348 void
349 gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
350 {
351   if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
352     ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
353   else if (nr_of_certs < -2)
354     ctx->include_certs = -2;
355   else
356     ctx->include_certs = nr_of_certs;
357
358   TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
359           nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
360 }
361
362
363 /* Get the number of certifications to include in an S/MIME
364    message.  */
365 int
366 gpgme_get_include_certs (gpgme_ctx_t ctx)
367 {
368   TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
369           ctx->include_certs);
370   return ctx->include_certs;
371 }
372
373
374 /* This function changes the default behaviour of the keylisting
375    functions.  MODE is a bitwise-OR of the GPGME_KEYLIST_* flags.  The
376    default mode is GPGME_KEYLIST_MODE_LOCAL.  */
377 gpgme_error_t
378 gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
379 {
380   TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
381           mode);
382
383   ctx->keylist_mode = mode;
384   return 0;
385 }
386
387 /* This function returns the default behaviour of the keylisting
388    functions.  */
389 gpgme_keylist_mode_t
390 gpgme_get_keylist_mode (gpgme_ctx_t ctx)
391 {
392   TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
393           "ctx->keylist_mode=0x%x", ctx->keylist_mode);
394   return ctx->keylist_mode;
395 }
396
397
398 /* This function sets a callback function to be used to pass a
399    passphrase to gpg.  */
400 void
401 gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
402                          void *cb_value)
403 {
404   TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
405           "passphrase_cb=%p/%p", cb, cb_value);
406   ctx->passphrase_cb = cb;
407   ctx->passphrase_cb_value = cb_value;
408 }
409
410
411 /* This function returns the callback function to be used to pass a
412    passphrase to the crypto engine.  */
413 void
414 gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
415                          void **r_cb_value)
416 {
417   TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
418           "ctx->passphrase_cb=%p/%p",
419           ctx->passphrase_cb, ctx->passphrase_cb_value);
420   if (r_cb)
421     *r_cb = ctx->passphrase_cb;
422   if (r_cb_value)
423     *r_cb_value = ctx->passphrase_cb_value;
424 }
425
426
427 /* This function sets a callback function to be used as a progress
428    indicator.  */
429 void
430 gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
431 {
432   TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
433           cb, cb_value);
434   ctx->progress_cb = cb;
435   ctx->progress_cb_value = cb_value;
436 }
437
438
439 /* This function returns the callback function to be used as a
440    progress indicator.  */
441 void
442 gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
443                        void **r_cb_value)
444 {
445   TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
446           ctx->progress_cb, ctx->progress_cb_value);
447   if (r_cb)
448     *r_cb = ctx->progress_cb;
449   if (r_cb_value)
450     *r_cb_value = ctx->progress_cb_value;
451 }
452
453
454 /* Set the I/O callback functions for CTX to IO_CBS.  */
455 void
456 gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
457 {
458   if (io_cbs)
459     {
460       TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
461               "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
462               io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
463               io_cbs->event, io_cbs->event_priv);
464       ctx->io_cbs = *io_cbs;
465     }
466   else
467     {
468       TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
469               "io_cbs=%p (default)", io_cbs);
470       ctx->io_cbs.add = NULL;
471       ctx->io_cbs.add_priv = NULL;
472       ctx->io_cbs.remove = NULL;
473       ctx->io_cbs.event = NULL;
474       ctx->io_cbs.event_priv = NULL;
475     }
476 }
477
478
479 /* This function provides access to the internal read function; it is
480    normally not used.  */
481 ssize_t
482 gpgme_io_read (int fd, void *buffer, size_t count)
483 {
484   int ret;
485
486   ret = _gpgme_io_read (fd, buffer, count);
487
488   return ret;
489 }
490
491
492 /* This function provides access to the internal write function.  It
493    is to be used by user callbacks to return data to gpgme.  See
494    gpgme_passphrase_cb_t and gpgme_edit_cb_t.  */
495 ssize_t
496 gpgme_io_write (int fd, const void *buffer, size_t count)
497 {
498   int ret;
499
500   ret = _gpgme_io_write (fd, buffer, count);
501
502   return ret;
503 }
504
505
506 /* This function returns the callback function for I/O.  */
507 void
508 gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
509 {
510   TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
511           "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
512           io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
513           io_cbs->event, io_cbs->event_priv);
514
515   *io_cbs = ctx->io_cbs;
516 }
517
518 \f
519 /* This function sets the locale for the context CTX, or the default
520    locale if CTX is a null pointer.  */
521 gpgme_error_t
522 gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
523 {
524   int failed = 0;
525   char *new_lc_ctype = NULL;
526   char *new_lc_messages = NULL;
527
528   TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
529                "category=%i, value=%s", category, value ? value : "(null)");
530
531 #define PREPARE_ONE_LOCALE(lcat, ucat)                          \
532   if (!failed && value                                          \
533       && (category == LC_ALL || category == LC_ ## ucat))       \
534     {                                                           \
535       new_lc_ ## lcat = strdup (value);                         \
536       if (!new_lc_ ## lcat)                                     \
537         failed = 1;                                             \
538     }
539
540   PREPARE_ONE_LOCALE (ctype, CTYPE);
541 #ifdef LC_MESSAGES
542   PREPARE_ONE_LOCALE (messages, MESSAGES);
543 #endif
544
545   if (failed)
546     {
547       int saved_errno = errno;
548
549       if (new_lc_ctype)
550         free (new_lc_ctype);
551       if (new_lc_messages)
552         free (new_lc_messages);
553
554       return TRACE_ERR (gpg_error_from_errno (saved_errno));
555     }
556
557 #define SET_ONE_LOCALE(lcat, ucat)                      \
558   if (category == LC_ALL || category == LC_ ## ucat)    \
559     {                                                   \
560       if (ctx)                                          \
561         {                                               \
562           if (ctx->lc_ ## lcat)                         \
563             free (ctx->lc_ ## lcat);                    \
564           ctx->lc_ ## lcat = new_lc_ ## lcat;           \
565         }                                               \
566       else                                              \
567         {                                               \
568           if (def_lc_ ## lcat)                          \
569             free (def_lc_ ## lcat);                     \
570           def_lc_ ## lcat = new_lc_ ## lcat;            \
571         }                                               \
572     }
573
574   if (!ctx)
575     LOCK (def_lc_lock);
576   SET_ONE_LOCALE (ctype, CTYPE);
577 #ifdef LC_MESSAGES
578   SET_ONE_LOCALE (messages, MESSAGES);
579 #endif
580   if (!ctx)
581     UNLOCK (def_lc_lock);
582
583   return TRACE_ERR (0);
584 }
585
586 \f
587 /* Get the information about the configured engines.  A pointer to the
588    first engine in the statically allocated linked list is returned.
589    The returned data is valid until the next gpgme_ctx_set_engine_info.  */
590 gpgme_engine_info_t
591 gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
592 {
593   TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
594           "ctx->engine_info=%p", ctx->engine_info);
595   return ctx->engine_info;
596 }
597
598
599 /* Set the engine info for the context CTX, protocol PROTO, to the
600    file name FILE_NAME and the home directory HOME_DIR.  */
601 gpgme_error_t
602 gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
603                            const char *file_name, const char *home_dir)
604 {
605   gpgme_error_t err;
606   TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
607               "protocol=%i (%s), file_name=%s, home_dir=%s",
608               proto, gpgme_get_protocol_name (proto)
609               ? gpgme_get_protocol_name (proto) : "unknown",
610               file_name ? file_name : "(default)",
611               home_dir ? home_dir : "(default)");
612               
613   /* Shut down the engine when changing engine info.  */
614   if (ctx->engine)
615     {
616       TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
617       _gpgme_engine_release (ctx->engine);
618       ctx->engine = NULL;
619     }
620   err = _gpgme_set_engine_info (ctx->engine_info, proto,
621                                 file_name, home_dir);
622   return TRACE_ERR (err);
623 }
624
625 \f
626 /* Clear all notation data from the context.  */
627 void
628 gpgme_sig_notation_clear (gpgme_ctx_t ctx)
629 {
630   gpgme_sig_notation_t notation;
631   TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
632
633   if (!ctx)
634     return;
635
636   notation = ctx->sig_notations;
637   while (notation)
638     {
639       gpgme_sig_notation_t next_notation = notation->next;
640       _gpgme_sig_notation_free (notation);
641       notation = next_notation;
642     }
643   ctx->sig_notations = NULL;
644 }
645
646
647 /* Add the human-readable notation data with name NAME and value VALUE
648    to the context CTX, using the flags FLAGS.  If NAME is NULL, then
649    VALUE should be a policy URL.  The flag
650    GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
651    data, and false for policy URLs.  */
652 gpgme_error_t
653 gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
654                         const char *value, gpgme_sig_notation_flags_t flags)
655 {
656   gpgme_error_t err;
657   gpgme_sig_notation_t notation;
658   gpgme_sig_notation_t *lastp;
659
660   TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
661               "name=%s, value=%s, flags=0x%x",
662               name ? name : "(null)", value ? value : "(null)",
663               flags);
664   
665   if (!ctx)
666     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
667
668   if (name)
669     flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
670   else
671     flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
672
673   err = _gpgme_sig_notation_create (&notation, name, name ? strlen (name) : 0,
674                                     value, value ? strlen (value) : 0, flags);
675   if (err)
676     return TRACE_ERR (err);
677
678   lastp = &ctx->sig_notations;
679   while (*lastp)
680     lastp = &(*lastp)->next;
681
682   *lastp = notation;
683   return TRACE_ERR (0);
684 }
685
686
687 /* Get the sig notations for this context.  */
688 gpgme_sig_notation_t
689 gpgme_sig_notation_get (gpgme_ctx_t ctx)
690 {
691   if (!ctx)
692     {
693       TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
694       return NULL;
695     }
696   TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
697           "ctx->sig_notations=%p", ctx->sig_notations);
698
699   return ctx->sig_notations;
700 }
701   
702 \f
703 const char *
704 gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
705 {
706   switch (algo)
707     {
708     case GPGME_PK_RSA:
709       return "RSA";
710
711     case GPGME_PK_RSA_E:
712       return "RSA-E";
713
714     case GPGME_PK_RSA_S:
715       return "RSA-S";
716
717     case GPGME_PK_ELG_E:
718       return "ELG-E";
719
720     case GPGME_PK_DSA:
721       return "DSA";
722
723     case GPGME_PK_ELG:
724       return "ELG";
725
726     default:
727       return NULL;
728     }
729 }
730
731
732 const char *
733 gpgme_hash_algo_name (gpgme_hash_algo_t algo)
734 {
735   switch (algo)
736     {
737     case GPGME_MD_MD5:
738       return "MD5";
739
740     case GPGME_MD_SHA1:
741       return "SHA1";
742
743     case GPGME_MD_RMD160:
744       return "RIPEMD160";
745
746     case GPGME_MD_MD2:
747       return "MD2";
748
749     case GPGME_MD_TIGER:
750       return "TIGER192";
751
752     case GPGME_MD_HAVAL:
753       return "HAVAL";
754
755     case GPGME_MD_SHA256:
756       return "SHA256";
757
758     case GPGME_MD_SHA384:
759       return "SHA384";
760
761     case GPGME_MD_SHA512:
762       return "SHA512";
763
764     case GPGME_MD_MD4:
765       return "MD4";
766
767     case GPGME_MD_CRC32:
768       return "CRC32";
769
770     case GPGME_MD_CRC32_RFC1510:
771       return "CRC32RFC1510";
772
773     case GPGME_MD_CRC24_RFC2440:
774       return "CRC24RFC2440";
775
776     default:
777       return NULL;
778     }
779 }