LCOV - code coverage report
Current view: top level - src - gpgme.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 261 481 54.3 %
Date: 2016-12-01 18:45:36 Functions: 33 51 64.7 %

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

Generated by: LCOV version 1.11