LCOV - code coverage report
Current view: top level - src - gpgme.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 242 450 53.8 %
Date: 2016-09-12 13:07:23 Functions: 30 48 62.5 %

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

Generated by: LCOV version 1.11