Greenbone Vulnerability Management Libraries  11.0.1
gpgmeutils.h File Reference

Protos and data structures for GPGME utilities. More...

#include <glib.h>
#include <gpgme.h>
Include dependency graph for gpgmeutils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void log_gpgme (GLogLevelFlags, gpg_error_t, const char *,...)
 Log function with extra gpg-error style output. More...
 
gpgme_ctx_t gvm_init_gpgme_ctx_from_dir (const gchar *)
 Returns a new gpgme context. More...
 
int gvm_gpg_import_many_types_from_string (gpgme_ctx_t, const char *, ssize_t, GArray *)
 Import a key or certificate given by a string. More...
 
int gvm_gpg_import_from_string (gpgme_ctx_t, const char *, ssize_t, gpgme_data_type_t)
 Import a key or certificate given by a string. More...
 
int gvm_pgp_pubkey_encrypt_stream (FILE *, FILE *, const char *, const char *, ssize_t)
 Encrypt a stream for a PGP public key, writing to another stream. More...
 
int gvm_smime_encrypt_stream (FILE *, FILE *, const char *, const char *, ssize_t)
 Encrypt a stream for a S/MIME certificate, writing to another stream. More...
 

Detailed Description

Protos and data structures for GPGME utilities.

This file contains the protos for gpgmeutils.c

Definition in file gpgmeutils.h.

Function Documentation

◆ gvm_gpg_import_from_string()

int gvm_gpg_import_from_string ( gpgme_ctx_t  ctx,
const char *  key_str,
ssize_t  key_len,
gpgme_data_type_t  key_type 
)

Import a key or certificate given by a string.

Parameters
[in]ctxThe GPGME context to import the key / certificate into.
[in]key_strKey or certificate string.
[in]key_lenLength of key/certificate string or -1 to use strlen.
[in]key_typeThe expected key type.
Returns
0 success, 1 invalid key data, 2 unexpected key data, 3 error importing key/certificate, -1 error.

Definition at line 282 of file gpgmeutils.c.

284 {
285  int ret;
286  GArray *key_types = g_array_sized_new (FALSE,
287  FALSE,
288  sizeof (gpgme_data_type_t),
289  1);
290  g_array_insert_val (key_types, 0, key_type);
291  ret = gvm_gpg_import_many_types_from_string (ctx, key_str, key_len,
292  key_types);
293  g_array_free (key_types, TRUE);
294  return ret;
295 }

References gvm_gpg_import_many_types_from_string().

Here is the call graph for this function:

◆ gvm_gpg_import_many_types_from_string()

int gvm_gpg_import_many_types_from_string ( gpgme_ctx_t  ctx,
const char *  key_str,
ssize_t  key_len,
GArray *  key_types 
)

Import a key or certificate given by a string.

Parameters
[in]ctxThe GPGME context to import the key / certificate into.
[in]key_strKey or certificate string.
[in]key_lenLength of key/certificate string or -1 to use strlen.
[in]key_typesGArray of expected key types.
Returns
0 success, 1 invalid key data, 2 unexpected key data, 3 error importing key/certificate, -1 error.

Definition at line 180 of file gpgmeutils.c.

184 {
185  gpgme_data_t key_data;
186  gpgme_error_t err;
187  gpgme_data_type_t given_key_type;
188  gpgme_import_result_t import_result;
189  int ret;
190 
191  gpgme_data_new_from_mem (
192  &key_data, key_str, (key_len >= 0 ? key_len : (ssize_t) strlen (key_str)),
193  0);
194 
195  given_key_type = gpgme_data_identify (key_data, 0);
196  ret = 0;
197  if (given_key_type == GPGME_DATA_TYPE_INVALID)
198  {
199  ret = 1;
200  g_warning ("%s: key_str is invalid", __FUNCTION__);
201  }
202  else
203  {
204  unsigned int index;
205  for (index = 0; index < key_types->len; index++)
206  {
207  if (g_array_index (key_types, gpgme_data_type_t, index)
208  == given_key_type)
209  break;
210  }
211 
212  if (index >= key_types->len)
213  {
214  ret = 2;
215  GString *expected_buffer = g_string_new ("");
216  for (index = 0; index < key_types->len; index++)
217  {
218  if (index)
219  g_string_append (expected_buffer, " or ");
220  g_string_append_printf (expected_buffer,
221  "%d",
222  g_array_index (key_types,
223  gpgme_data_type_t,
224  index));
225  }
226  g_warning ("%s: key_str is not the expected type: "
227  " expected: %s, got %d",
228  __FUNCTION__, expected_buffer->str, given_key_type);
229  g_string_free (expected_buffer, TRUE);
230  }
231  }
232 
233  if (ret)
234  {
235  gpgme_data_release (key_data);
236  return ret;
237  }
238 
239  err = gpgme_op_import (ctx, key_data);
240  gpgme_data_release (key_data);
241  if (err)
242  {
243  g_warning ("%s: Import failed: %s", __FUNCTION__, gpgme_strerror (err));
244  return 3;
245  }
246 
247  import_result = gpgme_op_import_result (ctx);
248  g_debug ("%s: %d imported, %d not imported", __FUNCTION__,
249  import_result->imported, import_result->not_imported);
250 
251  gpgme_import_status_t status;
252  status = import_result->imports;
253  while (status)
254  {
255  if (status->result != GPG_ERR_NO_ERROR)
256  g_warning ("%s: '%s' could not be imported: %s", __FUNCTION__,
257  status->fpr, gpgme_strerror (status->result));
258  else
259  g_debug ("%s: Imported '%s'", __FUNCTION__, status->fpr);
260 
261  status = status->next;
262  };
263 
264  if (import_result->not_imported)
265  return 3;
266 
267  return 0;
268 }

