2009-06-16 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   LOCK (result_ref_lock);
193   data->references++;
194   UNLOCK (result_ref_lock);
195 }
196
197
198 void
199 gpgme_result_unref (void *result)
200 {
201   struct ctx_op_data *data;
202
203   if (! result)
204     return;
205
206   data = result - sizeof (struct ctx_op_data);
207
208   LOCK (result_ref_lock);
209   if (--data->references)
210     {
211       UNLOCK (result_ref_lock);
212       return;
213     }
214   UNLOCK (result_ref_lock);
215
216   if (data->cleanup)
217     (*data->cleanup) (data->hook);
218   free (data);
219 }
220
221
222 void
223 _gpgme_release_result (gpgme_ctx_t ctx)
224 {
225   struct ctx_op_data *data = ctx->op_data;
226
227   while (data)
228     {
229       struct ctx_op_data *next_data = data->next;
230       data->next = NULL;
231       gpgme_result_unref (data->hook);
232       data = next_data;
233     }
234   ctx->op_data = NULL;
235 }
236
237
238 gpgme_error_t
239 gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
240 {
241   TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
242               protocol, gpgme_get_protocol_name (protocol)
243               ? gpgme_get_protocol_name (protocol) : "unknown");
244
245   if (protocol != GPGME_PROTOCOL_OpenPGP
246       && protocol != GPGME_PROTOCOL_CMS
247       && protocol != GPGME_PROTOCOL_ASSUAN)
248     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
249
250   if (ctx->protocol != protocol)
251     {
252       /* Shut down the engine when switching protocols.  */
253       if (ctx->engine)
254         {
255           TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
256           _gpgme_engine_release (ctx->engine);
257           ctx->engine = NULL;
258         }
259
260       ctx->protocol = protocol;
261     }
262   return TRACE_ERR (0);
263 }
264
265
266 gpgme_protocol_t
267 gpgme_get_protocol (gpgme_ctx_t ctx)
268 {
269   TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
270           "ctx->protocol=%i (%s)", ctx->protocol,
271           gpgme_get_protocol_name (ctx->protocol)
272           ? gpgme_get_protocol_name (ctx->protocol) : "unknown");
273   return ctx->protocol;
274 }
275
276
277 const char *
278 gpgme_get_protocol_name (gpgme_protocol_t protocol)
279 {
280   switch (protocol)
281     {
282     case GPGME_PROTOCOL_OpenPGP:
283       return "OpenPGP";
284
285     case GPGME_PROTOCOL_CMS:
286       return "CMS";
287
288     case GPGME_PROTOCOL_ASSUAN:
289       return "Assuan";
290
291     case GPGME_PROTOCOL_UNKNOWN:
292       return "unknown";
293
294     default:
295       return NULL;
296     }
297 }
298
299 /* Enable or disable the use of an ascii armor for all output.  */
300 void
301 gpgme_set_armor (gpgme_ctx_t ctx, int use_armor)
302 {
303   TRACE2 (DEBUG_CTX, "gpgme_set_armor", ctx, "use_armor=%i (%s)",
304           use_armor, use_armor ? "yes" : "no");
305   ctx->use_armor = use_armor;
306 }
307
308
309 /* Return the state of the armor flag.  */
310 int
311 gpgme_get_armor (gpgme_ctx_t ctx)
312 {
313   TRACE2 (DEBUG_CTX, "gpgme_get_armor", ctx, "ctx->use_armor=%i (%s)",
314           ctx->use_armor, ctx->use_armor ? "yes" : "no");
315   return ctx->use_armor;
316 }
317
318
319 /* Enable or disable the use of the special textmode.  Textmode is for
320   example used for the RFC2015 signatures; note that the updated RFC
321   3156 mandates that the MUA does some preparations so that textmode
322   is not needed anymore.  */
323 void
324 gpgme_set_textmode (gpgme_ctx_t ctx, int use_textmode)
325 {
326   TRACE2 (DEBUG_CTX, "gpgme_set_textmode", ctx, "use_textmode=%i (%s)",
327           use_textmode, use_textmode ? "yes" : "no");
328   ctx->use_textmode = use_textmode;
329 }
330
331 /* Return the state of the textmode flag.  */
332 int
333 gpgme_get_textmode (gpgme_ctx_t ctx)
334 {
335   TRACE2 (DEBUG_CTX, "gpgme_get_textmode", ctx, "ctx->use_textmode=%i (%s)",
336           ctx->use_textmode, ctx->use_textmode ? "yes" : "no");
337   return ctx->use_textmode;
338 }
339
340
341 /* Set the number of certifications to include in an S/MIME message.
342    The default is GPGME_INCLUDE_CERTS_DEFAULT.  -1 means all certs,
343    and -2 means all certs except the root cert.  */
344 void
345 gpgme_set_include_certs (gpgme_ctx_t ctx, int nr_of_certs)
346 {
347   if (nr_of_certs == GPGME_INCLUDE_CERTS_DEFAULT)
348     ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
349   else if (nr_of_certs < -2)
350     ctx->include_certs = -2;
351   else
352     ctx->include_certs = nr_of_certs;
353
354   TRACE2 (DEBUG_CTX, "gpgme_set_include_certs", ctx, "nr_of_certs=%i%s",
355           nr_of_certs, nr_of_certs == ctx->include_certs ? "" : " (-2)");
356 }
357
358
359 /* Get the number of certifications to include in an S/MIME
360    message.  */
361 int
362 gpgme_get_include_certs (gpgme_ctx_t ctx)
363 {
364   TRACE1 (DEBUG_CTX, "gpgme_get_include_certs", ctx, "ctx->include_certs=%i",
365           ctx->include_certs);
366   return ctx->include_certs;
367 }
368
369
370 /* This function changes the default behaviour of the keylisting
371    functions.  MODE is a bitwise-OR of the GPGME_KEYLIST_* flags.  The
372    default mode is GPGME_KEYLIST_MODE_LOCAL.  */
373 gpgme_error_t
374 gpgme_set_keylist_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
375 {
376   TRACE1 (DEBUG_CTX, "gpgme_set_keylist_mode", ctx, "keylist_mode=0x%x",
377           mode);
378
379   ctx->keylist_mode = mode;
380   return 0;
381 }
382
383 /* This function returns the default behaviour of the keylisting
384    functions.  */
385 gpgme_keylist_mode_t
386 gpgme_get_keylist_mode (gpgme_ctx_t ctx)
387 {
388   TRACE1 (DEBUG_CTX, "gpgme_get_keylist_mode", ctx,
389           "ctx->keylist_mode=0x%x", ctx->keylist_mode);
390   return ctx->keylist_mode;
391 }
392
393
394 /* This function sets a callback function to be used to pass a
395    passphrase to gpg.  */
396 void
397 gpgme_set_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb,
398                          void *cb_value)
399 {
400   TRACE2 (DEBUG_CTX, "gpgme_set_passphrase_cb", ctx,
401           "passphrase_cb=%p/%p", cb, cb_value);
402   ctx->passphrase_cb = cb;
403   ctx->passphrase_cb_value = cb_value;
404 }
405
406
407 /* This function returns the callback function to be used to pass a
408    passphrase to the crypto engine.  */
409 void
410 gpgme_get_passphrase_cb (gpgme_ctx_t ctx, gpgme_passphrase_cb_t *r_cb,
411                          void **r_cb_value)
412 {
413   TRACE2 (DEBUG_CTX, "gpgme_get_passphrase_cb", ctx,
414           "ctx->passphrase_cb=%p/%p",
415           ctx->passphrase_cb, ctx->passphrase_cb_value);
416   if (r_cb)
417     *r_cb = ctx->passphrase_cb;
418   if (r_cb_value)
419     *r_cb_value = ctx->passphrase_cb_value;
420 }
421
422
423 /* This function sets a callback function to be used as a progress
424    indicator.  */
425 void
426 gpgme_set_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t cb, void *cb_value)
427 {
428   TRACE2 (DEBUG_CTX, "gpgme_set_progress_cb", ctx, "progress_cb=%p/%p",
429           cb, cb_value);
430   ctx->progress_cb = cb;
431   ctx->progress_cb_value = cb_value;
432 }
433
434
435 /* This function returns the callback function to be used as a
436    progress indicator.  */
437 void
438 gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb,
439                        void **r_cb_value)
440 {
441   TRACE2 (DEBUG_CTX, "gpgme_get_progress_cb", ctx, "ctx->progress_cb=%p/%p",
442           ctx->progress_cb, ctx->progress_cb_value);
443   if (r_cb)
444     *r_cb = ctx->progress_cb;
445   if (r_cb_value)
446     *r_cb_value = ctx->progress_cb_value;
447 }
448
449
450 /* Set the I/O callback functions for CTX to IO_CBS.  */
451 void
452 gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
453 {
454   if (io_cbs)
455     {
456       TRACE6 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
457               "io_cbs=%p (add=%p/%p, remove=%p, event=%p/%p",
458               io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
459               io_cbs->event, io_cbs->event_priv);
460       ctx->io_cbs = *io_cbs;
461     }
462   else
463     {
464       TRACE1 (DEBUG_CTX, "gpgme_set_io_cbs", ctx,
465               "io_cbs=%p (default)", io_cbs);
466       ctx->io_cbs.add = NULL;
467       ctx->io_cbs.add_priv = NULL;
468       ctx->io_cbs.remove = NULL;
469       ctx->io_cbs.event = NULL;
470       ctx->io_cbs.event_priv = NULL;
471     }
472 }
473
474
475 /* This function provides access to the internal read function; it is
476    normally not used.  */
477 ssize_t
478 gpgme_io_read (int fd, void *buffer, size_t count)
479 {
480   int ret;
481
482   ret = _gpgme_io_read (fd, buffer, count);
483
484   return ret;
485 }
486
487
488 /* This function provides access to the internal write function.  It
489    is to be used by user callbacks to return data to gpgme.  See
490    gpgme_passphrase_cb_t and gpgme_edit_cb_t.  */
491 ssize_t
492 gpgme_io_write (int fd, const void *buffer, size_t count)
493 {
494   int ret;
495
496   ret = _gpgme_io_write (fd, buffer, count);
497
498   return ret;
499 }
500
501
502 /* This function returns the callback function for I/O.  */
503 void
504 gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs)
505 {
506   TRACE6 (DEBUG_CTX, "gpgme_get_io_cbs", ctx,
507           "io_cbs=%p, ctx->io_cbs.add=%p/%p, .remove=%p, .event=%p/%p",
508           io_cbs, io_cbs->add, io_cbs->add_priv, io_cbs->remove,
509           io_cbs->event, io_cbs->event_priv);
510
511   *io_cbs = ctx->io_cbs;
512 }
513
514 \f
515 /* This function sets the locale for the context CTX, or the default
516    locale if CTX is a null pointer.  */
517 gpgme_error_t
518 gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
519 {
520   int failed = 0;
521   char *new_lc_ctype = NULL;
522   char *new_lc_messages = NULL;
523
524   TRACE_BEG2 (DEBUG_CTX, "gpgme_set_locale", ctx,
525                "category=%i, value=%s", category, value ? value : "(null)");
526
527 #define PREPARE_ONE_LOCALE(lcat, ucat)                          \
528   if (!failed && value                                          \
529       && (category == LC_ALL || category == LC_ ## ucat))       \
530     {                                                           \
531       new_lc_ ## lcat = strdup (value);                         \
532       if (!new_lc_ ## lcat)                                     \
533         failed = 1;                                             \
534     }
535
536   PREPARE_ONE_LOCALE (ctype, CTYPE);
537 #ifdef LC_MESSAGES
538   PREPARE_ONE_LOCALE (messages, MESSAGES);
539 #endif
540
541   if (failed)
542     {
543       int saved_errno = errno;
544
545       if (new_lc_ctype)
546         free (new_lc_ctype);
547       if (new_lc_messages)
548         free (new_lc_messages);
549
550       return TRACE_ERR (gpg_error_from_errno (saved_errno));
551     }
552
553 #define SET_ONE_LOCALE(lcat, ucat)                      \
554   if (category == LC_ALL || category == LC_ ## ucat)    \
555     {                                                   \
556       if (ctx)                                          \
557         {                                               \
558           if (ctx->lc_ ## lcat)                         \
559             free (ctx->lc_ ## lcat);                    \
560           ctx->lc_ ## lcat = new_lc_ ## lcat;           \
561         }                                               \
562       else                                              \
563         {                                               \
564           if (def_lc_ ## lcat)                          \
565             free (def_lc_ ## lcat);                     \
566           def_lc_ ## lcat = new_lc_ ## lcat;            \
567         }                                               \
568     }
569
570   if (!ctx)
571     LOCK (def_lc_lock);
572   SET_ONE_LOCALE (ctype, CTYPE);
573 #ifdef LC_MESSAGES
574   SET_ONE_LOCALE (messages, MESSAGES);
575 #endif
576   if (!ctx)
577     UNLOCK (def_lc_lock);
578
579   return TRACE_ERR (0);
580 }
581
582 \f
583 /* Get the information about the configured engines.  A pointer to the
584    first engine in the statically allocated linked list is returned.
585    The returned data is valid until the next gpgme_ctx_set_engine_info.  */
586 gpgme_engine_info_t
587 gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
588 {
589   TRACE1 (DEBUG_CTX, "gpgme_ctx_get_engine_info", ctx,
590           "ctx->engine_info=%p", ctx->engine_info);
591   return ctx->engine_info;
592 }
593
594
595 /* Set the engine info for the context CTX, protocol PROTO, to the
596    file name FILE_NAME and the home directory HOME_DIR.  */
597 gpgme_error_t
598 gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
599                            const char *file_name, const char *home_dir)
600 {
601   gpgme_error_t err;
602   TRACE_BEG4 (DEBUG_CTX, "gpgme_ctx_set_engine_info", ctx,
603               "protocol=%i (%s), file_name=%s, home_dir=%s",
604               proto, gpgme_get_protocol_name (proto)
605               ? gpgme_get_protocol_name (proto) : "unknown",
606               file_name ? file_name : "(default)",
607               home_dir ? home_dir : "(default)");
608               
609   /* Shut down the engine when changing engine info.  */
610   if (ctx->engine)
611     {
612       TRACE_LOG1 ("releasing ctx->engine=%p", ctx->engine);
613       _gpgme_engine_release (ctx->engine);
614       ctx->engine = NULL;
615     }
616   err = _gpgme_set_engine_info (ctx->engine_info, proto,
617                                 file_name, home_dir);
618   return TRACE_ERR (err);
619 }
620
621 \f
622 /* Clear all notation data from the context.  */
623 void
624 gpgme_sig_notation_clear (gpgme_ctx_t ctx)
625 {
626   gpgme_sig_notation_t notation;
627   TRACE (DEBUG_CTX, "gpgme_sig_notation_clear", ctx);
628
629   if (!ctx)
630     return;
631
632   notation = ctx->sig_notations;
633   while (notation)
634     {
635       gpgme_sig_notation_t next_notation = notation->next;
636       _gpgme_sig_notation_free (notation);
637       notation = next_notation;
638     }
639   ctx->sig_notations = NULL;
640 }
641
642
643 /* Add the human-readable notation data with name NAME and value VALUE
644    to the context CTX, using the flags FLAGS.  If NAME is NULL, then
645    VALUE should be a policy URL.  The flag
646    GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
647    data, and false for policy URLs.  */
648 gpgme_error_t
649 gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
650                         const char *value, gpgme_sig_notation_flags_t flags)
651 {
652   gpgme_error_t err;
653   gpgme_sig_notation_t notation;
654   gpgme_sig_notation_t *lastp;
655
656   TRACE_BEG3 (DEBUG_CTX, "gpgme_sig_notation_add", ctx,
657               "name=%s, value=%s, flags=0x%x",
658               name ? name : "(null)", value ? value : "(null)",
659               flags);
660   
661   if (!ctx)
662     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
663
664   if (name)
665     flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
666   else
667     flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
668
669   err = _gpgme_sig_notation_create (&notation, name, name ? strlen (name) : 0,
670                                     value, value ? strlen (value) : 0, flags);
671   if (err)
672     return TRACE_ERR (err);
673
674   lastp = &ctx->sig_notations;
675   while (*lastp)
676     lastp = &(*lastp)->next;
677
678   *lastp = notation;
679   return TRACE_ERR (0);
680 }
681
682
683 /* Get the sig notations for this context.  */
684 gpgme_sig_notation_t
685 gpgme_sig_notation_get (gpgme_ctx_t ctx)
686 {
687   if (!ctx)
688     {
689       TRACE (DEBUG_CTX, "gpgme_sig_notation_get", ctx);
690       return NULL;
691     }
692   TRACE1 (DEBUG_CTX, "gpgme_sig_notation_get", ctx,
693           "ctx->sig_notations=%p", ctx->sig_notations);
694
695   return ctx->sig_notations;
696 }
697   
698 \f
699 const char *
700 gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
701 {
702   switch (algo)
703     {
704     case GPGME_PK_RSA:
705       return "RSA";
706
707     case GPGME_PK_RSA_E:
708       return "RSA-E";
709
710     case GPGME_PK_RSA_S:
711       return "RSA-S";
712
713     case GPGME_PK_ELG_E:
714       return "ELG-E";
715
716     case GPGME_PK_DSA:
717       return "DSA";
718
719     case GPGME_PK_ELG:
720       return "ELG";
721
722     default:
723       return NULL;
724     }
725 }
726
727
728 const char *
729 gpgme_hash_algo_name (gpgme_hash_algo_t algo)
730 {
731   switch (algo)
732     {
733     case GPGME_MD_MD5:
734       return "MD5";
735
736     case GPGME_MD_SHA1:
737       return "SHA1";
738
739     case GPGME_MD_RMD160:
740       return "RIPEMD160";
741
742     case GPGME_MD_MD2:
743       return "MD2";
744
745     case GPGME_MD_TIGER:
746       return "TIGER192";
747
748     case GPGME_MD_HAVAL:
749       return "HAVAL";
750
751     case GPGME_MD_SHA256:
752       return "SHA256";
753
754     case GPGME_MD_SHA384:
755       return "SHA384";
756
757     case GPGME_MD_SHA512:
758       return "SHA512";
759
760     case GPGME_MD_MD4:
761       return "MD4";
762
763     case GPGME_MD_CRC32:
764       return "CRC32";
765
766     case GPGME_MD_CRC32_RFC1510:
767       return "CRC32RFC1510";
768
769     case GPGME_MD_CRC24_RFC2440:
770       return "CRC24RFC2440";
771
772     default:
773       return NULL;
774     }
775 }