comparison mcabber/mcabber/pgp.c @ 2187:e3b66c8ead4f

PGP: Change gpg_encrypt() so that several encryption keys can be used
author Mikael Berthe <mikael@lilotux.net>
date Sun, 04 Oct 2015 19:04:04 +0200
parents e6d355e50d7a
children 84252c616919
comparison
equal deleted inserted replaced
2186:a852aed87ac0 2187:e3b66c8ead4f
1 /* 1 /*
2 * pgp.c -- PGP utility functions 2 * pgp.c -- PGP utility functions
3 * 3 *
4 * Copyright (C) 2006-2009 Mikael Berthe <mikael@lilotux.net> 4 * Copyright (C) 2006-2015 Mikael Berthe <mikael@lilotux.net>
5 * Some parts inspired by centericq (impgp.cc) 5 * Some parts inspired by centericq (impgp.cc)
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at 9 * the Free Software Foundation; either version 2 of the License, or (at
379 gpgme_release(ctx); 379 gpgme_release(ctx);
380 g_free(data); 380 g_free(data);
381 return decrypted_data; 381 return decrypted_data;
382 } 382 }
383 383
384 // gpg_encrypt(gpg_data, keyid) 384 // gpg_encrypt(gpg_data, keyids[], n)
385 // Return encrypted gpg_data with the key keyid (or NULL). 385 // Return encrypted gpg_data with the n keys from the keyids array (or NULL).
386 // The returned string must be freed with g_free() after use. 386 // The returned string must be freed with g_free() after use.
387 char *gpg_encrypt(const char *gpg_data, const char *keyid) 387 char *gpg_encrypt(const char *gpg_data, const char *keyids[], size_t nkeys)
388 { 388 {
389 gpgme_ctx_t ctx; 389 gpgme_ctx_t ctx;
390 gpgme_data_t in, out; 390 gpgme_data_t in, out;
391 char *encrypted_data = NULL, *edata; 391 char *encrypted_data = NULL, *edata;
392 size_t nread; 392 size_t nread;
393 gpgme_key_t key; 393 gpgme_key_t *keys;
394 gpgme_error_t err; 394 gpgme_error_t err;
395 unsigned i;
395 396
396 if (!gpg.enabled) 397 if (!gpg.enabled)
397 return NULL; 398 return NULL;
399
400 if (!keyids || !nkeys) {
401 return NULL;
402 }
398 403
399 err = gpgme_new(&ctx); 404 err = gpgme_new(&ctx);
400 if (err) { 405 if (err) {
401 scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, 406 scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8,
402 "GPGME error: %s", gpgme_strerror(err)); 407 "GPGME error: %s", gpgme_strerror(err));
405 410
406 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); 411 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP);
407 gpgme_set_textmode(ctx, 0); 412 gpgme_set_textmode(ctx, 0);
408 gpgme_set_armor(ctx, 1); 413 gpgme_set_armor(ctx, 1);
409 414
410 err = gpgme_get_key(ctx, keyid, &key, 0); 415 keys = g_new0(gpgme_key_t, 1+nkeys);
411 if (!err && key) { 416
412 gpgme_key_t keys[] = { key, 0 }; 417 for (i = 0; i < nkeys; i++) {
418 err = gpgme_get_key(ctx, keyids[i], &keys[i], 0);
419 if (err || !keys[i]) {
420 scr_LogPrint(LPRINT_LOGNORM, "GPGME encryption error: cannot use key %s",
421 keyids[i]);
422 // We need to have err not null to ensure we won't try to encrypt
423 // without this key.
424 if (!err) err = GPG_ERR_UNKNOWN_ERRNO;
425 break;
426 }
427 }
428
429 if (!err) {
413 err = gpgme_data_new_from_mem(&in, gpg_data, strlen(gpg_data), 0); 430 err = gpgme_data_new_from_mem(&in, gpg_data, strlen(gpg_data), 0);
414 if (!err) { 431 if (!err) {
415 err = gpgme_data_new(&out); 432 err = gpgme_data_new(&out);
416 if (!err) { 433 if (!err) {
417 err = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); 434 err = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
420 else 437 else
421 gpgme_data_release(out); 438 gpgme_data_release(out);
422 } 439 }
423 gpgme_data_release(in); 440 gpgme_data_release(in);
424 } 441 }
425 gpgme_key_release(key); 442
426 } else { 443 if (err && err != GPG_ERR_CANCELED) {
427 scr_LogPrint(LPRINT_LOGNORM, "GPGME encryption error: key not found"); 444 scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8,
428 err = 0; 445 "GPGME encryption error: %s", gpgme_strerror(err));
429 } 446 }
430 if (err && err != GPG_ERR_CANCELED) 447 }
431 scr_LogPrint(LPRINT_LOGNORM|LPRINT_NOTUTF8, 448
432 "GPGME encryption error: %s", gpgme_strerror(err)); 449 for (i = 0; keys[i]; i++)
450 gpgme_key_release(keys[i]);
451 g_free(keys);
433 gpgme_release(ctx); 452 gpgme_release(ctx);
434 edata = strip_header_footer(encrypted_data); 453 edata = strip_header_footer(encrypted_data);
435 if (encrypted_data) 454 if (encrypted_data)
436 free(encrypted_data); 455 free(encrypted_data);
437 return edata; 456 return edata;