Referenced by encrypt_stream_internal(), and gvm_gpg_import_from_string().

Here is the caller graph for this function:

◆ gvm_init_gpgme_ctx_from_dir()

gpgme_ctx_t gvm_init_gpgme_ctx_from_dir ( const gchar *  dir)

Returns a new gpgme context.

Inits a gpgme context with the custom gpg directory, protocol version etc. Returns the context or NULL if an error occurred. This function also does an gpgme initialization the first time it is called.

Parameters
dirDirectory to use for gpg
Returns
The gpgme_ctx_t to the context or NULL if an error occurred.

Definition at line 88 of file gpgmeutils.c.

89 {
90  static int initialized;
91  gpgme_error_t err;
92  gpgme_ctx_t ctx;
93 
94  /* Initialize GPGME the first time we are called. This is a
95  failsafe mode; it would be better to initialize GPGME early at
96  process startup instead of this on-the-fly method; however in
97  this non-threaded system; this is an easier way for a library.
98  We allow to initialize until a valid gpgme or a gpg backend has
99  been found. */
100  if (!initialized)
101  {
102  gpgme_engine_info_t info;
103 
104  if (!gpgme_check_version (NULL))
105  {
106  g_critical ("gpgme library could not be initialized.");
107  return NULL;
108  }
109  gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
110 #ifdef LC_MESSAGES
111  gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
112 #endif
113 
114 #ifndef NDEBUG
115  g_message ("Setting GnuPG dir to '%s'", dir);
116 #endif
117  err = 0;
118  if (access (dir, F_OK))
119  {
120  err = gpg_error_from_syserror ();
121 
122  if (errno == ENOENT)
123  /* directory does not exists. try to create it */
124  if (mkdir (dir, 0700) == 0)
125  {
126 #ifndef NDEBUG
127  g_message ("Created GnuPG dir '%s'", dir);
128 #endif
129  err = 0;
130  }
131  }
132 
133  if (!err)
134  err = gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, NULL, dir);
135 
136  if (err)
137  {
138  log_gpgme (G_LOG_LEVEL_WARNING, err, "Setting GnuPG dir failed");
139  return NULL;
140  }
141 
142  /* Show the OpenPGP engine version. */
143  if (!gpgme_get_engine_info (&info))
144  {
145  while (info && info->protocol != GPGME_PROTOCOL_OpenPGP)
146  info = info->next;
147  }
148  else
149  info = NULL;
150 #ifndef NDEBUG
151  g_message ("Using OpenPGP engine version '%s'",
152  info && info->version ? info->version : "[?]");
153 #endif
154 
155  /* Everything is fine. */
156  initialized = 1;
157  }
158 
159  /* Allocate the context. */
160  ctx = NULL;
161  err = gpgme_new (&ctx);
162  if (err)
163  log_gpgme (G_LOG_LEVEL_WARNING, err, "Creating GPGME context failed");
164 
165  return ctx;
166 }

References initialized, and log_gpgme().

Here is the call graph for this function:

◆ gvm_pgp_pubkey_encrypt_stream()

int gvm_pgp_pubkey_encrypt_stream ( FILE *  plain_file,
FILE *  encrypted_file,
const char *  uid_email,
const char *  public_key_str,
ssize_t  public_key_len 
)

Encrypt a stream for a PGP public key, writing to another stream.

The output will use ASCII armor mode and no compression.

