LCOV - code coverage report
Current view: top level - src - gpgme.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 293 519 56.5 %
Date: 2018-11-15 08:49:49 Functions: 35 51 68.6 %

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

Generated by: LCOV version 1.13