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