1 /*
2  * gpg.c
3  * vim: expandtab:ts=4:sts=4:sw=4
4  *
5  * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
6  *
7  * This file is part of Profanity.
8  *
9  * Profanity is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Profanity is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Profanity.  If not, see <https://www.gnu.org/licenses/>.
21  *
22  * In addition, as a special exception, the copyright holders give permission to
23  * link the code of portions of this program with the OpenSSL library under
24  * certain conditions as described in each individual source file, and
25  * distribute linked combinations including the two.
26  *
27  * You must obey the GNU General Public License in all respects for all of the
28  * code used other than OpenSSL. If you modify file(s) with this exception, you
29  * may extend this exception to your version of the file(s), but you are not
30  * obligated to do so. If you do not wish to do so, delete this exception
31  * statement from your version. If you delete this exception statement from all
32  * source files in the program, then also delete it here.
33  *
34  */
35 
36 #include "config.h"
37 
38 #include <locale.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <errno.h>
42 #include <sys/stat.h>
43 
44 #include <glib.h>
45 #include <glib/gstdio.h>
46 #include <gpgme.h>
47 
48 #include "log.h"
49 #include "common.h"
50 #include "pgp/gpg.h"
51 #include "config/files.h"
52 #include "tools/autocomplete.h"
53 #include "ui/ui.h"
54 
55 #define PGP_SIGNATURE_HEADER "-----BEGIN PGP SIGNATURE-----"
56 #define PGP_SIGNATURE_FOOTER "-----END PGP SIGNATURE-----"
57 #define PGP_MESSAGE_HEADER   "-----BEGIN PGP MESSAGE-----"
58 #define PGP_MESSAGE_FOOTER   "-----END PGP MESSAGE-----"
59 
60 static const char* libversion = NULL;
61 static GHashTable* pubkeys;
62 
63 static gchar* pubsloc;
64 static GKeyFile* pubkeyfile;
65 
66 static char* passphrase;
67 static char* passphrase_attempt;
68 
69 static Autocomplete key_ac;
70 
71 static char* _remove_header_footer(char* str, const char* const footer);
72 static char* _add_header_footer(const char* const str, const char* const header, const char* const footer);
73 static void _save_pubkeys(void);
74 
75 static gpgme_key_t _ox_key_lookup(const char* const barejid, gboolean secret_only);
76 static gboolean _ox_key_is_usable(gpgme_key_t key, const char* const barejid, gboolean secret);
77 
78 void
_p_gpg_free_pubkeyid(ProfPGPPubKeyId * pubkeyid)79 _p_gpg_free_pubkeyid(ProfPGPPubKeyId* pubkeyid)
80 {
81     if (pubkeyid) {
82         free(pubkeyid->id);
83     }
84     free(pubkeyid);
85 }
86 
87 static gpgme_error_t*
_p_gpg_passphrase_cb(void * hook,const char * uid_hint,const char * passphrase_info,int prev_was_bad,int fd)88 _p_gpg_passphrase_cb(void* hook, const char* uid_hint, const char* passphrase_info, int prev_was_bad, int fd)
89 {
90     if (passphrase) {
91         gpgme_io_write(fd, passphrase, strlen(passphrase));
92     } else {
93         GString* pass_term = g_string_new("");
94 
95         char* password = ui_ask_pgp_passphrase(uid_hint, prev_was_bad);
96         if (password) {
97             g_string_append(pass_term, password);
98             free(password);
99         }
100 
101         g_string_append(pass_term, "\n");
102         if (passphrase_attempt) {
103             free(passphrase_attempt);
104         }
105         passphrase_attempt = pass_term->str;
106         g_string_free(pass_term, FALSE);
107 
108         gpgme_io_write(fd, passphrase_attempt, strlen(passphrase_attempt));
109     }
110 
111     return 0;
112 }
113 
114 void
p_gpg_init(void)115 p_gpg_init(void)
116 {
117     libversion = gpgme_check_version(NULL);
118     log_debug("GPG: Found gpgme version: %s", libversion);
119     gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
120 
121     pubkeys = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_p_gpg_free_pubkeyid);
122 
123     key_ac = autocomplete_new();
124     GHashTable* keys = p_gpg_list_keys();
125     p_gpg_free_keys(keys);
126 
127     passphrase = NULL;
128     passphrase_attempt = NULL;
129 }
130 
131 void
p_gpg_close(void)132 p_gpg_close(void)
133 {
134     if (pubkeys) {
135         g_hash_table_destroy(pubkeys);
136         pubkeys = NULL;
137     }
138 
139     if (pubkeyfile) {
140         g_key_file_free(pubkeyfile);
141         pubkeyfile = NULL;
142     }
143 
144     free(pubsloc);
145     pubsloc = NULL;
146 
147     autocomplete_free(key_ac);
148     key_ac = NULL;
149 
150     if (passphrase) {
151         free(passphrase);
152         passphrase = NULL;
153     }
154 
155     if (passphrase_attempt) {
156         free(passphrase_attempt);
157         passphrase_attempt = NULL;
158     }
159 }
160 
161 void
p_gpg_on_connect(const char * const barejid)162 p_gpg_on_connect(const char* const barejid)
163 {
164     gchar* pubsfile = files_get_account_data_path(DIR_PGP, barejid);
165 
166     // mkdir if doesn't exist for account
167     errno = 0;
168     int res = g_mkdir_with_parents(pubsfile, S_IRWXU);
169     if (res == -1) {
170         const char* errmsg = strerror(errno);
171         if (errmsg) {
172             log_error("Error creating directory: %s, %s", pubsfile, errmsg);
173         } else {
174             log_error("Error creating directory: %s", pubsfile);
175         }
176     }
177 
178     // create or read publickeys
179     GString* pubtmp = g_string_new(pubsfile);
180     g_string_append(pubtmp, "/pubkeys");
181     pubsloc = pubtmp->str;
182     g_string_free(pubtmp, FALSE);
183     g_free(pubsfile);
184 
185     if (g_file_test(pubsloc, G_FILE_TEST_EXISTS)) {
186         g_chmod(pubsloc, S_IRUSR | S_IWUSR);
187     }
188 
189     pubkeyfile = g_key_file_new();
190     g_key_file_load_from_file(pubkeyfile, pubsloc, G_KEY_FILE_KEEP_COMMENTS, NULL);
191 
192     // load each keyid
193     gsize len = 0;
194     gchar** jids = g_key_file_get_groups(pubkeyfile, &len);
195 
196     gpgme_ctx_t ctx;
197     gpgme_error_t error = gpgme_new(&ctx);
198 
199     if (error) {
200         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
201         g_strfreev(jids);
202         return;
203     }
204 
205     for (int i = 0; i < len; i++) {
206         GError* gerr = NULL;
207         gchar* jid = jids[i];
208         gchar* keyid = g_key_file_get_string(pubkeyfile, jid, "keyid", &gerr);
209         if (gerr) {
210             log_error("Error loading PGP key id for %s", jid);
211             g_error_free(gerr);
212             g_free(keyid);
213         } else {
214             gpgme_key_t key = NULL;
215             error = gpgme_get_key(ctx, keyid, &key, 0);
216             if (error || key == NULL) {
217                 log_warning("GPG: Failed to get key for %s: %s %s", jid, gpgme_strsource(error), gpgme_strerror(error));
218                 continue;
219             }
220 
221             ProfPGPPubKeyId* pubkeyid = malloc(sizeof(ProfPGPPubKeyId));
222             pubkeyid->id = strdup(keyid);
223             pubkeyid->received = FALSE;
224             g_hash_table_replace(pubkeys, strdup(jid), pubkeyid);
225             g_free(keyid);
226             gpgme_key_unref(key);
227         }
228     }
229 
230     gpgme_release(ctx);
231     g_strfreev(jids);
232 
233     _save_pubkeys();
234 }
235 
236 void
p_gpg_on_disconnect(void)237 p_gpg_on_disconnect(void)
238 {
239     if (pubkeys) {
240         g_hash_table_destroy(pubkeys);
241         pubkeys = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_p_gpg_free_pubkeyid);
242     }
243 
244     if (pubkeyfile) {
245         g_key_file_free(pubkeyfile);
246         pubkeyfile = NULL;
247     }
248 
249     free(pubsloc);
250     pubsloc = NULL;
251 
252     if (passphrase) {
253         free(passphrase);
254         passphrase = NULL;
255     }
256 
257     if (passphrase_attempt) {
258         free(passphrase_attempt);
259         passphrase_attempt = NULL;
260     }
261 }
262 
263 gboolean
p_gpg_addkey(const char * const jid,const char * const keyid)264 p_gpg_addkey(const char* const jid, const char* const keyid)
265 {
266     gpgme_ctx_t ctx;
267     gpgme_error_t error = gpgme_new(&ctx);
268     if (error) {
269         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
270         return FALSE;
271     }
272 
273     gpgme_key_t key = NULL;
274     error = gpgme_get_key(ctx, keyid, &key, 0);
275     gpgme_release(ctx);
276 
277     if (error || key == NULL) {
278         log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
279         return FALSE;
280     }
281 
282     // save to public key file
283     g_key_file_set_string(pubkeyfile, jid, "keyid", keyid);
284     _save_pubkeys();
285 
286     // update in memory pubkeys list
287     ProfPGPPubKeyId* pubkeyid = malloc(sizeof(ProfPGPPubKeyId));
288     pubkeyid->id = strdup(keyid);
289     pubkeyid->received = FALSE;
290     g_hash_table_replace(pubkeys, strdup(jid), pubkeyid);
291     gpgme_key_unref(key);
292 
293     return TRUE;
294 }
295 
296 static ProfPGPKey*
_p_gpg_key_new(void)297 _p_gpg_key_new(void)
298 {
299     ProfPGPKey* p_pgpkey = malloc(sizeof(ProfPGPKey));
300     p_pgpkey->id = NULL;
301     p_pgpkey->name = NULL;
302     p_pgpkey->fp = NULL;
303     p_pgpkey->encrypt = FALSE;
304     p_pgpkey->sign = FALSE;
305     p_pgpkey->certify = FALSE;
306     p_pgpkey->authenticate = FALSE;
307     p_pgpkey->secret = FALSE;
308 
309     return p_pgpkey;
310 }
311 
312 static void
_p_gpg_free_key(ProfPGPKey * key)313 _p_gpg_free_key(ProfPGPKey* key)
314 {
315     if (key) {
316         free(key->id);
317         free(key->name);
318         free(key->fp);
319         free(key);
320     }
321 }
322 
323 GHashTable*
p_gpg_list_keys(void)324 p_gpg_list_keys(void)
325 {
326     gpgme_error_t error;
327     GHashTable* result = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_p_gpg_free_key);
328 
329     gpgme_ctx_t ctx;
330     error = gpgme_new(&ctx);
331 
332     if (error) {
333         log_error("GPG: Could not list keys. %s %s", gpgme_strsource(error), gpgme_strerror(error));
334         return NULL;
335     }
336 
337     error = gpgme_op_keylist_start(ctx, NULL, 0);
338     if (error == GPG_ERR_NO_ERROR) {
339         gpgme_key_t key;
340         error = gpgme_op_keylist_next(ctx, &key);
341         while (!error) {
342             gpgme_subkey_t sub = key->subkeys;
343 
344             ProfPGPKey* p_pgpkey = _p_gpg_key_new();
345             p_pgpkey->id = strdup(sub->keyid);
346             p_pgpkey->name = strdup(key->uids->uid);
347             p_pgpkey->fp = strdup(sub->fpr);
348             if (sub->can_encrypt)
349                 p_pgpkey->encrypt = TRUE;
350             if (sub->can_authenticate)
351                 p_pgpkey->authenticate = TRUE;
352             if (sub->can_certify)
353                 p_pgpkey->certify = TRUE;
354             if (sub->can_sign)
355                 p_pgpkey->sign = TRUE;
356 
357             sub = sub->next;
358             while (sub) {
359                 if (sub->can_encrypt)
360                     p_pgpkey->encrypt = TRUE;
361                 if (sub->can_authenticate)
362                     p_pgpkey->authenticate = TRUE;
363                 if (sub->can_certify)
364                     p_pgpkey->certify = TRUE;
365                 if (sub->can_sign)
366                     p_pgpkey->sign = TRUE;
367 
368                 sub = sub->next;
369             }
370 
371             g_hash_table_insert(result, strdup(p_pgpkey->name), p_pgpkey);
372 
373             gpgme_key_unref(key);
374             error = gpgme_op_keylist_next(ctx, &key);
375         }
376     }
377 
378     error = gpgme_op_keylist_start(ctx, NULL, 1);
379     if (error == GPG_ERR_NO_ERROR) {
380         gpgme_key_t key;
381         error = gpgme_op_keylist_next(ctx, &key);
382         while (!error) {
383             gpgme_subkey_t sub = key->subkeys;
384             while (sub) {
385                 if (sub->secret) {
386                     ProfPGPKey* p_pgpkey = g_hash_table_lookup(result, key->uids->uid);
387                     if (p_pgpkey) {
388                         p_pgpkey->secret = TRUE;
389                     }
390                 }
391                 sub = sub->next;
392             }
393 
394             gpgme_key_unref(key);
395             error = gpgme_op_keylist_next(ctx, &key);
396         }
397     }
398 
399     gpgme_release(ctx);
400 
401     autocomplete_clear(key_ac);
402     GList* ids = g_hash_table_get_keys(result);
403     GList* curr = ids;
404     while (curr) {
405         ProfPGPKey* key = g_hash_table_lookup(result, curr->data);
406         autocomplete_add(key_ac, key->id);
407         curr = curr->next;
408     }
409     g_list_free(ids);
410 
411     return result;
412 }
413 
414 void
p_gpg_free_keys(GHashTable * keys)415 p_gpg_free_keys(GHashTable* keys)
416 {
417     g_hash_table_destroy(keys);
418 }
419 
420 GHashTable*
p_gpg_pubkeys(void)421 p_gpg_pubkeys(void)
422 {
423     return pubkeys;
424 }
425 
426 const char*
p_gpg_libver(void)427 p_gpg_libver(void)
428 {
429     if (libversion == NULL) {
430         libversion = gpgme_check_version(NULL);
431     }
432     return libversion;
433 }
434 
435 gboolean
p_gpg_valid_key(const char * const keyid,char ** err_str)436 p_gpg_valid_key(const char* const keyid, char** err_str)
437 {
438     gpgme_ctx_t ctx;
439     gpgme_error_t error = gpgme_new(&ctx);
440     if (error) {
441         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
442         *err_str = strdup(gpgme_strerror(error));
443         return FALSE;
444     }
445 
446     gpgme_key_t key = NULL;
447     error = gpgme_get_key(ctx, keyid, &key, 1);
448 
449     if (error || key == NULL) {
450         log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
451         *err_str = strdup(gpgme_strerror(error));
452         gpgme_release(ctx);
453         return FALSE;
454     }
455 
456     if (key == NULL) {
457         *err_str = strdup("Unknown error");
458         gpgme_release(ctx);
459         return FALSE;
460     }
461 
462     gpgme_release(ctx);
463     gpgme_key_unref(key);
464     return TRUE;
465 }
466 
467 gboolean
p_gpg_available(const char * const barejid)468 p_gpg_available(const char* const barejid)
469 {
470     char* pubkey = g_hash_table_lookup(pubkeys, barejid);
471     return (pubkey != NULL);
472 }
473 
474 void
p_gpg_verify(const char * const barejid,const char * const sign)475 p_gpg_verify(const char* const barejid, const char* const sign)
476 {
477     if (!sign) {
478         return;
479     }
480 
481     gpgme_ctx_t ctx;
482     gpgme_error_t error = gpgme_new(&ctx);
483 
484     if (error) {
485         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
486         return;
487     }
488 
489     char* sign_with_header_footer = _add_header_footer(sign, PGP_SIGNATURE_HEADER, PGP_SIGNATURE_FOOTER);
490     gpgme_data_t sign_data;
491     gpgme_data_new_from_mem(&sign_data, sign_with_header_footer, strlen(sign_with_header_footer), 1);
492     free(sign_with_header_footer);
493 
494     gpgme_data_t plain_data;
495     gpgme_data_new(&plain_data);
496 
497     error = gpgme_op_verify(ctx, sign_data, NULL, plain_data);
498     gpgme_data_release(sign_data);
499     gpgme_data_release(plain_data);
500 
501     if (error) {
502         log_error("GPG: Failed to verify. %s %s", gpgme_strsource(error), gpgme_strerror(error));
503         gpgme_release(ctx);
504         return;
505     }
506 
507     gpgme_verify_result_t result = gpgme_op_verify_result(ctx);
508     if (result) {
509         if (result->signatures) {
510             gpgme_key_t key = NULL;
511             error = gpgme_get_key(ctx, result->signatures->fpr, &key, 0);
512             if (error) {
513                 log_debug("Could not find PGP key with ID %s for %s", result->signatures->fpr, barejid);
514             } else {
515                 log_debug("Fingerprint found for %s: %s ", barejid, key->subkeys->fpr);
516                 ProfPGPPubKeyId* pubkeyid = malloc(sizeof(ProfPGPPubKeyId));
517                 pubkeyid->id = strdup(key->subkeys->keyid);
518                 pubkeyid->received = TRUE;
519                 g_hash_table_replace(pubkeys, strdup(barejid), pubkeyid);
520             }
521 
522             gpgme_key_unref(key);
523         }
524     }
525 
526     gpgme_release(ctx);
527 }
528 
529 char*
p_gpg_sign(const char * const str,const char * const fp)530 p_gpg_sign(const char* const str, const char* const fp)
531 {
532     gpgme_ctx_t ctx;
533     gpgme_error_t error = gpgme_new(&ctx);
534     if (error) {
535         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
536         return NULL;
537     }
538 
539     gpgme_set_passphrase_cb(ctx, (gpgme_passphrase_cb_t)_p_gpg_passphrase_cb, NULL);
540 
541     gpgme_key_t key = NULL;
542     error = gpgme_get_key(ctx, fp, &key, 1);
543 
544     if (error || key == NULL) {
545         log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
546         gpgme_release(ctx);
547         return NULL;
548     }
549 
550     gpgme_signers_clear(ctx);
551     error = gpgme_signers_add(ctx, key);
552     gpgme_key_unref(key);
553 
554     if (error) {
555         log_error("GPG: Failed to load signer. %s %s", gpgme_strsource(error), gpgme_strerror(error));
556         gpgme_release(ctx);
557         return NULL;
558     }
559 
560     char* str_or_empty = NULL;
561     if (str) {
562         str_or_empty = strdup(str);
563     } else {
564         str_or_empty = strdup("");
565     }
566     gpgme_data_t str_data;
567     gpgme_data_new_from_mem(&str_data, str_or_empty, strlen(str_or_empty), 1);
568     free(str_or_empty);
569 
570     gpgme_data_t signed_data;
571     gpgme_data_new(&signed_data);
572 
573     gpgme_set_armor(ctx, 1);
574     error = gpgme_op_sign(ctx, str_data, signed_data, GPGME_SIG_MODE_DETACH);
575     gpgme_data_release(str_data);
576     gpgme_release(ctx);
577 
578     if (error) {
579         log_error("GPG: Failed to sign string. %s %s", gpgme_strsource(error), gpgme_strerror(error));
580         gpgme_data_release(signed_data);
581         return NULL;
582     }
583 
584     char* result = NULL;
585 
586     size_t len = 0;
587     char* signed_str = gpgme_data_release_and_get_mem(signed_data, &len);
588     if (signed_str) {
589         GString* signed_gstr = g_string_new("");
590         g_string_append_len(signed_gstr, signed_str, len);
591         result = _remove_header_footer(signed_gstr->str, PGP_SIGNATURE_FOOTER);
592         g_string_free(signed_gstr, TRUE);
593         gpgme_free(signed_str);
594     }
595 
596     if (passphrase_attempt) {
597         passphrase = strdup(passphrase_attempt);
598     }
599 
600     return result;
601 }
602 
603 char*
p_gpg_encrypt(const char * const barejid,const char * const message,const char * const fp)604 p_gpg_encrypt(const char* const barejid, const char* const message, const char* const fp)
605 {
606     ProfPGPPubKeyId* pubkeyid = g_hash_table_lookup(pubkeys, barejid);
607     if (!pubkeyid) {
608         return NULL;
609     }
610     if (!pubkeyid->id) {
611         return NULL;
612     }
613 
614     gpgme_key_t keys[3];
615 
616     keys[0] = NULL;
617     keys[1] = NULL;
618     keys[2] = NULL;
619 
620     gpgme_ctx_t ctx;
621     gpgme_error_t error = gpgme_new(&ctx);
622     if (error) {
623         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
624         return NULL;
625     }
626 
627     gpgme_key_t receiver_key;
628     error = gpgme_get_key(ctx, pubkeyid->id, &receiver_key, 0);
629     if (error || receiver_key == NULL) {
630         log_error("GPG: Failed to get receiver_key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
631         gpgme_release(ctx);
632         return NULL;
633     }
634     keys[0] = receiver_key;
635 
636     gpgme_key_t sender_key = NULL;
637     error = gpgme_get_key(ctx, fp, &sender_key, 0);
638     if (error || sender_key == NULL) {
639         log_error("GPG: Failed to get sender_key. %s %s", gpgme_strsource(error), gpgme_strerror(error));
640         gpgme_release(ctx);
641         return NULL;
642     }
643     keys[1] = sender_key;
644 
645     gpgme_data_t plain;
646     gpgme_data_new_from_mem(&plain, message, strlen(message), 1);
647 
648     gpgme_data_t cipher;
649     gpgme_data_new(&cipher);
650 
651     gpgme_set_armor(ctx, 1);
652     error = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher);
653     gpgme_data_release(plain);
654     gpgme_release(ctx);
655     gpgme_key_unref(receiver_key);
656     gpgme_key_unref(sender_key);
657 
658     if (error) {
659         log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error));
660         return NULL;
661     }
662 
663     size_t len;
664     char* cipher_str = gpgme_data_release_and_get_mem(cipher, &len);
665 
666     char* result = NULL;
667     if (cipher_str) {
668         GString* cipher_gstr = g_string_new("");
669         g_string_append_len(cipher_gstr, cipher_str, len);
670         result = _remove_header_footer(cipher_gstr->str, PGP_MESSAGE_FOOTER);
671         g_string_free(cipher_gstr, TRUE);
672         gpgme_free(cipher_str);
673     }
674 
675     return result;
676 }
677 
678 char*
p_gpg_decrypt(const char * const cipher)679 p_gpg_decrypt(const char* const cipher)
680 {
681     gpgme_ctx_t ctx;
682     gpgme_error_t error = gpgme_new(&ctx);
683 
684     if (error) {
685         log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error));
686         return NULL;
687     }
688 
689     gpgme_set_passphrase_cb(ctx, (gpgme_passphrase_cb_t)_p_gpg_passphrase_cb, NULL);
690 
691     char* cipher_with_headers = _add_header_footer(cipher, PGP_MESSAGE_HEADER, PGP_MESSAGE_FOOTER);
692     gpgme_data_t cipher_data;
693     gpgme_data_new_from_mem(&cipher_data, cipher_with_headers, strlen(cipher_with_headers), 1);
694     free(cipher_with_headers);
695 
696     gpgme_data_t plain_data;
697     gpgme_data_new(&plain_data);
698 
699     error = gpgme_op_decrypt(ctx, cipher_data, plain_data);
700     gpgme_data_release(cipher_data);
701 
702     if (error) {
703         log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error));
704         gpgme_data_release(plain_data);
705         gpgme_release(ctx);
706         return NULL;
707     }
708 
709     gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx);
710     if (res) {
711         GString* recipients_str = g_string_new("");
712         gpgme_recipient_t recipient = res->recipients;
713         while (recipient) {
714             gpgme_key_t key;
715             error = gpgme_get_key(ctx, recipient->keyid, &key, 1);
716 
717             if (!error && key) {
718                 const char* addr = gpgme_key_get_string_attr(key, GPGME_ATTR_EMAIL, NULL, 0);
719                 if (addr) {
720                     g_string_append(recipients_str, addr);
721                 }
722                 gpgme_key_unref(key);
723             }
724 
725             if (recipient->next) {
726                 g_string_append(recipients_str, ", ");
727             }
728 
729             recipient = recipient->next;
730         }
731 
732         log_debug("GPG: Decrypted message for recipients: %s", recipients_str->str);
733         g_string_free(recipients_str, TRUE);
734     }
735     gpgme_release(ctx);
736 
737     size_t len = 0;
738     char* plain_str = gpgme_data_release_and_get_mem(plain_data, &len);
739     char* result = NULL;
740     if (plain_str) {
741         plain_str[len] = 0;
742         result = g_strdup(plain_str);
743     }
744     gpgme_free(plain_str);
745 
746     if (passphrase_attempt) {
747         passphrase = strdup(passphrase_attempt);
748     }
749 
750     return result;
751 }
752 
753 void
p_gpg_free_decrypted(char * decrypted)754 p_gpg_free_decrypted(char* decrypted)
755 {
756     g_free(decrypted);
757 }
758 
759 char*
p_gpg_autocomplete_key(const char * const search_str,gboolean previous,void * context)760 p_gpg_autocomplete_key(const char* const search_str, gboolean previous, void* context)
761 {
762     return autocomplete_complete(key_ac, search_str, TRUE, previous);
763 }
764 
765 void
p_gpg_autocomplete_key_reset(void)766 p_gpg_autocomplete_key_reset(void)
767 {
768     autocomplete_reset(key_ac);
769 }
770 
771 char*
p_gpg_format_fp_str(char * fp)772 p_gpg_format_fp_str(char* fp)
773 {
774     if (!fp) {
775         return NULL;
776     }
777 
778     GString* format = g_string_new("");
779     int len = strlen(fp);
780     for (int i = 0; i < len; i++) {
781         g_string_append_c(format, fp[i]);
782         if (((i + 1) % 4 == 0) && (i + 1 < len)) {
783             g_string_append_c(format, ' ');
784         }
785     }
786 
787     char* result = format->str;
788     g_string_free(format, FALSE);
789 
790     return result;
791 }
792 
793 /*!
794  * \brief Public keys with XMPP-URI.
795  *
796  * This function will look for all public key with a XMPP-URI as UID.
797  *
798  */
799 GHashTable*
ox_gpg_public_keys(void)800 ox_gpg_public_keys(void)
801 {
802     gpgme_error_t error;
803     GHashTable* result = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_p_gpg_free_key);
804 
805     gpgme_ctx_t ctx;
806     error = gpgme_new(&ctx);
807 
808     if (error) {
809         log_error("OX - gpgme_new failed: %s %s", gpgme_strsource(error), gpgme_strerror(error));
810         return NULL;
811     }
812 
813     error = gpgme_op_keylist_start(ctx, NULL, 0); // all public keys
814     if (error == GPG_ERR_NO_ERROR) {
815         gpgme_key_t key;
816         error = gpgme_op_keylist_next(ctx, &key);
817         if (error != GPG_ERR_EOF && error != GPG_ERR_NO_ERROR) {
818             log_error("OX: gpgme_op_keylist_next %s %s", gpgme_strsource(error), gpgme_strerror(error));
819             g_hash_table_destroy(result);
820             return NULL;
821         }
822         while (!error) {
823             // Looking for XMPP URI UID
824             gpgme_user_id_t uid = key->uids;
825             gpgme_user_id_t xmppid = NULL;
826             while (!xmppid && uid) {
827                 if (uid->name && strlen(uid->name) >= 10) {
828                     if (strstr(uid->name, "xmpp:") == uid->name) {
829                         xmppid = uid;
830                     }
831                 }
832                 uid = uid->next;
833             }
834 
835             if (xmppid) {
836                 // Build Key information about all subkey
837                 gpgme_subkey_t sub = key->subkeys;
838 
839                 ProfPGPKey* p_pgpkey = _p_gpg_key_new();
840                 p_pgpkey->id = strdup(sub->keyid);
841                 p_pgpkey->name = strdup(xmppid->uid);
842                 p_pgpkey->fp = strdup(sub->fpr);
843                 if (sub->can_encrypt)
844                     p_pgpkey->encrypt = TRUE;
845                 if (sub->can_authenticate)
846                     p_pgpkey->authenticate = TRUE;
847                 if (sub->can_certify)
848                     p_pgpkey->certify = TRUE;
849                 if (sub->can_sign)
850                     p_pgpkey->sign = TRUE;
851 
852                 sub = sub->next;
853                 while (sub) {
854                     if (sub->can_encrypt)
855                         p_pgpkey->encrypt = TRUE;
856                     if (sub->can_authenticate)
857                         p_pgpkey->authenticate = TRUE;
858                     if (sub->can_certify)
859                         p_pgpkey->certify = TRUE;
860                     if (sub->can_sign)
861                         p_pgpkey->sign = TRUE;
862 
863                     sub = sub->next;
864                 }
865 
866                 g_hash_table_insert(result, strdup(p_pgpkey->name), p_pgpkey);
867             }
868             gpgme_key_unref(key);
869             error = gpgme_op_keylist_next(ctx, &key);
870         }
871     }
872     gpgme_release(ctx);
873 
874     //autocomplete_clear(key_ac);
875     //    GList *ids = g_hash_table_get_keys(result);
876     //    GList *curr = ids;
877     //    while (curr) {
878     //        ProfPGPKey *key = g_hash_table_lookup(result, curr->data);
879     //        autocomplete_add(key_ac, key->id);
880     //        curr = curr->next;
881     //    }
882     //    g_list_free(ids);
883 
884     return result;
885 }
886 
887 char*
p_ox_gpg_signcrypt(const char * const sender_barejid,const char * const recipient_barejid,const char * const message)888 p_ox_gpg_signcrypt(const char* const sender_barejid, const char* const recipient_barejid, const char* const message)
889 {
890     setlocale(LC_ALL, "");
891     gpgme_check_version(NULL);
892     gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
893     gpgme_ctx_t ctx;
894 
895     gpgme_error_t error = gpgme_new(&ctx);
896     if (GPG_ERR_NO_ERROR != error) {
897         printf("gpgme_new: %d\n", error);
898         return NULL;
899     }
900 
901     error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
902     if (error != 0) {
903         log_error("GpgME Error: %s", gpgme_strerror(error));
904     }
905 
906     gpgme_set_armor(ctx, 0);
907     gpgme_set_textmode(ctx, 0);
908     gpgme_set_offline(ctx, 1);
909     gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
910     if (error != 0) {
911         log_error("GpgME Error: %s", gpgme_strerror(error));
912     }
913 
914     gpgme_key_t recp[3];
915     recp[0] = NULL,
916     recp[1] = NULL;
917 
918     char* xmpp_jid_me = alloca((strlen(sender_barejid) + 6) * sizeof(char));
919     char* xmpp_jid_recipient = alloca((strlen(recipient_barejid) + 6) * sizeof(char));
920 
921     strcpy(xmpp_jid_me, "xmpp:");
922     strcpy(xmpp_jid_recipient, "xmpp:");
923     strcat(xmpp_jid_me, sender_barejid);
924     strcat(xmpp_jid_recipient, recipient_barejid);
925 
926     gpgme_signers_clear(ctx);
927 
928     // lookup own key
929     recp[0] = _ox_key_lookup(sender_barejid, TRUE);
930     if (error != 0) {
931         log_error("Key not found for %s. GpgME Error: %s", xmpp_jid_me, gpgme_strerror(error));
932         return NULL;
933     }
934 
935     error = gpgme_signers_add(ctx, recp[0]);
936     if (error != 0) {
937         log_error("gpgme_signers_add %s. GpgME Error: %s", xmpp_jid_me, gpgme_strerror(error));
938         return NULL;
939     }
940 
941     // lookup key of recipient
942     recp[1] = _ox_key_lookup(recipient_barejid, FALSE);
943     if (error != 0) {
944         log_error("Key not found for %s. GpgME Error: %s", xmpp_jid_recipient, gpgme_strerror(error));
945         return NULL;
946     }
947     recp[2] = NULL;
948     log_debug("%s <%s>", recp[0]->uids->name, recp[0]->uids->email);
949     log_debug("%s <%s>", recp[1]->uids->name, recp[1]->uids->email);
950 
951     gpgme_encrypt_flags_t flags = 0;
952 
953     gpgme_data_t plain;
954     gpgme_data_t cipher;
955 
956     error = gpgme_data_new(&plain);
957     if (error != 0) {
958         log_error("GpgME Error: %s", gpgme_strerror(error));
959         return NULL;
960     }
961 
962     error = gpgme_data_new_from_mem(&plain, message, strlen(message), 0);
963     if (error != 0) {
964         log_error("GpgME Error: %s", gpgme_strerror(error));
965         return NULL;
966     }
967     error = gpgme_data_new(&cipher);
968     if (error != 0) {
969         log_error("GpgME Error: %s", gpgme_strerror(error));
970         return NULL;
971     }
972 
973     error = gpgme_op_encrypt_sign(ctx, recp, flags, plain, cipher);
974     if (error != 0) {
975         log_error("GpgME Error: %s", gpgme_strerror(error));
976         return NULL;
977     }
978 
979     size_t len;
980     char* cipher_str = gpgme_data_release_and_get_mem(cipher, &len);
981     char* result = g_base64_encode((unsigned char*)cipher_str, len);
982     gpgme_key_release(recp[0]);
983     gpgme_key_release(recp[1]);
984     gpgme_release(ctx);
985     return result;
986 }
987 
988 gboolean
ox_is_private_key_available(const char * const barejid)989 ox_is_private_key_available(const char* const barejid)
990 {
991     g_assert(barejid);
992     gboolean result = FALSE;
993 
994     gpgme_key_t key = _ox_key_lookup(barejid, TRUE);
995     if (key) {
996         if (_ox_key_is_usable(key, barejid, TRUE)) {
997             result = TRUE;
998         }
999         gpgme_key_unref(key);
1000     }
1001 
1002     return result;
1003 }
1004 
1005 gboolean
ox_is_public_key_available(const char * const barejid)1006 ox_is_public_key_available(const char* const barejid)
1007 {
1008     g_assert(barejid);
1009     gboolean result = FALSE;
1010     gpgme_key_t key = _ox_key_lookup(barejid, FALSE);
1011     if (key) {
1012         if (_ox_key_is_usable(key, barejid, FALSE)) {
1013             result = TRUE;
1014         }
1015         gpgme_key_unref(key);
1016     }
1017     return result;
1018 }
1019 
1020 static char*
_remove_header_footer(char * str,const char * const footer)1021 _remove_header_footer(char* str, const char* const footer)
1022 {
1023     int pos = 0;
1024     int newlines = 0;
1025 
1026     while (newlines < 2) {
1027         if (str[pos] == '\n') {
1028             newlines++;
1029         }
1030         pos++;
1031 
1032         if (str[pos] == '\0') {
1033             return NULL;
1034         }
1035     }
1036 
1037     char* stripped = strdup(&str[pos]);
1038     char* footer_start = g_strrstr(stripped, footer);
1039     footer_start[0] = '\0';
1040 
1041     return stripped;
1042 }
1043 
1044 static char*
_add_header_footer(const char * const str,const char * const header,const char * const footer)1045 _add_header_footer(const char* const str, const char* const header, const char* const footer)
1046 {
1047     GString* result_str = g_string_new("");
1048 
1049     g_string_append(result_str, header);
1050     g_string_append(result_str, "\n\n");
1051     g_string_append(result_str, str);
1052     g_string_append(result_str, "\n");
1053     g_string_append(result_str, footer);
1054 
1055     char* result = result_str->str;
1056     g_string_free(result_str, FALSE);
1057 
1058     return result;
1059 }
1060 
1061 static void
_save_pubkeys(void)1062 _save_pubkeys(void)
1063 {
1064     gsize g_data_size;
1065     gchar* g_pubkeys_data = g_key_file_to_data(pubkeyfile, &g_data_size, NULL);
1066     g_file_set_contents(pubsloc, g_pubkeys_data, g_data_size, NULL);
1067     g_chmod(pubsloc, S_IRUSR | S_IWUSR);
1068     g_free(g_pubkeys_data);
1069 }
1070 
1071 static gpgme_key_t
_ox_key_lookup(const char * const barejid,gboolean secret_only)1072 _ox_key_lookup(const char* const barejid, gboolean secret_only)
1073 {
1074     g_assert(barejid);
1075     log_debug("Looking for %s key: %s", secret_only == TRUE ? "Private" : "Public", barejid);
1076     gpgme_key_t key = NULL;
1077     gpgme_error_t error;
1078 
1079     gpgme_ctx_t ctx;
1080     error = gpgme_new(&ctx);
1081 
1082     if (error) {
1083         log_error("OX - gpgme_new failed: %s %s", gpgme_strsource(error), gpgme_strerror(error));
1084         return NULL;
1085     }
1086 
1087     error = gpgme_op_keylist_start(ctx, NULL, secret_only);
1088     if (error == GPG_ERR_NO_ERROR) {
1089         error = gpgme_op_keylist_next(ctx, &key);
1090         if (error != GPG_ERR_EOF && error != GPG_ERR_NO_ERROR) {
1091             log_error("OX: gpgme_op_keylist_next %s %s", gpgme_strsource(error), gpgme_strerror(error));
1092             return NULL;
1093         }
1094 
1095         GString* xmppuri = g_string_new("xmpp:");
1096         g_string_append(xmppuri, barejid);
1097 
1098         while (!error) {
1099             // Looking for XMPP URI UID
1100             gpgme_user_id_t uid = key->uids;
1101 
1102             while (uid) {
1103                 if (uid->name && strlen(uid->name) >= 10) {
1104                     if (g_strcmp0(uid->name, xmppuri->str) == 0) {
1105                         gpgme_release(ctx);
1106                         return key;
1107                     }
1108                 }
1109                 uid = uid->next;
1110             }
1111             gpgme_key_unref(key);
1112             error = gpgme_op_keylist_next(ctx, &key);
1113         }
1114     }
1115     gpgme_release(ctx);
1116 
1117     return key;
1118 }
1119 
1120 static gboolean
_ox_key_is_usable(gpgme_key_t key,const char * const barejid,gboolean secret)1121 _ox_key_is_usable(gpgme_key_t key, const char* const barejid, gboolean secret)
1122 {
1123     gboolean result = TRUE;
1124 
1125     if (key->revoked || key->expired || key->disabled) {
1126         result = FALSE;
1127     }
1128 
1129     return result;
1130 }
1131 
1132 /*!
1133  * @brief XMPP-OX: Decrypt OX Message.
1134  *
1135  *
1136  *
1137  * @param base64  base64_encode OpenPGP message.
1138  *
1139  * @result decrypt XMPP OX Message NULL terminated C-String
1140  */
1141 char*
p_ox_gpg_decrypt(char * base64)1142 p_ox_gpg_decrypt(char* base64)
1143 {
1144     // if there is no private key avaibale,
1145     // we don't try do decrypt
1146     if(!ox_is_private_key_available(connection_get_barejid())) {
1147         return NULL;
1148     }
1149     setlocale(LC_ALL, "");
1150     gpgme_check_version(NULL);
1151     gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
1152     gpgme_ctx_t ctx;
1153     gpgme_error_t error = gpgme_new(&ctx);
1154 
1155     if (GPG_ERR_NO_ERROR != error) {
1156         printf("gpgme_new: %d\n", error);
1157         return NULL;
1158     }
1159 
1160     error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
1161     if (error != 0) {
1162         log_error("GpgME Error: %s", gpgme_strerror(error));
1163     }
1164 
1165     gpgme_set_armor(ctx, 0);
1166     gpgme_set_textmode(ctx, 0);
1167     gpgme_set_offline(ctx, 1);
1168     gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
1169     if (error != 0) {
1170         log_error("GpgME Error: %s", gpgme_strerror(error));
1171     }
1172 
1173     gpgme_data_t plain = NULL;
1174     gpgme_data_t cipher = NULL;
1175 
1176     gsize s;
1177     guchar* encrypted = g_base64_decode(base64, &s);
1178     error = gpgme_data_new_from_mem(&cipher, (char*)encrypted, s, 0);
1179     if (error != 0) {
1180         log_error("GpgME Error gpgme_data_new_from_mem: %s", gpgme_strerror(error));
1181         return NULL;
1182     }
1183 
1184     error = gpgme_data_new(&plain);
1185     if (error != 0) {
1186         log_error("GpgME Error: %s", gpgme_strerror(error));
1187         return NULL;
1188     }
1189 
1190     error = gpgme_op_decrypt_verify(ctx, cipher, plain);
1191     if (error != 0) {
1192         log_error("GpgME Error gpgme_op_decrypt: %s", gpgme_strerror(error));
1193         error = gpgme_op_decrypt(ctx, cipher, plain);
1194         if (error != 0) {
1195             return NULL;
1196         }
1197     }
1198     size_t len;
1199     char* plain_str = gpgme_data_release_and_get_mem(plain, &len);
1200     char* result = malloc(len + 1);
1201     strcpy(result, plain_str);
1202     result[len] = '\0';
1203     return result;
1204 }
1205 
1206 /*!
1207  * \brief Read public key from file.
1208  *
1209  * This function is used the read a public key from a file.
1210  *
1211  * This function is used to read a key and push it on PEP. There are some checks
1212  * in this function:
1213  *
1214  * Key is not
1215  * - gkey->revoked
1216  * - gkey->expired
1217  * - gkey->disabled
1218  * - gkey->invalid
1219  * - gkey->secret
1220  *
1221  * Only one key in the file.
1222  *
1223  * \param filename filename to read the file.
1224  * \param key result with base64 encode key or NULL
1225  * \param fp result with the fingerprint or NULL
1226  *
1227  */
1228 
1229 void
p_ox_gpg_readkey(const char * const filename,char ** key,char ** fp)1230 p_ox_gpg_readkey(const char* const filename, char** key, char** fp)
1231 {
1232 
1233     log_info("Read OpenPGP Key from file %s", filename);
1234 
1235     GError* error = NULL;
1236     gchar* data = NULL;
1237     gsize size = -1;
1238 
1239     gboolean success = g_file_get_contents(filename,
1240                                            &data,
1241                                            &size,
1242                                            &error);
1243     if (success) {
1244         setlocale(LC_ALL, "");
1245         gpgme_check_version(NULL);
1246         gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
1247         gpgme_ctx_t ctx;
1248         gpgme_error_t error = gpgme_new(&ctx);
1249 
1250         if (GPG_ERR_NO_ERROR != error) {
1251             log_error("Read OpenPGP key from file: gpgme_new failed: %s", gpgme_strerror(error));
1252             return;
1253         }
1254 
1255         error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
1256         if (error != GPG_ERR_NO_ERROR) {
1257             log_error("Read OpenPGP key from file: set GPGME_PROTOCOL_OPENPGP:  %s", gpgme_strerror(error));
1258             return;
1259         }
1260 
1261         gpgme_set_armor(ctx, 0);
1262         gpgme_set_textmode(ctx, 0);
1263         gpgme_set_offline(ctx, 1);
1264         gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
1265 
1266         gpgme_data_t gpgme_data = NULL;
1267         error = gpgme_data_new(&gpgme_data);
1268         if (error != GPG_ERR_NO_ERROR) {
1269             log_error("Read OpenPGP key from file: gpgme_data_new %s", gpgme_strerror(error));
1270             return;
1271         }
1272 
1273         error = gpgme_data_new_from_mem(&gpgme_data, (char*)data, size, 0);
1274         if (error != GPG_ERR_NO_ERROR) {
1275             log_error("Read OpenPGP key from file: gpgme_data_new_from_mem %s", gpgme_strerror(error));
1276             return;
1277         }
1278         error = gpgme_op_keylist_from_data_start(ctx, gpgme_data, 0);
1279         if (error != GPG_ERR_NO_ERROR) {
1280             log_error("Read OpenPGP key from file: gpgme_op_keylist_from_data_start %s", gpgme_strerror(error));
1281             return;
1282         }
1283         gpgme_key_t gkey;
1284         error = gpgme_op_keylist_next(ctx, &gkey);
1285         if (error != GPG_ERR_NO_ERROR) {
1286             log_error("Read OpenPGP key from file: gpgme_op_keylist_next %s", gpgme_strerror(error));
1287             return;
1288         }
1289 
1290         gpgme_key_t end;
1291         error = gpgme_op_keylist_next(ctx, &end);
1292         if (error == GPG_ERR_NO_ERROR) {
1293             log_error("Read OpenPGP key from file: ambiguous key");
1294             return;
1295         }
1296 
1297         if (gkey->revoked || gkey->expired || gkey->disabled || gkey->invalid || gkey->secret) {
1298             log_error("Read OpenPGP key from file: Key is not valid");
1299             return;
1300         }
1301 
1302         gchar* keybase64 = g_base64_encode((const guchar*)data, size);
1303 
1304         *key = strdup(keybase64);
1305         *fp = strdup(gkey->fpr);
1306     } else {
1307         log_error("Read OpenPGP key from file: Unable to read file: %s", error->message);
1308     }
1309 }
1310 
1311 gboolean
p_ox_gpg_import(char * base64_public_key)1312 p_ox_gpg_import(char* base64_public_key)
1313 {
1314     gsize size = -1;
1315     guchar* key = g_base64_decode(base64_public_key, &size);
1316 
1317     setlocale(LC_ALL, "");
1318     gpgme_check_version(NULL);
1319     gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
1320     gpgme_ctx_t ctx;
1321     gpgme_error_t error = gpgme_new(&ctx);
1322 
1323     if (GPG_ERR_NO_ERROR != error) {
1324         log_error("Read OpenPGP key from file: gpgme_new failed: %s", gpgme_strerror(error));
1325         return FALSE;
1326     }
1327 
1328     error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
1329     if (error != GPG_ERR_NO_ERROR) {
1330         log_error("Read OpenPGP key from file: set GPGME_PROTOCOL_OPENPGP:  %s", gpgme_strerror(error));
1331         return FALSE;
1332     }
1333 
1334     gpgme_set_armor(ctx, 0);
1335     gpgme_set_textmode(ctx, 0);
1336     gpgme_set_offline(ctx, 1);
1337     gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
1338 
1339     gpgme_data_t gpgme_data = NULL;
1340     error = gpgme_data_new(&gpgme_data);
1341     if (error != GPG_ERR_NO_ERROR) {
1342         log_error("Read OpenPGP key from file: gpgme_data_new %s", gpgme_strerror(error));
1343         return FALSE;
1344     }
1345 
1346     gpgme_data_new_from_mem(&gpgme_data, (gchar*)key, size, 0);
1347     error = gpgme_op_import(ctx, gpgme_data);
1348     if (error != GPG_ERR_NO_ERROR) {
1349         log_error("Failed to import key");
1350     }
1351 
1352     return TRUE;
1353 }
1354