Mercurial > ~mikael > mcabber > hg
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; |