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