30 #include <gpg-error.h>
41 #define G_LOG_DOMAIN "util gpgme"
57 log_gpgme (GLogLevelFlags level, gpg_error_t err,
const char *fmt, ...)
62 va_start (arg_ptr, fmt);
63 msg = g_strdup_vprintf (fmt, 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),
69 g_log (
G_LOG_DOMAIN, level,
"%s: %s", msg, gpg_strerror (err));
102 gpgme_engine_info_t info;
104 if (!gpgme_check_version (NULL))
106 g_critical (
"gpgme library could not be initialized.");
109 gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
111 gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
115 g_message (
"Setting GnuPG dir to '%s'", dir);
118 if (access (dir, F_OK))
120 err = gpg_error_from_syserror ();
124 if (mkdir (dir, 0700) == 0)
127 g_message (
"Created GnuPG dir '%s'", dir);
134 err = gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, NULL, dir);
138 log_gpgme (G_LOG_LEVEL_WARNING, err,
"Setting GnuPG dir failed");
143 if (!gpgme_get_engine_info (&info))
145 while (info && info->protocol != GPGME_PROTOCOL_OpenPGP)
151 g_message (
"Using OpenPGP engine version '%s'",
152 info && info->version ? info->version :
"[?]");
161 err = gpgme_new (&ctx);
163 log_gpgme (G_LOG_LEVEL_WARNING, err,
"Creating GPGME context failed");
185 gpgme_data_t key_data;
187 gpgme_data_type_t given_key_type;
188 gpgme_import_result_t import_result;
191 gpgme_data_new_from_mem (
192 &key_data, key_str, (key_len >= 0 ? key_len : (ssize_t) strlen (key_str)),
195 given_key_type = gpgme_data_identify (key_data, 0);
197 if (given_key_type == GPGME_DATA_TYPE_INVALID)
200 g_warning (
"%s: key_str is invalid", __FUNCTION__);
205 for (index = 0; index < key_types->len; index++)
207 if (g_array_index (key_types, gpgme_data_type_t, index)
212 if (index >= key_types->len)
215 GString *expected_buffer = g_string_new (
"");
216 for (index = 0; index < key_types->len; index++)
219 g_string_append (expected_buffer,
" or ");
220 g_string_append_printf (expected_buffer,
222 g_array_index (key_types,
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);
235 gpgme_data_release (key_data);
239 err = gpgme_op_import (ctx, key_data);
240 gpgme_data_release (key_data);
243 g_warning (
"%s: Import failed: %s", __FUNCTION__, gpgme_strerror (err));
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);
251 gpgme_import_status_t status;
252 status = import_result->imports;
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));
259 g_debug (
"%s: Imported '%s'", __FUNCTION__, status->fpr);
261 status = status->next;
264 if (import_result->not_imported)
283 ssize_t key_len, gpgme_data_type_t key_type)
286 GArray *key_types = g_array_sized_new (FALSE,
288 sizeof (gpgme_data_type_t),
290 g_array_insert_val (key_types, 0, key_type);
293 g_array_free (key_types, TRUE);
308 gchar *bracket_email;
310 gboolean recipient_found = FALSE;
312 if (uid_email == NULL)
315 bracket_email = g_strdup_printf (
"<%s>", uid_email);
317 gpgme_op_keylist_start (ctx, NULL, 0);
318 gpgme_op_keylist_next (ctx, &key);
319 while (key && recipient_found == FALSE)
321 if (key->can_encrypt)
323 g_debug (
"%s: key '%s' OK for encryption", __FUNCTION__,
328 while (uid && recipient_found == FALSE)
330 g_debug (
"%s: UID email: %s", __FUNCTION__, uid->email);
332 if (strcmp (uid->email, uid_email) == 0
333 || strstr (uid->email, bracket_email))
335 g_message (
"%s: Found matching UID for %s", __FUNCTION__,
337 recipient_found = TRUE;
344 g_debug (
"%s: key '%s' cannot be used for encryption", __FUNCTION__,
348 if (recipient_found == FALSE)
349 gpgme_op_keylist_next (ctx, &key);
356 g_warning (
"%s: No suitable key found for %s", __FUNCTION__, uid_email);
374 FILE *file = (FILE *)handle;
376 ret = fread (buffer, 1, size, file);
395 FILE *file = (FILE *)handle;
397 ret = fwrite (buffer, 1, size, file);
420 gchar *trustlist_filename;
421 GString *trustlist_content;
425 gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_CANCEL);
427 trustlist_filename = g_build_filename (homedir,
431 trustlist_content = g_string_new (
"");
433 gpgme_op_keylist_start (ctx, NULL, 0);
434 gpgme_op_keylist_next (ctx, &key);
437 g_string_append_printf (trustlist_content,
"%s S\n", key->fpr);
438 gpgme_op_keylist_next (ctx, &key);
441 if (g_file_set_contents (trustlist_filename,
442 trustlist_content->str,
443 trustlist_content->len,
446 g_warning (
"%s: Could not write trust list: %s",
447 __func__, g_err->message);
448 g_free (trustlist_filename);
449 g_string_free (trustlist_content, TRUE);
453 g_free (trustlist_filename);
454 g_string_free (trustlist_content, TRUE);
476 const char *key_str, ssize_t key_len,
477 const char *uid_email, gpgme_protocol_t protocol,
480 char gpg_temp_dir[] =
"/tmp/gvmd-gpg-XXXXXX";
482 gpgme_data_t plain_data, encrypted_data;
484 gpgme_key_t keys[2] = {NULL, NULL};
486 gpgme_encrypt_flags_t encrypt_flags;
487 const char *key_type_str;
488 struct gpgme_data_cbs callbacks;
490 if (uid_email == NULL || strcmp (uid_email,
"") == 0)
492 g_warning (
"%s: No email address for user identification given",
497 if (protocol == GPGME_PROTOCOL_CMS)
498 key_type_str =
"certificate";
500 key_type_str =
"public key";
503 if (mkdtemp (gpg_temp_dir) == NULL)
505 g_warning (
"%s: mkdtemp failed\n", __FUNCTION__);
511 if (protocol == GPGME_PROTOCOL_CMS)
512 gpgme_set_armor (ctx, 0);
514 gpgme_set_armor (ctx, 1);
516 gpgme_ctx_set_engine_info (ctx, protocol, NULL, gpg_temp_dir);
517 gpgme_set_protocol (ctx, protocol);
518 encrypt_flags = GPGME_ENCRYPT_ALWAYS_TRUST | GPGME_ENCRYPT_NO_COMPRESS;
523 g_warning (
"%s: Import of %s failed", __FUNCTION__, key_type_str);
533 g_warning (
"%s: Could not find %s for encryption", __FUNCTION__,
542 gpgme_data_new_from_stream (&plain_data, plain_file);
548 memset (&callbacks, 0,
sizeof (callbacks));
551 gpgme_data_new_from_cbs (&encrypted_data, &callbacks, encrypted_file);
553 if (protocol == GPGME_PROTOCOL_CMS)
555 gpgme_data_set_encoding (encrypted_data, GPGME_DATA_ENCODING_BASE64);
559 gpgme_data_release (plain_data);
560 gpgme_data_release (encrypted_data);
568 err = gpgme_op_encrypt (ctx, keys, encrypt_flags, plain_data, encrypted_data);
572 g_warning (
"%s: Encryption failed: %s", __FUNCTION__,
573 gpgme_strerror (err));
574 gpgme_data_release (plain_data);
575 gpgme_data_release (encrypted_data);
581 gpgme_data_release (plain_data);
582 gpgme_data_release (encrypted_data);
604 const char *uid_email,
605 const char *public_key_str,
606 ssize_t public_key_len)
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));
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);
636 const char *uid_email,
const char *certificate_str,
637 ssize_t certificate_len)
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));
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);