Parameters
[in]plain_fileStream / FILE* providing the plain text.
[in]encrypted_fileStream to write the encrypted text to.
[in]uid_emailEmail address of public key to use.
[in]public_key_strString containing the public key.
[in]public_key_lenLength of public key or -1 to use strlen.
Returns
0 success, -1 error.

Definition at line 603 of file gpgmeutils.c.

607 {
608  int ret;
609  const gpgme_data_type_t types_ptr[1] = {GPGME_DATA_TYPE_PGP_KEY};
610  GArray *key_types = g_array_new (FALSE, FALSE, sizeof (gpgme_data_type_t));
611 
612  g_array_append_vals (key_types, types_ptr, 1);
614  plain_file, encrypted_file, public_key_str, public_key_len, uid_email,
615  GPGME_PROTOCOL_OpenPGP, key_types);
616  g_array_free (key_types, TRUE);
617 
618  return ret;
619 }

References encrypt_stream_internal().

Here is the call graph for this function:

◆ gvm_smime_encrypt_stream()

int gvm_smime_encrypt_stream ( FILE *  plain_file,
FILE *  encrypted_file,
const char *  uid_email,
const char *  certificate_str,
ssize_t  certificate_len 
)

Encrypt a stream for a S/MIME certificate, writing to another stream.

The output will use ASCII armor mode and no compression.

Parameters
[in]plain_fileStream / FILE* providing the plain text.
[in]encrypted_fileStream to write the encrypted text to.
[in]uid_emailEmail address of certificate to use.
[in]certificate_strString containing the public key.
[in]certificate_lenLength of public key or -1 to use strlen.
Returns
0 success, -1 error.

Definition at line 635 of file gpgmeutils.c.

638 {
639  int ret;
640  const gpgme_data_type_t types_ptr[2] = {GPGME_DATA_TYPE_X509_CERT,
641  GPGME_DATA_TYPE_CMS_OTHER};
642  GArray *key_types = g_array_new (FALSE, FALSE, sizeof (gpgme_data_type_t));
643 
644  g_array_append_vals (key_types, types_ptr, 2);
646  plain_file, encrypted_file, certificate_str, certificate_len, uid_email,
647  GPGME_PROTOCOL_CMS, key_types);
648  g_array_free (key_types, TRUE);
649 
650  return ret;
651 }

References encrypt_stream_internal().

Here is the call graph for this function:

◆ log_gpgme()

void log_gpgme ( GLogLevelFlags  level,
gpg_error_t  err,
const char *  fmt,
  ... 
)

Log function with extra gpg-error style output.

If err is not 0, the appropriate error string is appended to the output. It takes care to only add the error source string if it makes sense.

Parameters
levelThe GLib style log level
errAn gpg-error value or 0
fmtThe printf style format string, followed by its arguments.

Definition at line 57 of file gpgmeutils.c.

58 {
59  va_list arg_ptr;
60  char *msg;
61 
62  va_start (arg_ptr, fmt);
63  msg = g_strdup_vprintf (fmt, arg_ptr);
64  va_end (arg_ptr);
65  if (err && gpg_err_source (err) != GPG_ERR_SOURCE_ANY && gpg_err_source (err))
66  g_log (G_LOG_DOMAIN, level, "%s: %s <%s>", msg, gpg_strerror (err),
67  gpg_strsource (err));
68  else if (err)
69  g_log (G_LOG_DOMAIN, level, "%s: %s", msg, gpg_strerror (err));
70  else
71  g_log (G_LOG_DOMAIN, level, "%s", msg);
72  g_free (msg);
73 }

References G_LOG_DOMAIN.

Referenced by gvm_init_gpgme_ctx_from_dir().

Here is the caller graph for this function:
gvm_gpg_import_many_types_from_string
int gvm_gpg_import_many_types_from_string(gpgme_ctx_t ctx, const char *key_str, ssize_t key_len, GArray *key_types)
Import a key or certificate given by a string.
Definition: gpgmeutils.c:180
G_LOG_DOMAIN
#define G_LOG_DOMAIN
GLib log domain.
Definition: gpgmeutils.c:41
encrypt_stream_internal
static int encrypt_stream_internal(FILE *plain_file, FILE *encrypted_file, const char *key_str, ssize_t key_len, const char *uid_email, gpgme_protocol_t protocol, GArray *key_types)
Encrypt a stream for a PGP public key, writing to another stream.
Definition: gpgmeutils.c:475
initialized
static gboolean initialized
Flag whether the config file was read.
Definition: authutils.c:47
log_gpgme
void log_gpgme(GLogLevelFlags level, gpg_error_t err, const char *fmt,...)
Log function with extra gpg-error style output.
Definition: gpgmeutils.c:57