Greenbone Vulnerability Management Libraries  22.8.0
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 264 of file gpgmeutils.c.

266 {
267  int ret;
268  GArray *key_types =
269  g_array_sized_new (FALSE, FALSE, sizeof (gpgme_data_type_t), 1);
270  g_array_insert_val (key_types, 0, key_type);
271  ret =
272  gvm_gpg_import_many_types_from_string (ctx, key_str, key_len, key_types);
273  g_array_free (key_types, TRUE);
274  return ret;
275 }

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 166 of file gpgmeutils.c.

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

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 74 of file gpgmeutils.c.

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

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 640 of file gpgmeutils.c.

644 {
645  int ret;
646  const gpgme_data_type_t types_ptr[1] = {GPGME_DATA_TYPE_PGP_KEY};
647  GArray *key_types = g_array_new (FALSE, FALSE, sizeof (gpgme_data_type_t));
648 
649  g_array_append_vals (key_types, types_ptr, 1);
650  ret = encrypt_stream_internal (plain_file, encrypted_file, public_key_str,
651  public_key_len, uid_email,
652  GPGME_PROTOCOL_OpenPGP, key_types);
653  g_array_free (key_types, TRUE);
654 
655  return ret;
656 }

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 672 of file gpgmeutils.c.

675 {
676  int ret;
677  const gpgme_data_type_t types_ptr[2] = {GPGME_DATA_TYPE_X509_CERT,
678  GPGME_DATA_TYPE_CMS_OTHER};
679  GArray *key_types = g_array_new (FALSE, FALSE, sizeof (gpgme_data_type_t));
680 
681  g_array_append_vals (key_types, types_ptr, 2);
682  ret = encrypt_stream_internal (plain_file, encrypted_file, certificate_str,
683  certificate_len, uid_email, GPGME_PROTOCOL_CMS,
684  key_types);
685  g_array_free (key_types, TRUE);
686 
687  return ret;
688 }

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 43 of file gpgmeutils.c.

44 {
45  va_list arg_ptr;
46  char *msg;
47 
48  va_start (arg_ptr, fmt);
49  msg = g_strdup_vprintf (fmt, arg_ptr);
50  va_end (arg_ptr);
51  if (err && gpg_err_source (err) != GPG_ERR_SOURCE_ANY && gpg_err_source (err))
52  g_log (G_LOG_DOMAIN, level, "%s: %s <%s>", msg, gpg_strerror (err),
53  gpg_strsource (err));
54  else if (err)
55  g_log (G_LOG_DOMAIN, level, "%s: %s", msg, gpg_strerror (err));
56  else
57  g_log (G_LOG_DOMAIN, level, "%s", msg);
58  g_free (msg);
59 }

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:166
G_LOG_DOMAIN
#define G_LOG_DOMAIN
GLib logging domain.
Definition: gpgmeutils.c:27
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:500
initialized
static gboolean initialized
Flag whether the config file was read.
Definition: authutils.c:33
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:43