From cvs at cvs.gnupg.org Fri Jun 1 00:22:02 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 01 Jun 2018 00:22:02 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-41-ge2aa38b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via e2aa38b56a991a0da052acfe7566cc7a146d3bb6 (commit) via 2219fc19d58ae1071493de92093b711f3c71454a (commit) from 618aa7f08db41911f25632d9fba23bca80908ebe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e2aa38b56a991a0da052acfe7566cc7a146d3bb6 Author: Werner Koch Date: Fri Jun 1 00:13:18 2018 +0200 core: Remove cruft from the engine-gpg code. * src/engine-gpg.c (read_status): Remove the handling of GPGME_STATUS_END_STREAM; this was used only by the former experimental --pipemode of gpg but that is not even anymore invoked here. (struct engine_gpg): Remove cmd.linked_data and .linked_idx. (build_argv): Remove code for linked_data. (gpg_new): Ditto. (gpg_set_command_handler): Remove arr linked_data. * src/engine-backend.h (engine_ops): Remove arg data from set_command_handler. * src/engine.c (_gpgme_engine_set_command_handler): Remove arg linked_data and adjust all callers. Signed-off-by: Werner Koch diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c index 17f79ac..ce4a7a9 100644 --- a/src/decrypt-verify.c +++ b/src/decrypt-verify.c @@ -74,7 +74,7 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/decrypt.c b/src/decrypt.c index ecd9c14..7dbc6fd 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -510,7 +510,7 @@ _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/edit.c b/src/edit.c index ca4d595..2867efb 100644 --- a/src/edit.c +++ b/src/edit.c @@ -139,8 +139,7 @@ interact_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key, opd->fnc_old = NULL; opd->fnc_value = fnc_value; - err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, - ctx, out); + err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, ctx); if (err) return err; @@ -219,8 +218,7 @@ edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key, opd->fnc_old = fnc; opd->fnc_value = fnc_value; - err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, - ctx, out); + err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, ctx); if (err) return err; diff --git a/src/encrypt-sign.c b/src/encrypt-sign.c index 4db46e2..cc34fbd 100644 --- a/src/encrypt-sign.c +++ b/src/encrypt-sign.c @@ -93,7 +93,7 @@ encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[], if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/encrypt.c b/src/encrypt.c index 2318497..a27a53a 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -242,7 +242,7 @@ encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[], { /* Symmetric encryption requires a passphrase. */ err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/engine-backend.h b/src/engine-backend.h index f692666..4f33da1 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -55,7 +55,7 @@ struct engine_ops void *fnc_value); gpgme_error_t (*set_command_handler) (void *engine, engine_command_handler_t fnc, - void *fnc_value, gpgme_data_t data); + void *fnc_value); gpgme_error_t (*set_colon_line_handler) (void *engine, engine_colon_line_handler_t fnc, void *fnc_value); diff --git a/src/engine-gpg.c b/src/engine-gpg.c index e955820..43d49fe 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -135,10 +135,6 @@ struct engine_gpg char *keyword; /* what has been requested (malloced) */ engine_command_handler_t fnc; void *fnc_value; - /* The kludges never end. This is used to couple command handlers - with output data in edit key mode. */ - gpgme_data_t linked_data; - int linked_idx; } cmd; struct gpgme_io_cbs io_cbs; @@ -502,8 +498,6 @@ gpg_new (void **engine, const char *file_name, const char *home_dir, gpg->colon.fd[1] = -1; gpg->cmd.fd = -1; gpg->cmd.idx = -1; - gpg->cmd.linked_data = NULL; - gpg->cmd.linked_idx = -1; /* Allocate the read buffer for the status pipe. */ gpg->status.bufsize = 1024; @@ -792,14 +786,14 @@ command_handler (void *opaque, int fd) -/* The Fnc will be called to get a value for one of the commands with - a key KEY. If the Code passed to FNC is 0, the function may release - resources associated with the returned value from another call. To - match such a second call to a first call, the returned value from - the first call is passed as keyword. */ +/* The FNC will be called to get a value for one of the commands with + * a key KEY. If the code passed to FNC is 0, the function may + * release resources associated with the returned value from another + * call. To match such a second call to a first call, the returned + * value from the first call is passed as keyword. */ static gpgme_error_t gpg_set_command_handler (void *engine, engine_command_handler_t fnc, - void *fnc_value, gpgme_data_t linked_data) + void *fnc_value) { engine_gpg_t gpg = engine; gpgme_error_t rc; @@ -818,7 +812,6 @@ gpg_set_command_handler (void *engine, engine_command_handler_t fnc, gpg->cmd.fnc = fnc; gpg->cmd.cb_data = (void *) &gpg->cmd; gpg->cmd.fnc_value = fnc_value; - gpg->cmd.linked_data = linked_data; gpg->cmd.used = 1; return 0; } @@ -1076,11 +1069,6 @@ build_argv (engine_gpg_t gpg, const char *pgmname) assert (gpg->cmd.idx == -1); gpg->cmd.idx = datac; } - else if (gpg->cmd.linked_data == a->data) - { - assert (gpg->cmd.linked_idx == -1); - gpg->cmd.linked_idx = datac; - } } fd_data_map[datac].data = a->data; @@ -1267,44 +1255,6 @@ read_status (engine_gpg_t gpg) if (err) return err; } - - if (r == GPGME_STATUS_END_STREAM) - { - if (gpg->cmd.used) - { - /* Before we can actually add the - command fd, we might have to flush - the linked output data pipe. */ - if (gpg->cmd.linked_idx != -1 - && gpg->fd_data_map[gpg->cmd.linked_idx].fd - != -1) - { - struct io_select_fd_s fds; - fds.fd = - gpg->fd_data_map[gpg->cmd.linked_idx].fd; - fds.for_read = 1; - fds.for_write = 0; - fds.opaque = NULL; - do - { - fds.signaled = 0; - _gpgme_io_select (&fds, 1, 1); - if (fds.signaled) - _gpgme_data_inbound_handler - (gpg->cmd.linked_data, fds.fd); - } - while (fds.signaled); - } - - /* XXX We must check if there are any - more fds active after removing this - one. */ - (*gpg->io_cbs.remove) - (gpg->fd_data_map[gpg->cmd.idx].tag); - gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd; - gpg->fd_data_map[gpg->cmd.idx].fd = -1; - } - } } } /* To reuse the buffer for the next line we have to diff --git a/src/engine.c b/src/engine.c index b716ca2..b629bea 100644 --- a/src/engine.c +++ b/src/engine.c @@ -596,8 +596,7 @@ _gpgme_engine_set_status_handler (engine_t engine, gpgme_error_t _gpgme_engine_set_command_handler (engine_t engine, engine_command_handler_t fnc, - void *fnc_value, - gpgme_data_t linked_data) + void *fnc_value) { if (!engine) return gpg_error (GPG_ERR_INV_VALUE); @@ -605,8 +604,7 @@ _gpgme_engine_set_command_handler (engine_t engine, if (!engine->ops->set_command_handler) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - return (*engine->ops->set_command_handler) (engine->engine, - fnc, fnc_value, linked_data); + return (*engine->ops->set_command_handler) (engine->engine, fnc, fnc_value); } gpgme_error_t diff --git a/src/engine.h b/src/engine.h index 8b692f2..c512a25 100644 --- a/src/engine.h +++ b/src/engine.h @@ -78,8 +78,7 @@ void _gpgme_engine_set_status_handler (engine_t engine, void *fnc_value); gpgme_error_t _gpgme_engine_set_command_handler (engine_t engine, engine_command_handler_t fnc, - void *fnc_value, - gpgme_data_t data); + void *fnc_value); gpgme_error_t _gpgme_engine_set_colon_line_handler (engine_t engine, engine_colon_line_handler_t fnc, diff --git a/src/genkey.c b/src/genkey.c index 16484ec..ffca7e8 100644 --- a/src/genkey.c +++ b/src/genkey.c @@ -259,7 +259,7 @@ genkey_start (gpgme_ctx_t ctx, int synchronous, const char *parms, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } @@ -345,7 +345,7 @@ createkey_start (gpgme_ctx_t ctx, int synchronous, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } @@ -433,7 +433,7 @@ createsubkey_start (gpgme_ctx_t ctx, int synchronous, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } @@ -519,7 +519,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int extraflags, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/keysign.c b/src/keysign.c index c2fcabb..5e49793 100644 --- a/src/keysign.c +++ b/src/keysign.c @@ -171,7 +171,7 @@ keysign_start (gpgme_ctx_t ctx, int synchronous, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/passwd.c b/src/passwd.c index 5bd67a5..6c03002 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -151,7 +151,7 @@ passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } diff --git a/src/sign.c b/src/sign.c index bfd9ad1..ab4109e 100644 --- a/src/sign.c +++ b/src/sign.c @@ -449,7 +449,7 @@ sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain, if (ctx->passphrase_cb) { err = _gpgme_engine_set_command_handler - (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + (ctx->engine, _gpgme_passphrase_command_handler, ctx); if (err) return err; } commit 2219fc19d58ae1071493de92093b711f3c71454a Author: Werner Koch Date: Thu May 31 23:56:06 2018 +0200 core: Minor cleanup in engine-gpg and -gpgsm. * src/engine-gpg.c: Remove errno.h. (build_argv): Use gpg_error_from_syserror instead of ERRNO. * src/engine-gpgsm.c: Remove errno.h. (status_handler): Remove check for EINTR; gpgme_data_write already handles EINTR. Signed-off-by: Werner Koch diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 173e940..e955820 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -26,7 +26,6 @@ #include #include #include -#include #ifdef HAVE_UNISTD_H # include #endif @@ -1039,10 +1038,10 @@ build_argv (engine_gpg_t gpg, const char *pgmname) if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0) == -1) { - int saved_errno = errno; + int saved_err = gpg_error_from_syserror (); free (fd_data_map); free_argv (argv); - return gpg_error (saved_errno); + return saved_err; } if (_gpgme_io_set_close_notify (fds[0], close_notify_handler, gpg) diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 7b22183..84a9315 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -37,7 +37,6 @@ #include #endif #include /* FIXME */ -#include #include "gpgme.h" #include "util.h" @@ -986,8 +985,7 @@ status_handler (void *opaque, int fd) while (linelen > 0) { nwritten = gpgme_data_write (gpgsm->inline_data, src, linelen); - if (!nwritten || (nwritten < 0 && errno != EINTR) - || nwritten > linelen) + if (nwritten <= 0 || nwritten > linelen) { err = gpg_error_from_syserror (); break; ----------------------------------------------------------------------- Summary of changes: src/decrypt-verify.c | 2 +- src/decrypt.c | 2 +- src/edit.c | 6 ++--- src/encrypt-sign.c | 2 +- src/encrypt.c | 2 +- src/engine-backend.h | 2 +- src/engine-gpg.c | 67 +++++++--------------------------------------------- src/engine-gpgsm.c | 4 +--- src/engine.c | 6 ++--- src/engine.h | 3 +-- src/genkey.c | 8 +++---- src/keysign.c | 2 +- src/passwd.c | 2 +- src/sign.c | 2 +- 14 files changed, 26 insertions(+), 84 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 1 01:37:43 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 01 Jun 2018 01:37:43 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-43-g662604c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 662604c5bcb4e03d3c9ecc670d4f320a2418ebb3 (commit) via dd19cabe81b7bf4177ea2ca741f6eb6cd1cab25e (commit) from e2aa38b56a991a0da052acfe7566cc7a146d3bb6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 662604c5bcb4e03d3c9ecc670d4f320a2418ebb3 Author: Werner Koch Date: Fri Jun 1 01:29:20 2018 +0200 core: New context flag "ignore-mdc-error". * src/context.h (gpgme_context): Add field ignore_mdc_error. * src/gpgme.c (gpgme_set_ctx_flag, gpgme_get_ctx_flag): Set/get it. * src/engine-gpg.c (engine_gpg): Add flags.ignore_mdc_error. (gpg_set_engine_flags): Set it. (build_argv): Pass option to gpg. * src/decrypt.c (_gpgme_decrypt_status_handler): Take care of flag. (gpgme_op_decrypt_result): Clear flag. (gpgme_op_decrypt): Clear flag. * src/decrypt-verify.c (gpgme_op_decrypt_verify): Clear flag (gpgme_op_decrypt_ext): Clear flag. * tests/run-decrypt.c (show_usage): Add option --ignore-mdc-error. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index bc1330a..4eb3dbe 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Noteworthy changes in version 1.11.2 (unreleased) * Interface changes relative to the 1.11.1 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc. + gpgme_set_ctx_flag EXTENDED: New flag 'ignore-mdc-error'. cpp: DecryptionResult::sessionKey NEW. cpp: DecryptionResult::symkeyAlgo NEW. cpp: Data::rewind NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index d877116..e3445a0 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3078,7 +3078,7 @@ the time when you verified the signature. The string given in @var{value} is passed to the GnuPG engines to request restrictions based on the origin of the request. Valid values are documented in the GnuPG manual and the gpg man page under the -option ``--request-origin''. Requires at least GnuPG 2.2.6 to have an +option @option{--request-origin}. Requires at least GnuPG 2.2.6 to have an effect. @item "no-symkey-cache" @@ -3086,6 +3086,15 @@ For OpenPGP disable the passphrase cache used for symmetrical en- and decryption. This cache is based on the message specific salt value. Requires at least GnuPG 2.2.7 to have an effect. + at item "ignore-mdc-error" +This flag passes the option @option{--ignore-mdc-error} to gpg. This +can be used to force decryption of a message which failed due to a +missing integrity check. This flag must be used with great caution +and only if it is a known non-corrupted old message and the decryption +result of the former try had the decryption result flag + at code{legacy_cipher_nomdc} set. For failsafe reasons this flag is +reset after each operation. + @end table This function returns @code{0} on success. diff --git a/src/context.h b/src/context.h index c8e75ba..bdab687 100644 --- a/src/context.h +++ b/src/context.h @@ -124,6 +124,10 @@ struct gpgme_context /* Do not use the symmtric encryption passphrase cache. */ unsigned int no_symkey_cache : 1; + /* Pass --ignore-mdc-error to gpg. Note that this flag is reset + * after the operation. */ + unsigned int ignore_mdc_error : 1; + /* Flags for keylist mode. */ gpgme_keylist_mode_t keylist_mode; diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c index ce4a7a9..1bd81c3 100644 --- a/src/decrypt-verify.c +++ b/src/decrypt-verify.c @@ -127,6 +127,7 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher, err = decrypt_verify_start (ctx, 1, GPGME_DECRYPT_VERIFY, cipher, plain); if (!err) err = _gpgme_wait_one (ctx); + ctx->ignore_mdc_error = 0; /* Always reset. */ return TRACE_ERR (err); } @@ -177,5 +178,6 @@ gpgme_op_decrypt_ext (gpgme_ctx_t ctx, err = _gpgme_decrypt_start (ctx, 1, flags, cipher, plain); if (!err) err = _gpgme_wait_one (ctx); + ctx->ignore_mdc_error = 0; /* Always reset. */ return TRACE_ERR (err); } diff --git a/src/decrypt.c b/src/decrypt.c index f2278d8..8c95ebe 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -97,6 +97,8 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx) TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx); + ctx->ignore_mdc_error = 0; /* Always reset this flag. */ + err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL); opd = hook; if (err || !opd) @@ -362,7 +364,8 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, return opd->pkdecrypt_failed; else if (opd->failed && opd->any_no_seckey) return gpg_error (GPG_ERR_NO_SECKEY); - else if (opd->failed || opd->not_integrity_protected) + else if (opd->failed || (opd->not_integrity_protected + && !ctx->ignore_mdc_error)) return gpg_error (GPG_ERR_DECRYPT_FAILED); else if (!opd->okay) return gpg_error (GPG_ERR_NO_DATA); @@ -564,5 +567,6 @@ gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain); if (!err) err = _gpgme_wait_one (ctx); + ctx->ignore_mdc_error = 0; /* Always reset. */ return TRACE_ERR (err); } diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 43d49fe..802af08 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -144,6 +144,7 @@ struct engine_gpg struct { unsigned int no_symkey_cache : 1; unsigned int offline : 1; + unsigned int ignore_mdc_error : 1; } flags; /* NULL or the data object fed to --override_session_key-fd. */ @@ -646,9 +647,10 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx) gpg->flags.no_symkey_cache = (ctx->no_symkey_cache && have_gpg_version (gpg, "2.2.7")); - gpg->flags.offline = (ctx->offline && have_gpg_version (gpg, "2.1.23")); + gpg->flags.ignore_mdc_error = !!ctx->ignore_mdc_error; + } @@ -955,6 +957,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname) argc++; } + if (gpg->flags.ignore_mdc_error) + { + argv[argc] = strdup ("--ignore-mdc-error"); + if (!argv[argc]) + { + int saved_err = gpg_error_from_syserror (); + free (fd_data_map); + free_argv (argv); + return saved_err; + } + argc++; + } + if (gpg->flags.offline) { argv[argc] = strdup ("--disable-dirmngr"); diff --git a/src/gpgme.c b/src/gpgme.c index 82d6747..b03c7b8 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -542,6 +542,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value) { ctx->no_symkey_cache = abool; } + else if (!strcmp (name, "ignore-mdc-error")) + { + ctx->ignore_mdc_error = abool; + } else err = gpg_error (GPG_ERR_UNKNOWN_NAME); @@ -591,6 +595,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name) { return ctx->no_symkey_cache? "1":""; } + else if (!strcmp (name, "ignore-mdc-error")) + { + return ctx->ignore_mdc_error? "1":""; + } else return NULL; } diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index 8ec0cb4..99a15c7 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -86,6 +86,7 @@ show_usage (int ex) " --override-session-key STRING use STRING as session key\n" " --request-origin STRING use STRING as request origin\n" " --no-symkey-cache disable the use of that cache\n" + " --ignore-mdc-error allow decryption of legacy data\n" " --unwrap remove only the encryption layer\n" , stderr); exit (ex); @@ -109,6 +110,7 @@ main (int argc, char **argv) const char *override_session_key = NULL; const char *request_origin = NULL; int no_symkey_cache = 0; + int ignore_mdc_error = 0; int raw_output = 0; if (argc) @@ -170,6 +172,11 @@ main (int argc, char **argv) no_symkey_cache = 1; argc--; argv++; } + else if (!strcmp (*argv, "--ignore-mdc-error")) + { + ignore_mdc_error = 1; + argc--; argv++; + } else if (!strcmp (*argv, "--unwrap")) { flags |= GPGME_DECRYPT_UNWRAP; @@ -241,7 +248,18 @@ main (int argc, char **argv) err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1"); if (err) { - fprintf (stderr, PGM ": error setting no-symkey-cache: %s\n", + fprintf (stderr, PGM ": error setting no-symkey-cache: %s\n", + gpgme_strerror (err)); + exit (1); + } + } + + if (ignore_mdc_error) + { + err = gpgme_set_ctx_flag (ctx, "ignore-mdc-error", "1"); + if (err) + { + fprintf (stderr, PGM ": error setting ignore-mdc-error: %s\n", gpgme_strerror (err)); exit (1); } commit dd19cabe81b7bf4177ea2ca741f6eb6cd1cab25e Author: Werner Koch Date: Fri Jun 1 01:01:08 2018 +0200 core: New decryption result flag 'legacy_cipher_nomdc'. * src/gpgme.h.in (_gpgme_op_decrypt_result): Add flag legacy_cipher_nomdc. * src/decrypt.c (parse_status_error): Set this flag. * tests/run-decrypt.c (print_result): print it. (main): Print the result even on error. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index 848f4e9..bc1330a 100644 --- a/NEWS +++ b/NEWS @@ -6,9 +6,11 @@ Noteworthy changes in version 1.11.2 (unreleased) * Interface changes relative to the 1.11.1 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - cpp: DecryptionResult::sessionKey NEW. - cpp: DecryptionResult::symkeyAlgo NEW. - cpp: Data::rewind NEW. + gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc. + cpp: DecryptionResult::sessionKey NEW. + cpp: DecryptionResult::symkeyAlgo NEW. + cpp: Data::rewind NEW. + Noteworthy changes in version 1.11.1 (2018-04-20) ------------------------------------------------- diff --git a/doc/gpgme.texi b/doc/gpgme.texi index c745675..d877116 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -5368,7 +5368,7 @@ This is a pointer to a structure used to store the result of a data, you can retrieve the pointer to the result with @code{gpgme_op_decrypt_result}. As with all result structures, it this structure shall be considered read-only and an application must -not allocated such a strucure on its own. The structure contains the +not allocate such a strucure on its own. The structure contains the following members: @table @code @@ -5378,9 +5378,22 @@ algorithm that is not supported. @item unsigned int wrong_key_usage : 1 @since{0.9.0} - This is true if the key was not used according to its policy. + at item unsigned int legacy_cipher_nomdc : 1 + at since{1.11.2} +The message was made by a legacy algorithm without any integrity +protection. This might be an old but legitimate message. + + at item unsigned int is_mime : 1; + at since{1.11.0} +The message claims that the content is a MIME object. + + at item unsigned int is_de_vs : 1; + at since{1.10.0} +The message was encrypted in a VS-NfD compliant way. This is a +specification in Germany for a restricted communication level. + @item gpgme_recipient_t recipients @since{1.1.0} diff --git a/src/decrypt.c b/src/decrypt.c index 7dbc6fd..f2278d8 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -57,7 +57,7 @@ typedef struct int any_no_seckey; /* If the engine emits a DECRYPTION_INFO status and that does not - * indicate that an integrity proetction mode is active, this flag + * indicate that an integrity protection mode is active, this flag * is set. */ int not_integrity_protected; @@ -214,6 +214,11 @@ parse_status_error (char *args, op_data_t opd) break; } } + else if (!strcmp (field[0], "nomdc_with_legacy_cipher")) + { + opd->result.legacy_cipher_nomdc = 1; + opd->not_integrity_protected = 1; + } free (args2); diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 49fafb9..5279f6a 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1365,8 +1365,12 @@ struct _gpgme_op_decrypt_result /* The message claims that the content is a MIME object. */ unsigned int is_mime : 1; + /* The message was made by a legacy algorithm without any integrity + * protection. This might be an old but legitimate message. */ + unsigned int legacy_cipher_nomdc : 1; + /* Internal to GPGME, do not use. */ - int _unused : 29; + int _unused : 28; gpgme_recipient_t recipients; diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index 69de139..8ec0cb4 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -55,6 +55,7 @@ print_result (gpgme_decrypt_result_t result) printf ("Original file name .: %s\n", nonnull(result->file_name)); printf ("Wrong key usage ....: %s\n", result->wrong_key_usage? "yes":"no"); + printf ("Legacy w/o MDC ... .: %s\n", result->legacy_cipher_nomdc?"yes":"no"); printf ("Compliance de-vs ...: %s\n", result->is_de_vs? "yes":"no"); printf ("MIME flag ..........: %s\n", result->is_mime? "yes":"no"); printf ("Unsupported algo ...: %s\n", nonnull(result->unsupported_algorithm)); @@ -267,6 +268,8 @@ main (int argc, char **argv) if (err) { fprintf (stderr, PGM ": decrypt failed: %s\n", gpgme_strerror (err)); + if (result) + print_result (result); exit (1); } if (result) ----------------------------------------------------------------------- Summary of changes: NEWS | 9 ++++++--- doc/gpgme.texi | 28 +++++++++++++++++++++++++--- src/context.h | 4 ++++ src/decrypt-verify.c | 2 ++ src/decrypt.c | 13 +++++++++++-- src/engine-gpg.c | 17 ++++++++++++++++- src/gpgme.c | 8 ++++++++ src/gpgme.h.in | 6 +++++- tests/run-decrypt.c | 23 ++++++++++++++++++++++- 9 files changed, 99 insertions(+), 11 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 1 10:12:53 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 01 Jun 2018 10:12:53 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-9-ga193ad3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via a193ad36f82ecf8e5a18b74dc9bc71fcf1ff2b38 (commit) via b2ed39c55af20223d60a3c6673fb823e53c9a016 (commit) from b6ddad7615a090d71c1fc00641280cf95af29e98 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a193ad36f82ecf8e5a18b74dc9bc71fcf1ff2b38 Author: Andre Heinecke Date: Fri Jun 1 10:11:44 2018 +0200 Show error status on syserror verify * src/mail.cpp (Mail::get_crypto_details): Show error. -- This helps with diagnostics. E.g. and ed25519 signature in vs-nfd mode leads to a sys error with status Invalid pubkey algorithm. diff --git a/src/mail.cpp b/src/mail.cpp index c20dc71..fefe2f9 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -2349,6 +2349,11 @@ Mail::get_crypto_details() m_verify_result.numSignatures() < 1) { message += _("There was an error verifying the signature.\n"); + const auto err = m_sig.status (); + if (err) + { + message += err.asString () + std::string ("\n"); + } } else if (m_sig.summary() & Signature::Summary::SigExpired) { commit b2ed39c55af20223d60a3c6673fb823e53c9a016 Author: Andre Heinecke Date: Fri Jun 1 10:06:18 2018 +0200 Block HTML for unsigned S/MIME messages * src/mail.cpp (Mail::set_block_status): New. Sets a MAPI prop to disable automatic HTML external references. (Mail::set_block_html): New. HTML content should be blocked. (Mail::parsing_done): check for block html. (Mail::update_body): Block HTML if necessary. * src/parsecontroller.cpp (ParseController::shouldBlockHtml): New. (is_valid_chksum): Check that the sig is valid even if it is untrusted. * src/mymapitags.h (PR_BLOCK_STATUS): New. * src/oomhelp.h (PR_BLOCK_STATUS_DASL): New. -- This blocks HTML display in unsigned S/MIME Mails to avoid attacks that rely on HTML side channels. If there is no text/plain part it will show the unparsed HTML. Trying to parse it with Outlook and then inserting at as plain text left the references intact and appears to be too risky. GnuPG-Bug-Id: T3986 diff --git a/src/mail.cpp b/src/mail.cpp index ca03066..c20dc71 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1085,7 +1085,7 @@ Mail::update_body() /** Outlook does not show newlines if \r\r\n is a newline. We replace these as apparently some other buggy MUA sends this. */ find_and_replace (html, "\r\r\n", "\r\n"); - if (opt.prefer_html && !html.empty()) + if (opt.prefer_html && !html.empty() && !m_block_html) { char *converted = ansi_charset_to_utf8 (m_parser->get_html_charset().c_str(), html.c_str(), html.size()); @@ -1096,9 +1096,71 @@ Mail::update_body() log_error ("%s:%s: Failed to modify html body of item.", SRCNAME, __func__); } + return; } auto body = m_parser->get_body (); + + if (body.empty () && m_block_html && !html.empty()) + { +#if 0 + Sadly the following code still offers to load external references + it might also be too dangerous if Outlook somehow autoloads the + references as soon as the Body is put into HTML + + + // Fallback to show HTML as plaintext if HTML display + // is blocked. + log_error ("%s:%s: No text body. Putting HTML into plaintext.", + SRCNAME, __func__); + + char *converted = ansi_charset_to_utf8 (m_parser->get_html_charset().c_str(), + html.c_str(), html.size()); + int ret = put_oom_string (m_mailitem, "HTMLBody", converted ? converted : ""); + xfree (converted); + if (ret) + { + log_error ("%s:%s: Failed to modify html body of item.", + SRCNAME, __func__); + body = html; + } + else + { + char *plainBody = get_oom_string (m_mailitem, "Body"); + + if (!plainBody) + { + log_error ("%s:%s: Failed to obtain converted plain body.", + SRCNAME, __func__); + body = html; + } + else + { + ret = put_oom_string (m_mailitem, "HTMLBody", plainBody); + xfree (plainBody); + if (ret) + { + log_error ("%s:%s: Failed to put plain into html body of item.", + SRCNAME, __func__); + body = html; + } + else + { + return; + } + } + } +#endif + body = html; + std::string buf = _("HTML display disabled."); + buf += "\n\n"; + buf += _("For security reasons HTML content in unsigned, encrypted\n" + "S/MIME mails cannot be displayed.\n\n" + "Please ask the sender to sign the message or to send it as plain text."); + + gpgol_message_box (get_window(), buf.c_str() , _("GpgOL"), MB_OK); + } + find_and_replace (body, "\r\r\n", "\r\n"); char *converted = ansi_charset_to_utf8 (m_parser->get_body_charset().c_str(), body.c_str(), body.size()); @@ -1160,7 +1222,16 @@ Mail::parsing_done() TRACEPOINT; /* Set categories according to the result. */ - update_categories(); + update_categories (); + + TRACEPOINT; + m_block_html = m_parser->shouldBlockHtml (); + + if (m_block_html) + { + // Just to be careful. + set_block_status (); + } TRACEPOINT; /* Update the body */ @@ -2966,3 +3037,30 @@ Mail::get_verification_result_dump() ss << m_verify_result; return ss.str(); } + +void +Mail::set_block_status() +{ + SPropValue prop; + + LPMESSAGE message = get_oom_base_message (m_mailitem); + + prop.ulPropTag = PR_BLOCK_STATUS; + prop.Value.l = 1; + HRESULT hr = message->SetProps (1, &prop, NULL); + + if (hr) + { + log_error ("%s:%s: can't set block value: hr=%#lx\n", + SRCNAME, __func__, hr); + } + + gpgol_release (message); + return; +} + +void +Mail::set_block_html(bool value) +{ + m_block_html = value; +} diff --git a/src/mail.h b/src/mail.h index 677ac7b..20e737a 100644 --- a/src/mail.h +++ b/src/mail.h @@ -487,6 +487,13 @@ public: /* Gets the string dump of the verification result. */ std::string get_verification_result_dump (); + + /* Block loading HTML content */ + void set_block_html (bool value); + + /* Remove automatic loading of HTML references setting. */ + void set_block_status (); + private: void update_categories (); void update_sigstate (); @@ -529,5 +536,6 @@ private: bool m_is_forwarded_crypto_mail; /* Is this a forward of a crypto mail */ bool m_is_send_again; /* Is this a send again of a crypto mail */ bool m_disable_att_remove_warning; /* Should not warn about attachment removal. */ + bool m_block_html; /* Force blocking of html content. e.g for unsigned S/MIME mails. */ }; #endif // MAIL_H diff --git a/src/mymapitags.h b/src/mymapitags.h index 9232c37..1458102 100644 --- a/src/mymapitags.h +++ b/src/mymapitags.h @@ -846,6 +846,7 @@ #define PR_SENT_REPRESENTING_SMTP_ADDRESS_A PROP_TAG( PT_STRING8, 0x5d02) #define PR_SENT_REPRESENTING_SMTP_ADDRESS_W PROP_TAG( PT_UNICODE, 0x5d02) #define PidTagSenderSmtpAddress_W PROP_TAG( PT_UNICODE, 0x5d01) +#define PR_BLOCK_STATUS PROP_TAG( PT_LONG, 0x1096) #define PROP_ID_SECURE_MIN 0x67F0 #define PROP_ID_SECURE_MAX 0x67FF diff --git a/src/oomhelp.h b/src/oomhelp.h index ccc8236..c2afd4a 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -118,6 +118,8 @@ DEFINE_OLEGUID(IID_IOleWindow, 0x00000114, 0, 0); "http://schemas.microsoft.com/mapi/proptag/0x5D08001F" #define PR_PIDNameContentType_DASL \ "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/content-type/0x0000001F" +#define PR_BLOCK_STATUS_DASL \ + "http://schemas.microsoft.com/mapi/proptag/0x10960003" #ifdef __cplusplus extern "C" { diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 3cd31a7..0db7734 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -77,7 +77,8 @@ ParseController::ParseController(LPSTREAM instream, msgtype_t type): m_inputprovider (new MimeDataProvider(instream, expect_no_headers(type))), m_outputprovider (new MimeDataProvider(expect_no_mime(type))), - m_type (type) + m_type (type), + m_block_html (false) { log_mime_parser ("%s:%s: Creating parser for stream: %p of type %i" " expect no headers: %i expect no mime: %i", @@ -90,7 +91,8 @@ ParseController::ParseController(FILE *instream, msgtype_t type): m_inputprovider (new MimeDataProvider(instream, expect_no_headers(type))), m_outputprovider (new MimeDataProvider(expect_no_mime(type))), - m_type (type) + m_type (type), + m_block_html (false) { log_mime_parser ("%s:%s: Creating parser for stream: %p of type %i", SRCNAME, __func__, instream, type); @@ -226,6 +228,25 @@ ParseController::setSender(const std::string &sender) m_sender = sender; } +static bool +is_valid_chksum(const GpgME::Signature &sig) +{ + switch (sig.summary()) + { + case GpgME::Signature::Valid: + case GpgME::Signature::Green: + case GpgME::Signature::KeyRevoked: + case GpgME::Signature::KeyExpired: + case GpgME::Signature::SigExpired: + case GpgME::Signature::CrlMissing: + case GpgME::Signature::CrlTooOld: + case GpgME::Signature::TofuConflict: + return true; + default: + return false; + } +} + void ParseController::parse() { @@ -358,9 +379,14 @@ ParseController::parse() m_verify_result.error().code()); TRACEPOINT; - /* Ensure that the Keys for the signatures are available */ + + bool has_valid_encrypted_checksum = false; + /* Ensure that the Keys for the signatures are available + and if it has a valid encrypted checksum. */ for (const auto sig: m_verify_result.signatures()) { + has_valid_encrypted_checksum = is_valid_chksum (sig); + sig.key(true, true); if (sig.validity() == Signature::Validity::Full || sig.validity() == Signature::Validity::Ultimate) @@ -371,6 +397,14 @@ ParseController::parse() } } + if (protocol == Protocol::CMS && decrypt && !m_decrypt_result.error() && + !has_valid_encrypted_checksum) + { + log_debug ("%s:%s:%p Encrypted S/MIME without checksum. Block HTML.", + SRCNAME, __func__, this); + m_block_html = true; + } + if (opt.enable_debug) { std::stringstream ss; diff --git a/src/parsecontroller.h b/src/parsecontroller.h index d3c67c8..c318b9d 100644 --- a/src/parsecontroller.h +++ b/src/parsecontroller.h @@ -102,6 +102,9 @@ public: void setSender(const std::string &sender); + bool shouldBlockHtml() const + { return m_block_html; } + private: /* State variables */ MimeDataProvider *m_inputprovider; @@ -111,6 +114,7 @@ private: GpgME::DecryptionResult m_decrypt_result; GpgME::VerificationResult m_verify_result; std::string m_sender; + bool m_block_html; }; #endif /* PARSECONTROLLER_H */ ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 107 +++++++++++++++++++++++++++++++++++++++++++++++- src/mail.h | 8 ++++ src/mymapitags.h | 1 + src/oomhelp.h | 2 + src/parsecontroller.cpp | 40 ++++++++++++++++-- src/parsecontroller.h | 4 ++ 6 files changed, 157 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 1 11:11:10 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 01 Jun 2018 11:11:10 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-45-g00b027a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 00b027af86f33782933c6200fe1ffe40e85f4346 (commit) via d46768c96082b4fd076506d7d3f0c03e61c59d51 (commit) from 662604c5bcb4e03d3c9ecc670d4f320a2418ebb3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 00b027af86f33782933c6200fe1ffe40e85f4346 Author: Andre Heinecke Date: Fri Jun 1 11:08:12 2018 +0200 cpp: Add gpgme_(get)set_ctx_flag * NEWS: Mention API extensions. * lang/cpp/src/context.cpp, lang/cpp/src/context.h (Context::setFlag, Context::getFlag): New. diff --git a/NEWS b/NEWS index 4eb3dbe..e70b9a9 100644 --- a/NEWS +++ b/NEWS @@ -8,9 +8,12 @@ Noteworthy changes in version 1.11.2 (unreleased) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc. gpgme_set_ctx_flag EXTENDED: New flag 'ignore-mdc-error'. - cpp: DecryptionResult::sessionKey NEW. - cpp: DecryptionResult::symkeyAlgo NEW. - cpp: Data::rewind NEW. + cpp: DecryptionResult::sessionKey NEW. + cpp: DecryptionResult::symkeyAlgo NEW. + cpp: DecryptionResult::isLegacyCipherNoMDC New. + cpp: Data::rewind NEW. + cpp: Context::setFlag NEW. + cpp: Context::getFlag NEW. Noteworthy changes in version 1.11.1 (2018-04-20) diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 135e4d5..8fde84a 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1478,6 +1478,16 @@ Error Context::startCreateSubkey(const Key &k, const char *algo, k.impl(), algo, reserved, expires, flags)); } +Error Context::setFlag(const char *name, const char *value) +{ + return Error(d->lasterr = gpgme_set_ctx_flag(d->ctx, name, value)); +} + +const char *Context::getFlag(const char *name) const +{ + return gpgme_get_ctx_flag(d->ctx, name); +} + // Engine Spawn stuff Error Context::spawn(const char *file, const char *argv[], Data &input, Data &output, Data &err, diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index aff8e49..8cccff5 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -86,6 +86,9 @@ public: void setOffline(bool useOfflineMode); bool offline() const; + const char *getFlag(const char *name) const; + Error setFlag(const char *name, const char *value); + enum CertificateInclusion { DefaultCertificates = -256, AllCertificatesExceptRoot = -2, @@ -453,6 +456,7 @@ public: { return d; } + private: // Helper functions that need to be context because they rely // on the "Friendlyness" of context to access the gpgme types. commit d46768c96082b4fd076506d7d3f0c03e61c59d51 Author: Andre Heinecke Date: Fri Jun 1 10:58:24 2018 +0200 cpp: Add legacy_cipher_nomdc * lang/cpp/src/decryptionresult.cpp, lang/cpp/src/decryptionresult.h (DecryptionResult::isLegacyCipherNoMDC): New. -- diff --git a/lang/cpp/src/decryptionresult.cpp b/lang/cpp/src/decryptionresult.cpp index 17524db..de58921 100644 --- a/lang/cpp/src/decryptionresult.cpp +++ b/lang/cpp/src/decryptionresult.cpp @@ -165,6 +165,11 @@ const char *GpgME::DecryptionResult::symkeyAlgo() const return d ? d->res.symkey_algo : nullptr; } +bool GpgME::DecryptionResult::isLegacyCipherNoMDC() const +{ + return d && d->res.legacy_cipher_nomdc; +} + class GpgME::DecryptionResult::Recipient::Private : public _gpgme_recipient { public: @@ -241,6 +246,7 @@ std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult &result << "\n unsupportedAlgorithm: " << protect(result.unsupportedAlgorithm()) << "\n isWrongKeyUsage: " << result.isWrongKeyUsage() << "\n isDeVs " << result.isDeVs() + << "\n legacyCipherNoMDC " << result.isLegacyCipherNoMDC() << "\n symkeyAlgo: " << protect(result.symkeyAlgo()) << "\n recipients:\n"; const std::vector recipients = result.recipients(); diff --git a/lang/cpp/src/decryptionresult.h b/lang/cpp/src/decryptionresult.h index c270223..e4d542d 100644 --- a/lang/cpp/src/decryptionresult.h +++ b/lang/cpp/src/decryptionresult.h @@ -87,6 +87,8 @@ public: Recipient recipient(unsigned int idx) const; std::vector recipients() const; + bool isLegacyCipherNoMDC() const; + private: class Private; void init(gpgme_ctx_t ctx); ----------------------------------------------------------------------- Summary of changes: NEWS | 9 ++++++--- lang/cpp/src/context.cpp | 10 ++++++++++ lang/cpp/src/context.h | 4 ++++ lang/cpp/src/decryptionresult.cpp | 6 ++++++ lang/cpp/src/decryptionresult.h | 2 ++ 5 files changed, 28 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 1 14:17:09 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 01 Jun 2018 14:17:09 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-12-gfc05ec0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via fc05ec08203882176486d7b19ab8504c12910f0c (commit) via 5f31ee9b15b34c37ef5696097292782a565ccaa0 (commit) via f46586d886cda26ba9c452a959a0d14013a11add (commit) from a193ad36f82ecf8e5a18b74dc9bc71fcf1ff2b38 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fc05ec08203882176486d7b19ab8504c12910f0c Author: Andre Heinecke Date: Fri Jun 1 14:09:07 2018 +0200 Try to convert clearsigned to utf8 on verify fail * src/parsecontroller.cpp (ParseController::parse): Try again with UTF-8 if verify opaque failed. -- We have a bit of a problem in that we access the body through the 8 bit interface and we need to give it to GnuPG as 8 bit. We now try utf8 if the native encoding did not give us a result. It's a bit of a hack but will work for messages from gpgol to gpgol and hopefully for some others, too. GnuPG-Bug-Id: T3962 diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 0db7734..88263a6 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -371,6 +371,54 @@ ParseController::parse() else { m_verify_result = ctx->verifyOpaqueSignature(input, output); + + const auto sigs = m_verify_result.signatures(); + bool allBad = sigs.size(); + for (const auto s :sigs) + { + if (!(s.summary() & Signature::Red)) + { + allBad = false; + break; + } + } + + if (allBad) + { + log_debug ("%s:%s:%p inline verify error trying native to utf8.", + SRCNAME, __func__, this); + + // Maybe we would need to take the internetcodepage here instead + // of native? + char *utf8 = native_to_utf8 (input.toString().c_str()); + if (utf8) + { + // Try again after conversion. + delete ctx; + ctx = Context::createForProtocol (protocol); + ctx->setArmor (true); + if (!m_sender.empty()) + { + ctx->setSender(m_sender.c_str()); + } + + input = Data (utf8, strlen (utf8)); + xfree (utf8); + + // Use a fresh output + auto provider = new MimeDataProvider (true); + + // Warning: The dtor of the Data object touches + // the provider. So we have to delete it after + // the assignment. + output = Data (provider); + delete m_outputprovider; + m_outputprovider = provider; + + // Try again + m_verify_result = ctx->verifyOpaqueSignature(input, output); + } + } } } delete ctx; commit 5f31ee9b15b34c37ef5696097292782a565ccaa0 Author: Andre Heinecke Date: Fri Jun 1 14:07:10 2018 +0200 Properly set UTF8 encoding for clearsigned * src/cryptcontroller.cpp(CryptController::update_mail_mapi): Set CPID. * src/mail.cpp (Mail::update_body): Fix charset variable. (Mail::inline_body_to_body): Also set CPID in OOM. * src/mymapitags.h: Define PR_INTERNET_CPID. -- GnuPG-Bug-Id: T3962 diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 2e9829b..7f701b2 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -29,6 +29,7 @@ #include "wks-helper.h" #include "overlay.h" #include "keycache.h" +#include "mymapitags.h" #include #include @@ -883,14 +884,6 @@ CryptController::update_mail_mapi () { log_debug ("%s:%s", SRCNAME, __func__); - if (m_mail->do_pgp_inline ()) - { - // Nothing to do for inline. - log_debug ("%s:%s: Inline mail. No MAPI update.", - SRCNAME, __func__); - return 0; - } - LPMESSAGE message = get_oom_base_message (m_mail->item()); if (!message) { @@ -899,6 +892,24 @@ CryptController::update_mail_mapi () return -1; } + if (m_mail->do_pgp_inline ()) + { + // Nothing to do for inline. + log_debug ("%s:%s: Inline mail. Setting encoding.", + SRCNAME, __func__); + + SPropValue prop; + prop.ulPropTag = PR_INTERNET_CPID; + prop.Value.l = 65001; + if (HrSetOneProp (message, &prop)) + { + log_error ("%s:%s: Failed to set CPID mapiprop.", + SRCNAME, __func__); + } + + return 0; + } + mapi_attach_item_t *att_table = mapi_create_attach_table (message, 0); // Set up the sink object for our MSOXSMIME attachment. diff --git a/src/mail.cpp b/src/mail.cpp index 4bdf8a6..b2d0fbe 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1090,7 +1090,7 @@ Mail::update_body() const auto charset = m_parser->get_html_charset(); int codepage = 0; - if (html_charset.empty()) + if (charset.empty()) { codepage = get_oom_int (m_mailitem, "InternetCodepage"); log_debug ("%s:%s: Did not find html charset." @@ -2675,6 +2675,9 @@ Mail::inline_body_to_body() return 0; } + /* For inline we always work with UTF-8 */ + put_oom_int (m_mailitem, "InternetCodepage", 65001); + int ret = put_oom_string (m_mailitem, "Body", body.c_str ()); return ret; diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index 1dcef01..a4774cb 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -500,7 +500,7 @@ mapi_get_body_as_stream (LPMESSAGE message) { /* The store knows about the Internet Charset Body property, thus try to get the body from this property if it exists. */ - + hr = message->OpenProperty (tag, &IID_IStream, 0, 0, (LPUNKNOWN*)&stream); if (!hr) diff --git a/src/mymapitags.h b/src/mymapitags.h index 1458102..69d1eef 100644 --- a/src/mymapitags.h +++ b/src/mymapitags.h @@ -847,6 +847,7 @@ #define PR_SENT_REPRESENTING_SMTP_ADDRESS_W PROP_TAG( PT_UNICODE, 0x5d02) #define PidTagSenderSmtpAddress_W PROP_TAG( PT_UNICODE, 0x5d01) #define PR_BLOCK_STATUS PROP_TAG( PT_LONG, 0x1096) +#define PR_INTERNET_CPID PROP_TAG( PT_LONG, 0x3FDE) #define PROP_ID_SECURE_MIN 0x67F0 #define PROP_ID_SECURE_MAX 0x67FF commit f46586d886cda26ba9c452a959a0d14013a11add Author: Andre Heinecke Date: Fri Jun 1 11:30:18 2018 +0200 Fix encoding for some inline pgp mails * src/mail.cpp (Mail::update_body): Use InternetCodepage if charset is not set by the parser. * src/mlang-charset.cpp (ansi_charset_to_utf8): Add handling for a directly provided codepage. * src/rfc2047parse.c (rfc2047_decode_tokens): Update caller. -- For PGP Inline the charset is not detected by the parsecontroller in that case we now just use the InternetCodepage from OOM. Tests show that this works properly. GnuPG-Bug-Id: T3962 diff --git a/src/mail.cpp b/src/mail.cpp index fefe2f9..4bdf8a6 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1087,8 +1087,19 @@ Mail::update_body() find_and_replace (html, "\r\r\n", "\r\n"); if (opt.prefer_html && !html.empty() && !m_block_html) { - char *converted = ansi_charset_to_utf8 (m_parser->get_html_charset().c_str(), - html.c_str(), html.size()); + const auto charset = m_parser->get_html_charset(); + + int codepage = 0; + if (html_charset.empty()) + { + codepage = get_oom_int (m_mailitem, "InternetCodepage"); + log_debug ("%s:%s: Did not find html charset." + " Using internet Codepage %i.", + SRCNAME, __func__, codepage); + } + + char *converted = ansi_charset_to_utf8 (charset.c_str(), html.c_str(), + html.size(), codepage); int ret = put_oom_string (m_mailitem, "HTMLBody", converted ? converted : ""); xfree (converted); if (ret) @@ -1162,8 +1173,21 @@ Mail::update_body() } find_and_replace (body, "\r\r\n", "\r\n"); - char *converted = ansi_charset_to_utf8 (m_parser->get_body_charset().c_str(), - body.c_str(), body.size()); + + const auto plain_charset = m_parser->get_body_charset(); + + int codepage = 0; + if (plain_charset.empty()) + { + codepage = get_oom_int (m_mailitem, "InternetCodepage"); + log_debug ("%s:%s: Did not find body charset. " + "Using internet Codepage %i.", + SRCNAME, __func__, codepage); + } + + char *converted = ansi_charset_to_utf8 (plain_charset.c_str(), + body.c_str(), body.size(), + codepage); int ret = put_oom_string (m_mailitem, "Body", converted ? converted : ""); xfree (converted); if (ret) diff --git a/src/mlang-charset.cpp b/src/mlang-charset.cpp index d800893..934c1e3 100644 --- a/src/mlang-charset.cpp +++ b/src/mlang-charset.cpp @@ -32,7 +32,7 @@ DEFINE_GUID (IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f, #include "mlang-charset.h" char *ansi_charset_to_utf8 (const char *charset, const char *input, - size_t inlen) + size_t inlen, int codepage) { LPMULTILANGUAGE multilang = NULL; MIMECSETINFO mime_info; @@ -44,9 +44,9 @@ char *ansi_charset_to_utf8 (const char *charset, const char *input, wchar_t *buf; char *ret; - if (!charset || !strlen (charset)) + if ((!charset || !strlen (charset)) && !codepage) { - log_debug ("%s:%s: No charset returning plain.", + log_debug ("%s:%s: No charset / codepage returning plain.", SRCNAME, __func__); return strdup (input); } @@ -71,20 +71,27 @@ char *ansi_charset_to_utf8 (const char *charset, const char *input, uinlen = (unsigned int) inlen; - mime_info.uiCodePage = 0; - mime_info.uiInternetEncoding = 0; - BSTR w_charset = utf8_to_wchar (charset); - err = multilang->GetCharsetInfo (w_charset, &mime_info); - xfree (w_charset); - if (err != S_OK) + if (!codepage) { - log_error ("%s:%s: Failed to find charset for: %s", - SRCNAME, __func__, charset); - gpgol_release (multilang); - return strdup(input); + mime_info.uiCodePage = 0; + mime_info.uiInternetEncoding = 0; + BSTR w_charset = utf8_to_wchar (charset); + err = multilang->GetCharsetInfo (w_charset, &mime_info); + xfree (w_charset); + if (err != S_OK) + { + log_error ("%s:%s: Failed to find charset for: %s", + SRCNAME, __func__, charset); + gpgol_release (multilang); + return strdup(input); + } + enc = (mime_info.uiInternetEncoding == 0) ? mime_info.uiCodePage : + mime_info.uiInternetEncoding; + } + else + { + enc = codepage; } - enc = (mime_info.uiInternetEncoding == 0) ? mime_info.uiCodePage : - mime_info.uiInternetEncoding; /** Get the size of the result */ err = multilang->ConvertStringToUnicode(&mode, enc, const_cast(input), diff --git a/src/mlang-charset.h b/src/mlang-charset.h index 06b0e68..7aaa26d 100644 --- a/src/mlang-charset.h +++ b/src/mlang-charset.h @@ -33,12 +33,13 @@ extern "C" { * @param charset: ANSI name of the charset to decode. * @param input: The input to convert. * @param inlen: The size of the input. + * @param codepage: Alternative codepage to be prefered over the name. * * @returns NULL on error or an UTF-8 encoded NULL terminated string. */ char *ansi_charset_to_utf8 (const char *charset, const char *input, - size_t inlen); + size_t inlen, int codepage); #ifdef __cplusplus } #endif diff --git a/src/rfc2047parse.c b/src/rfc2047parse.c index 17c7f73..5c96467 100644 --- a/src/rfc2047parse.c +++ b/src/rfc2047parse.c @@ -581,7 +581,7 @@ rfc2047_decode_tokens (rfc2047_token *tokens, size_t buflen) strncat (decoded, (char *) outptr, outlen); } else { #ifdef HAVE_W32_SYSTEM - str = ansi_charset_to_utf8 (charset, outptr, outlen); + str = ansi_charset_to_utf8 (charset, outptr, outlen, 0); #else log_debug ("%s:%s: Conversion not available on non W32 systems", SRCNAME, __func__); ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 27 +++++++++++++++++++-------- src/mail.cpp | 35 +++++++++++++++++++++++++++++++---- src/mapihelp.cpp | 2 +- src/mlang-charset.cpp | 37 ++++++++++++++++++++++--------------- src/mlang-charset.h | 3 ++- src/mymapitags.h | 1 + src/parsecontroller.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/rfc2047parse.c | 2 +- 8 files changed, 125 insertions(+), 30 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 1 15:00:42 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 01 Jun 2018 15:00:42 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-14-g75e02a5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 75e02a5985d3a57668ce7ea8b0057ca919850b1a (commit) via 9f7ec6eb29620e9cec66cefe5c10dc15e010b9b2 (commit) from fc05ec08203882176486d7b19ab8504c12910f0c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 75e02a5985d3a57668ce7ea8b0057ca919850b1a Author: Andre Heinecke Date: Fri Jun 1 15:00:14 2018 +0200 Clarify comment about inline pgp encoding * src/parsecontroller.cpp (ParseController::parse): Improve comment. diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index c52bae7..d14af9f 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -393,8 +393,19 @@ ParseController::parse() log_debug ("%s:%s:%p inline verify error trying native to utf8.", SRCNAME, __func__, this); - // Maybe we would need to take the internetcodepage here instead - // of native? + + /* The proper solution would be to take the encoding from + the mail / headers. Then convert the wchar body to that + encoding. Verify, and convert it after verifcation to + UTF-8 which the rest of the code expects. + + Or native_body from native ACP to InternetCodepage, then + verify and convert the output back to utf8 as the rest + expects. + + But as this is clearsigned and we don't really want that. + Meh. + */ char *utf8 = native_to_utf8 (input.toString().c_str()); if (utf8) { commit 9f7ec6eb29620e9cec66cefe5c10dc15e010b9b2 Author: Andre Heinecke Date: Fri Jun 1 14:59:25 2018 +0200 Add distinct error for legacy nomdc * src/parsecontroller.cpp (format_error): Check for isLegacyCipherNoMDC. -- GnuPG-Bug-Id: T3714 diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 88263a6..c52bae7 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -202,6 +202,11 @@ format_error(GpgME::DecryptionResult result, Protocol protocol) { msg += _("Failed to parse the mail."); } + else if (result.isLegacyCipherNoMDC()) + { + msg += _("Data is not integrity protected. " + "Decrypting it could be a security problem. (no MDC)"); + } else { msg += result.error().asString(); ----------------------------------------------------------------------- Summary of changes: src/parsecontroller.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 2 09:17:59 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sat, 02 Jun 2018 09:17:59 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-46-ge144a6d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via e144a6d70657675e28d43e42b48d879ff9b81d73 (commit) from 00b027af86f33782933c6200fe1ffe40e85f4346 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e144a6d70657675e28d43e42b48d879ff9b81d73 Author: Ben McGinnes Date: Sat Jun 2 17:15:40 2018 +1000 Authors: DCO * Added mine to the GPGME AUTHORS file. Mainly so I'm doing what I say myself when about to request another from someone ... ;) diff --git a/AUTHORS b/AUTHORS index c989eff..1bd3209 100644 --- a/AUTHORS +++ b/AUTHORS @@ -24,7 +24,7 @@ List of Copyright holders Copyright (C) 2004-2008 Igor Belyi Copyright (C) 2002 John Goerzen Copyright (C) 2014, 2015 Martin Albrecht - Copyright (C) 2015 Ben McGinnes + Copyright (C) 2015, 2018 Ben McGinnes Copyright (C) 2015-2016 Bundesamt f?r Sicherheit in der Informationstechnik Copyright (C) 2016 Intevation GmbH @@ -59,6 +59,9 @@ Colin Watson Tobias Mueller 2016-11-23:1479937342.11180.3.camel at cryptobitch.de: +Ben McGinnes +2017-12-16:20171216002102.l6aejk5xdp6xhtfi at adversary.org: + Copyright 2001, 2002, 2012, 2013 g10 Code GmbH ----------------------------------------------------------------------- Summary of changes: AUTHORS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 2 16:51:20 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sat, 02 Jun 2018 16:51:20 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-47-g8974234 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 897423422b9d3b856bfb72fbe1995b91d153a54e (commit) from e144a6d70657675e28d43e42b48d879ff9b81d73 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 897423422b9d3b856bfb72fbe1995b91d153a54e Author: Ben McGinnes Date: Sun Jun 3 00:46:46 2018 +1000 docs: python bindings howto * Another attempt at fixing the org-mode version. * A proof reader ascertained there were tabs in it instead of whitespace. * Stripped the lot out and replaced with standard 4 spaces, fixed every incorrect example ... and it still breaks upon save and/or export. * Added the reference to the mutt-groups.py script to demonstrate the groups.py module/code. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index c9397bc..3325c08 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -517,7 +517,7 @@ ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, sign=False) with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) + afile.write(ciphertext) #+end_src Though this is even more likely to be used like this; with the @@ -532,12 +532,13 @@ a_key = "0x12345678DEADBEEF" with open("secret_plans.txt", "rb") as afile: - text = afile.read() + text = afile.read() c = gpg.Context(armor=True) rkey = list(c.keylist(pattern=a_key, secret=False)) ciphertext, result, sign_result = c.encrypt(text, recipients=rkey, - sign=True, always_trust=True, add_encrypt_to=True) + sign=True, always_trust=True, + add_encrypt_to=True) with open("secret_plans.txt.asc", "wb") as afile: afile.write(ciphertext) @@ -587,8 +588,8 @@ if rpattern[i].can_encrypt == 1: logrus.append(rpattern[i]) - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False, - always_trust=True) + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + sign=False, always_trust=True) with open("secret_plans.txt.asc", "wb") as afile: afile.write(ciphertext) @@ -600,8 +601,8 @@ #+begin_src python ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, - always_trust=True, - add_encrypt_to=True) + always_trust=True, + add_encrypt_to=True) #+end_src The only keyword arguments requiring modification are those for @@ -618,7 +619,7 @@ import gpg with open("secret_plans.txt.asc", "rb") as afile: - text = afile.read() + text = afile.read() c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) @@ -628,24 +629,24 @@ if rpattern[i].can_encrypt == 1: logrus.append(rpattern[i]) - try: - ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, - add_encrypt_to=True) - except gpg.errors.InvalidRecipients as e: - for i in range(len(e.recipients)): - for n in range(len(logrus)): - if logrus[n].fpr == e.recipients[i].fpr: - logrus.remove(logrus[n]) - else: - pass try: ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) - except: - pass + except gpg.errors.InvalidRecipients as e: + for i in range(len(e.recipients)): + for n in range(len(logrus)): + if logrus[n].fpr == e.recipients[i].fpr: + logrus.remove(logrus[n]) + else: + pass - with open("secret_plans.txt.asc", "wb") as afile: - afile.write(ciphertext) + try: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True) + with open("secret_plans.txt.asc", "wb") as afile: + afile.write(ciphertext) + except: + pass #+end_src This will attempt to encrypt to all the keys searched for, then @@ -776,13 +777,13 @@ import gpg with open("/path/to/statement.txt", "rb") as tfile: - text = tfile.read() + text = tfile.read() c = gpg.Context() signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.NORMAL) with open("/path/to/statement.txt.sig", "wb") as afile: - afile.write(signed_data) + afile.write(signed_data) #+end_src @@ -808,7 +809,7 @@ signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) with open("/path/to/statement.txt.asc", "w") as afile: - afile.write(signed_data.decode()) + afile.write(signed_data.decode()) #+end_src As with normal signatures, detached signatures are best handled as @@ -818,13 +819,13 @@ import gpg with open("/path/to/statement.txt", "rb") as tfile: - text = tfile.read() + text = tfile.read() c = gpg.Context(signers=sig_src) signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.DETACH) with open("/path/to/statement.txt.sig", "wb") as afile: - afile.write(signed_data) + afile.write(signed_data) #+end_src @@ -860,13 +861,13 @@ import gpg with open("/path/to/statement.txt", "rb") as tfile: - text = tfile.read() + text = tfile.read() c = gpg.Context() signed_data, result = c.sign(text, mode=gpg.constants.sig.mode.CLEAR) with open("/path/to/statement.txt.asc", "wb") as afile: - afile.write(signed_data) + afile.write(signed_data) #+end_src @@ -906,8 +907,8 @@ {0} with key {1} made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) + """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, + time.ctime(sign.timestamp))) else: pass #+end_src @@ -938,8 +939,8 @@ {0} with key {1} made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) + """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, + time.ctime(sign.timestamp))) else: pass #+end_src @@ -987,8 +988,8 @@ {0} with key {1} made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) + """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, + time.ctime(sign.timestamp))) else: pass #+end_src @@ -1009,15 +1010,15 @@ verified = False print(e) - if verified is not None: + if verified is True: for i in range(len(result.signatures)): sign = result.signatures[i] print("""Good signature from: {0} with key {1} made at {2} - """.format(c.get_key(sign.fpr).uids[0].uid, - sign.fpr, time.ctime(sign.timestamp))) + """.format(c.get_key(sign.fpr).uids[0].uid, sign.fpr, + time.ctime(sign.timestamp))) else: pass #+end_src @@ -1109,15 +1110,15 @@ returned =GenkeyResult= object, which includes the following data: #+begin_src python - print(""" - Fingerprint: {0} - Primary Key: {1} - Public Key: {2} - Secret Key: {3} - Sub Key: {4} - User IDs: {5} - """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub, - dmkey.uid)) + print(""" + Fingerprint: {0} + Primary Key: {1} + Public Key: {2} + Secret Key: {3} + Sub Key: {4} + User IDs: {5} + """.format(dmkey.fpr, dmkey.primary, dmkey.pubkey, dmkey.seckey, dmkey.sub, + dmkey.uid)) #+end_src Alternatively the information can be confirmed using the command @@ -1128,7 +1129,7 @@ ~/.gnupg-dm/pubring.kbx ---------------------- sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA uid [ultimate] Danger Mouse bash-4.4$ @@ -1145,15 +1146,15 @@ Secret key is available. sec rsa3072/026D2F19E99E63AA - created: 2018-03-15 expires: 2019-03-15 usage: SC - trust: ultimate validity: ultimate + created: 2018-03-15 expires: 2019-03-15 usage: SC + trust: ultimate validity: ultimate [ultimate] (1). Danger Mouse [ultimate] (1). Danger Mouse - Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES - Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1 - Compression: ZLIB, BZIP2, ZIP, Uncompressed - Features: MDC, Keyserver no-modify + Cipher: TWOFISH, CAMELLIA256, AES256, CAMELLIA192, AES192, CAMELLIA128, AES, BLOWFISH, IDEA, CAST5, 3DES + Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1 + Compression: ZLIB, BZIP2, ZIP, Uncompressed + Features: MDC, Keyserver no-modify bash-4.4$ #+end_src @@ -1189,15 +1190,15 @@ As with the primary key, the results here can be checked with: #+begin_src python - print(""" - Fingerprint: {0} - Primary Key: {1} - Public Key: {2} - Secret Key: {3} - Sub Key: {4} - User IDs: {5} - """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub, - dmsub.uid)) + print(""" + Fingerprint: {0} + Primary Key: {1} + Public Key: {2} + Secret Key: {3} + Sub Key: {4} + User IDs: {5} + """.format(dmsub.fpr, dmsub.primary, dmsub.pubkey, dmsub.seckey, dmsub.sub, + dmsub.uid)) #+end_src As well as on the command line with: @@ -1207,7 +1208,7 @@ ~/.gnupg-dm/pubring.kbx ---------------------- sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA uid [ultimate] Danger Mouse ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] @@ -1251,7 +1252,7 @@ ~/.gnupg-dm/pubring.kbx ---------------------- sec rsa3072 2018-03-15 [SC] [expires: 2019-03-15] - 177B7C25DB99745EE2EE13ED026D2F19E99E63AA + 177B7C25DB99745EE2EE13ED026D2F19E99E63AA uid [ultimate] Danger Mouse uid [ultimate] Danger Mouse ssb rsa3072 2018-03-15 [E] [expires: 2018-09-13] @@ -1348,7 +1349,7 @@ if lines[i].startswith("group") is True: line = lines[i] else: - pass + pass groups = line.split(":")[-1].replace('"', '').split(',') @@ -1372,6 +1373,12 @@ =group_lines[i][0]= as the name of the group, but =group_lists[i][1]= is the key IDs of the group as a string. + A demonstration of using the =groups.py= module is also available + in the form of the executable =mutt-groups.py= script. This second + script reads all the group entries in a user's =gpg.conf= file and + converts them into crypt-hooks suitable for use with the Mutt and + Neomutt mail clients. + * Copyright and Licensing :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 139 +++++++++++++++++--------------- 1 file changed, 73 insertions(+), 66 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 5 03:42:36 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 05 Jun 2018 03:42:36 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-11-g7c004dd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 7c004dd58f28c182c1289bfa071cd1ec8892529d (commit) via 9f70e0af784d7744f0ae3ce0446e92ed058d241f (commit) from 825909e9cd5f344ece6c0b0ea3a9475df1d643de (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7c004dd58f28c182c1289bfa071cd1ec8892529d Author: NIIBE Yutaka Date: Mon May 14 22:39:44 2018 +0900 po: Fix Swedish and Turkish translations. -- (cherry picked from commit 61b1508281cda47b65c2bbd99cdef67fd6855c7c) Signed-off-by: NIIBE Yutaka diff --git a/po/sv.po b/po/sv.po index 2c93ebe..2f85206 100644 --- a/po/sv.po +++ b/po/sv.po @@ -5152,7 +5152,7 @@ msgstr "sp?rrningskommentar: " #. q = quit #. msgid "iImMqQsS" -msgstr "iImHhAsS" +msgstr "iIhHaAsS" msgid "No trust value assigned to:\n" msgstr "Inget tillitsv?rde tilldelat till:\n" diff --git a/po/tr.po b/po/tr.po index 4b41e97..f78c1a4 100644 --- a/po/tr.po +++ b/po/tr.po @@ -5088,7 +5088,7 @@ msgstr "y?r?rl?kten kald?rma a??klamas?: " #. q = quit #. msgid "iImMqQsS" -msgstr "bBmMaAkK" +msgstr "bBmMkKaA" msgid "No trust value assigned to:\n" msgstr "G?ven de?eri belirtilmemi?:\n" @@ -5121,7 +5121,7 @@ msgid " s = skip this key\n" msgstr " a = bu anahtar? atla\n" msgid " q = quit\n" -msgstr " ? = ??k\n" +msgstr " k = ??k\n" #, c-format msgid "" commit 9f70e0af784d7744f0ae3ce0446e92ed058d241f Author: NIIBE Yutaka Date: Mon May 14 22:18:43 2018 +0900 po: Fix Danish translation. -- (cherry picked from commit 49bbbd9dc5e1d4809e508ff4ab32fa238588917d) Debian-bug-id: 898552 Reported-by: Jonas Smedegaard Signed-off-by: NIIBE Yutaka diff --git a/po/da.po b/po/da.po index c8cd33c..74951b0 100644 --- a/po/da.po +++ b/po/da.po @@ -5065,7 +5065,7 @@ msgstr "tilbagekaldskommentar: " #. q = quit #. msgid "iImMqQsS" -msgstr "iImMqQsS" +msgstr "iIhHaAsS" msgid "No trust value assigned to:\n" msgstr "Ingen tillidsv?rdi tildelt til:\n" ----------------------------------------------------------------------- Summary of changes: po/da.po | 2 +- po/sv.po | 2 +- po/tr.po | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 5 04:25:55 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 05 Jun 2018 04:25:55 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-136-gd2e6b3e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via d2e6b3ea1d70db1039a828fb3a978a4504f8f0c5 (commit) from 874e391665405fc413a69f2ffacdb94bb08da7ff (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d2e6b3ea1d70db1039a828fb3a978a4504f8f0c5 Author: NIIBE Yutaka Date: Tue Jun 5 11:22:10 2018 +0900 g10: Remove bogus comment. * g10/mainproc.c (proc_pubkey_enc): Remove a comment. -- GnuPG always uses the OpenPGP algo number in its status report. We can find a function in GPGME, it's _gpgme_map_pk_algo. Signed-off-by: NIIBE Yutaka diff --git a/g10/mainproc.c b/g10/mainproc.c index cf22210..5689d73 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -475,11 +475,6 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) if (is_status_enabled()) { char buf[50]; - /* FIXME: For ECC support we need to map the OpenPGP algo number - to the Libgcrypt defined one. This is due a chicken-egg - problem: We need to have code in Libgcrypt for a new - algorithm so to implement a proposed new algorithm before the - IANA will finally assign an OpenPGP identifier. */ snprintf (buf, sizeof buf, "%08lX%08lX %d 0", (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo); write_status_text (STATUS_ENC_TO, buf); ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 5 ----- 1 file changed, 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 5 09:49:06 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 05 Jun 2018 09:49:06 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-48-g998fec8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 998fec8a4fbc46315fe6836980954eed402b38c5 (commit) from 897423422b9d3b856bfb72fbe1995b91d153a54e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 998fec8a4fbc46315fe6836980954eed402b38c5 Author: Werner Koch Date: Tue Jun 5 09:40:17 2018 +0200 json: Allow to compile with libgpg-error < 1.28 * src/cJSON.c: Use gpgrt fucntion only if available. -- We have a hack in gpgme-json to allow building with older libgpg-error versions. That whole thing will not work but the instead the binary will print an error at runtime that it needs to be build with a newer libgcrypt. There was a little bug here for the Debian packages libgpg-error versions which failed to build cJSON. cJSON is only needed be the full gpgme-json but nevertheless the Makefile wants to build it. The fix is straightforward. GnuPG-bug-id: 3971 Signed-off-by: Werner Koch diff --git a/src/cJSON.c b/src/cJSON.c index cf0cb13..38cb152 100644 --- a/src/cJSON.c +++ b/src/cJSON.c @@ -41,13 +41,13 @@ #include "cJSON.h" /* We use malloc function wrappers from gpgrt (aka libgpg-error). */ -#if 1 +#if GPGRT_VERSION_NUMBER >= 0x011c00 /* 1.28 */ # include # define xtrymalloc(a) gpgrt_malloc ((a)) # define xtrycalloc(a,b) gpgrt_calloc ((a), (b)) # define xtrystrdup(a) gpgrt_strdup ((a)) # define xfree(a) gpgrt_free ((a)) -#else +#else /* Without gpgrt (aka libgpg-error). */ # define xtrymalloc(a) malloc ((a)) # define xtrycalloc(a,b) calloc ((a), (b)) # define xtrystrdup(a) strdup ((a)) ----------------------------------------------------------------------- Summary of changes: src/cJSON.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 5 20:26:02 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 05 Jun 2018 20:26:02 +0200 Subject: [git] GPA - branch, master, updated. gpa-0.9.10-17-g48a685e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Assistant". The branch, master has been updated via 48a685eec1940f1b325da99040cc532aa66be191 (commit) via 85baf24947e4d05a116bd59c08cf198909a85fad (commit) via a5db9c242b8789413e703f70b3b5d5029b6956ed (commit) via fa562297a5aeb0e804211703af5622af6036999b (commit) from 069e354d8265ef0071522b14df981281e78a6409 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 48a685eec1940f1b325da99040cc532aa66be191 Author: Werner Koch Date: Tue Jun 5 20:17:18 2018 +0200 Simplify a xmalloc+snprintf use. * src/confdialog.c (create_dialog_tabs_2): Use g_strdup_printf. Signed-off-by: Werner Koch diff --git a/src/confdialog.c b/src/confdialog.c index 54bffdf..35ac05e 100644 --- a/src/confdialog.c +++ b/src/confdialog.c @@ -1018,7 +1018,6 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) if (option->flags & GPGME_CONF_GROUP) { char *name; - size_t name_len; const char *title; if (! group_has_options (option, &option)) @@ -1036,12 +1035,8 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) instantly privide that. */ title = (option->argname && *option->argname)? option->argname : option->description; - name_len = strlen (title) + strlen("") + 1; - name = xmalloc (name_len); - snprintf (name, name_len, "%s", title); - name[name_len - 1] = '\0'; + name = g_strdup_printf ("%s", title); percent_unescape (name, 0); - label = gtk_label_new (name); xfree (name); commit 85baf24947e4d05a116bd59c08cf198909a85fad Author: Ineiev Date: Tue May 22 09:39:02 2018 +0000 Unescape description texts. * src/confdialog.c (create_dialog_tabs_2): Strdup and unescape option->description and comp->description before using as labels. -- When not unescaped, commas in description texts show up like %2C. Signed-off-by: Ineiev diff --git a/src/confdialog.c b/src/confdialog.c index 0356b03..54bffdf 100644 --- a/src/confdialog.c +++ b/src/confdialog.c @@ -971,12 +971,16 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) if (reset) { + char *description; /* FIXME: Might need to put pages into scrolled panes if there are too many. */ page = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (dialog_notebook), page); - label = gtk_label_new (comp->description); + description = xstrdup (comp->description); + percent_unescape (description, 0); + label = gtk_label_new (description); + xfree (description); gtk_notebook_set_tab_label (GTK_NOTEBOOK (dialog_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (dialog_notebook), @@ -1036,6 +1040,8 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) name = xmalloc (name_len); snprintf (name, name_len, "%s", title); name[name_len - 1] = '\0'; + percent_unescape (name, 0); + label = gtk_label_new (name); xfree (name); @@ -1198,7 +1204,13 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) #if GTK_CHECK_VERSION (2, 12, 0) /* Add a tooltip description. */ if (option->description) - gtk_widget_set_tooltip_text (vbox, option->description); + { + char *description = xstrdup (option->description); + + percent_unescape (description, 0); + gtk_widget_set_tooltip_text (vbox, description); + xfree (description); + } #endif } option = option->next; commit a5db9c242b8789413e703f70b3b5d5029b6956ed Author: Ineiev Date: Tue May 22 08:28:10 2018 +0000 Fix percent unescaping. * src/utils.c (percent_unescape): Fix output string length. -- Without *p = 0, the function produces wrong results for any strings with escapes, for example: "%55" -> "U55" (should be "U") Signed-off-by: Ineiev diff --git a/src/utils.c b/src/utils.c index 0d3379f..e80b251 100644 --- a/src/utils.c +++ b/src/utils.c @@ -340,6 +340,7 @@ percent_unescape (char *string, int plus2space) n++; } } + *p = 0; return n; } commit fa562297a5aeb0e804211703af5622af6036999b Author: Ineiev Date: Tue May 22 09:16:10 2018 +0000 Eliminate arbitrary length limit on labels. * src/confdialog.c (create_dialog_tabs_2): Allocate memory for labels with xmalloc. -- The previous limit of 79 characters means 39 letters or less for non-Latin scripts, which is too short for some languages. Signed-off-by: Ineiev diff --git a/src/confdialog.c b/src/confdialog.c index 74ced87..0356b03 100644 --- a/src/confdialog.c +++ b/src/confdialog.c @@ -34,6 +34,7 @@ #include "gpgmetools.h" #include "gtktools.h" #include "options.h" +#include "gpa.h" /* Violation of GNOME standards: Cancel does not revert previous apply. We do not auto-apply or syntax check after focus @@ -1012,7 +1013,9 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) { if (option->flags & GPGME_CONF_GROUP) { - char name[80]; + char *name; + size_t name_len; + const char *title; if (! group_has_options (option, &option)) continue; @@ -1027,11 +1030,14 @@ create_dialog_tabs_2 (gpgme_conf_comp_t old_conf, gpgme_conf_comp_t new_conf) used for it. AFAICS, we would only need to prefix the description with the group name and gpgconf would instantly privide that. */ - snprintf (name, sizeof (name), "%s", - (option->argname && *option->argname)? - option->argname : option->description); - name[sizeof (name) - 1] = '\0'; + title = (option->argname && *option->argname)? + option->argname : option->description; + name_len = strlen (title) + strlen("") + 1; + name = xmalloc (name_len); + snprintf (name, name_len, "%s", title); + name[name_len - 1] = '\0'; label = gtk_label_new (name); + xfree (name); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_frame_set_label_widget (GTK_FRAME (frame), label); ----------------------------------------------------------------------- Summary of changes: src/confdialog.c | 27 ++++++++++++++++++++------- src/utils.c | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Assistant http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 08:57:17 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 08:57:17 +0200 Subject: [git] gnupg-doc - branch, master, updated. 07d8e33edb3470bc27d308967b5c243750cdac23 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 07d8e33edb3470bc27d308967b5c243750cdac23 (commit) from 7564686ae621038822092fb26066abf9dab8d56a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 07d8e33edb3470bc27d308967b5c243750cdac23 Author: Werner Koch Date: Wed Jun 6 08:49:19 2018 +0200 web: Add end-of-life dates diff --git a/web/download/index.org b/web/download/index.org index 36da43c..85e8c4c 100644 --- a/web/download/index.org +++ b/web/download/index.org @@ -40,7 +40,7 @@ The table lists the different GnuPG packages, followed by required libraries, required tools, optional software, and legacy versions - of GnuPG. + of GnuPG. For end-of-life dates see further down. | Name | Version | Date | Size | Tarball | Signature | |--------------+------------------------+-------------------------+-------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------| @@ -109,4 +109,25 @@ |---------+--------------------+------------------------------------------| +** End-of-life announcements + :PROPERTIES: + :CUSTOM_ID: end-of-life + :END: + + | Package | Branch | Birth | End-of-life | EOL | + |-----------+--------+------------+-------------+-----| + | | | | | | + | GnuPG | 1.0 | 1999-09-07 | 2002-09-07 | yes | + | | 1.2 | 2002-09-21 | 2005-01-01 | yes | + | | 1.4 | 2004-12-16 | (1) | | + | | 2.0 | 2006-11-11 | 2017-12-31 | yes | + | | 2.2 | 2014-11-06 | tba | | + | Libgcrypt | 1.5 | 2011-06-29 | 2016-12-31 | yes | + | | 1.6 | 2013-12-16 | 2017-06-30 | yes | + | | 1.7 | 2016-04-15 | 2019-06-30 | | + | | 1.8 | 2017-07-18 | tba | | + + - tba :: To be announced. + - (1) :: Legacy version; see remarks above. + # eof # ----------------------------------------------------------------------- Summary of changes: web/download/index.org | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 09:34:50 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 09:34:50 +0200 Subject: [git] gnupg-doc - branch, master, updated. e03e4c73c8d47ce83e694d341721764212f7cb10 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via e03e4c73c8d47ce83e694d341721764212f7cb10 (commit) from 07d8e33edb3470bc27d308967b5c243750cdac23 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e03e4c73c8d47ce83e694d341721764212f7cb10 Author: Werner Koch Date: Wed Jun 6 09:26:52 2018 +0200 web: Add more prose to the end-of-life section diff --git a/web/download/index.org b/web/download/index.org index 85e8c4c..6e3ed4c 100644 --- a/web/download/index.org +++ b/web/download/index.org @@ -114,20 +114,27 @@ :CUSTOM_ID: end-of-life :END: - | Package | Branch | Birth | End-of-life | EOL | - |-----------+--------+------------+-------------+-----| - | | | | | | - | GnuPG | 1.0 | 1999-09-07 | 2002-09-07 | yes | - | | 1.2 | 2002-09-21 | 2005-01-01 | yes | - | | 1.4 | 2004-12-16 | (1) | | - | | 2.0 | 2006-11-11 | 2017-12-31 | yes | - | | 2.2 | 2014-11-06 | tba | | - | Libgcrypt | 1.5 | 2011-06-29 | 2016-12-31 | yes | - | | 1.6 | 2013-12-16 | 2017-06-30 | yes | - | | 1.7 | 2016-04-15 | 2019-06-30 | | - | | 1.8 | 2017-07-18 | tba | | - - - tba :: To be announced. - - (1) :: Legacy version; see remarks above. + We announce the end-of-life date for a current stable version at + the time a new stable version is released. We maintain old + branches for at least two years. For GnuPG 2.2 we consider 2.1.0 + as the birth of this new stable branch. For the other packages we + don't maintain branches and thus there is no end-of-life; always + use the latest version. + + | Package | Ver. | EOL | End-of-life | Birth | + |-----------+------+-----+-------------+------------| + | | | | | | + | GnuPG | 1.0 | yes | 2002-09-07 | 1999-09-07 | + | | 1.2 | yes | 2005-01-01 | 2002-09-21 | + | | 1.4 | | none (1) | 2004-12-16 | + | | 2.0 | yes | 2017-12-31 | 2006-11-11 | + | | 2.2 | | tba | 2014-11-06 | + | Libgcrypt | 1.5 | yes | 2016-12-31 | 2011-06-29 | + | | 1.6 | yes | 2017-06-30 | 2013-12-16 | + | | 1.7 | | 2019-06-30 | 2016-04-15 | + | | 1.8 | | tba | 2017-07-18 | + + - /tba/: To be announced. + - /(1)/: Legacy version; see remarks above. # eof # ----------------------------------------------------------------------- Summary of changes: web/download/index.org | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 10:00:18 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 10:00:18 +0200 Subject: [git] gnupg-doc - branch, master, updated. 3ce9d4cdbcccddb6d065bd603f4d03921194ba4b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 3ce9d4cdbcccddb6d065bd603f4d03921194ba4b (commit) from e03e4c73c8d47ce83e694d341721764212f7cb10 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3ce9d4cdbcccddb6d065bd603f4d03921194ba4b Author: Werner Koch Date: Wed Jun 6 09:52:19 2018 +0200 web: Use strike-through for EOLed versions. diff --git a/web/download/index.org b/web/download/index.org index 6e3ed4c..e9df726 100644 --- a/web/download/index.org +++ b/web/download/index.org @@ -121,18 +121,18 @@ don't maintain branches and thus there is no end-of-life; always use the latest version. - | Package | Ver. | EOL | End-of-life | Birth | - |-----------+------+-----+-------------+------------| - | | | | | | - | GnuPG | 1.0 | yes | 2002-09-07 | 1999-09-07 | - | | 1.2 | yes | 2005-01-01 | 2002-09-21 | - | | 1.4 | | none (1) | 2004-12-16 | - | | 2.0 | yes | 2017-12-31 | 2006-11-11 | - | | 2.2 | | tba | 2014-11-06 | - | Libgcrypt | 1.5 | yes | 2016-12-31 | 2011-06-29 | - | | 1.6 | yes | 2017-06-30 | 2013-12-16 | - | | 1.7 | | 2019-06-30 | 2016-04-15 | - | | 1.8 | | tba | 2017-07-18 | + | Package | Ver. | End-of-life | Birth | + |-----------+-------+-------------+------------| + | | | | | + | GnuPG | +1.0+ | 2002-09-07 | 1999-09-07 | + | | +1.2+ | 2005-01-01 | 2002-09-21 | + | | 1.4 | none (1) | 2004-12-16 | + | | +2.0+ | 2017-12-31 | 2006-11-11 | + | | 2.2 | tba | 2014-11-06 | + | Libgcrypt | +1.5+ | 2016-12-31 | 2011-06-29 | + | | +1.6+ | 2017-06-30 | 2013-12-16 | + | | 1.7 | 2019-06-30 | 2016-04-15 | + | | 1.8 | tba | 2017-07-18 | - /tba/: To be announced. - /(1)/: Legacy version; see remarks above. ----------------------------------------------------------------------- Summary of changes: web/download/index.org | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 12:00:30 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Wed, 06 Jun 2018 12:00:30 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-53-g0356a66 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via 0356a667c5a8b4fdb4404cebb57475ed3f39ade9 (commit) from 332b4adbcc52ccf337cbc1943d5abef500769e10 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0356a667c5a8b4fdb4404cebb57475ed3f39ade9 Author: Maximilian Krambach Date: Wed Jun 6 11:57:41 2018 +0200 js: implement import/delete Key, some fixes -- * Keyring.js - implemented importKey: importing one or more armored public key blocks. - implemented deleteKey: deleting a public Key from gpg. * Key.js renamed property Key.armor to Key.armored * Helpers.js: toKeyIDArray does not complain anymore if there are no keys. Not having Keys in e.g. signing keys in encrypt is legitimate and common, the complaints were getting spammy * Errors.js: gpgme_errors now always pass an optional additional message, for easier debugging in minified code * Connection.js: Fix in gpgme-json responses containing objects * eslintrc.json: Start using eslint. A cleanup to conform to it is not done yet * Added further tests for the new functionality diff --git a/lang/js/.eslintrc.json b/lang/js/.eslintrc.json new file mode 100644 index 0000000..65253cf --- /dev/null +++ b/lang/js/.eslintrc.json @@ -0,0 +1,29 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "indent": [ + "warn", + 4 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "max-len": 1 + } +} \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/browsertest.html b/lang/js/BrowserTestExtension/browsertest.html index 3d81a9e..f3d7a40 100644 --- a/lang/js/BrowserTestExtension/browsertest.html +++ b/lang/js/BrowserTestExtension/browsertest.html @@ -18,6 +18,7 @@ + diff --git a/lang/js/BrowserTestExtension/tests/KeyImportExport.js b/lang/js/BrowserTestExtension/tests/KeyImportExport.js new file mode 100644 index 0000000..e6eb5a3 --- /dev/null +++ b/lang/js/BrowserTestExtension/tests/KeyImportExport.js @@ -0,0 +1,83 @@ +/* gpgme.js - Javascript integration for gpgme + * Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ + */ + +/* global describe, it, expect, Gpgmejs, ImportablePublicKey */ + +describe('Key importing', function () { + it('Prepare test Key (deleting it from gnupg, if present)', function(done){ + let prm = Gpgmejs.init(); + prm.then(function (context) { + expect(context.Keyring.getKeys).to.be.a('function'); + context.Keyring.getKeys(ImportablePublicKey.fingerprint).then( + function(result){ + if (result.length === 1) { + result[0].delete().then(function(result){ + expect(result).to.be.true; + done(); + }); + } else { + done(); + } + }); + }); + }); + + it('importing, updating, then deleting public Key', function (done) { + //This test runs in one large step, to ensure the proper state of the + // key in all stages. + let prm = Gpgmejs.init(); + prm.then(function (context) { + context.Keyring.getKeys(ImportablePublicKey.fingerprint).then( + function(result){ + expect(result).to.be.an('array'); + expect(result.length).to.equal(0); + context.Keyring.importKey(ImportablePublicKey.key, true) + .then(function(result){ + expect(result[0]).to.not.be.undefined; + expect(result[0].key).to.be.an('object'); + expect(result[0].key.fingerprint).to.equal( + ImportablePublicKey.fingerprint); + expect(result[0].status).to.equal('newkey'); + context.Keyring.importKey( + ImportablePublicKey.keyChangedUserId,true) + .then(function(res){ + expect(res[0]).to.not.be.undefined; + expect(res[0].key).to.be.an('object'); + expect(res[0].key.fingerprint).to.equal( + ImportablePublicKey.fingerprint); + expect(res[0].status).to.equal( + 'change'); + expect( + res[0].changes.userId).to.be.true; + expect( + res[0].changes.subkey).to.be.false; + expect( + res[0].changes.signature).to.be.true; + res[0].key.delete().then(function(result){ + expect(result).to.be.true; + done(); + }); + }); + }); + }); + }); + }); + +}); \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js index f5d2be1..e5c2f74 100644 --- a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js +++ b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js @@ -163,7 +163,6 @@ describe('Encryption and Decryption', function () { }).timeout(3000); it('Random data, input as base64', function (done) { - //TODO fails. The result is let data = bigBoringString(0.001); let b64data = btoa(data); let prm = Gpgmejs.init(); @@ -177,11 +176,11 @@ describe('Encryption and Decryption', function () { 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); - context.decrypt(answer.data).then( + context.decrypt(answer.data, true).then( function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); - expect(result.data).to.equal(data); + expect(result.data).to.equal(b64data); done(); }); }); diff --git a/lang/js/BrowserTestExtension/tests/inputvalues.js b/lang/js/BrowserTestExtension/tests/inputvalues.js index 52e3a7b..9dc1332 100644 --- a/lang/js/BrowserTestExtension/tests/inputvalues.js +++ b/lang/js/BrowserTestExtension/tests/inputvalues.js @@ -18,11 +18,12 @@ * SPDX-License-Identifier: LGPL-2.1+ */ -var inputvalues = { +var inputvalues = {// eslint-disable-line no-unused-vars encrypt: { good:{ data : 'Hello World.', - // Fingerprint of a key that has been imported to gnupg (i.e. see testkey.pub; testkey.sec) + // Fingerprint of a key that has been imported to gnupg + // (i.e. see testkey.pub; testkey.sec) fingerprint : 'D41735B91236FDB882048C5A2301635EEFF0CB05', data_nonascii: '??u?erste ?? f?r ?oquis at h?me! ?????? ????', @@ -45,7 +46,8 @@ var inputvalues = { ] }, bad: { - // valid Hex value, but not usable (not imported to gnupg, or bogus fingerprint) + // valid Hex value, but not usable (not imported to gnupg, or + // bogus fingerprint) fingerprint: 'CDC3A2B2860625CCBFC5AAAAAC6D1B604967FC4A' } }, @@ -54,14 +56,13 @@ var inputvalues = { invalid_startups: [ {all_passwords: true}, 'openpgpmode', - {api_style:"frankenstein"} + {api_style:'frankenstein'} ] } }; // (Pseudo-)Random String covering all of utf8. -function bigString(length){ - var uint = ''; +function bigString(length){// eslint-disable-line no-unused-vars let arr = []; for (let i= 0; i < length; i++){ arr.push(String.fromCharCode( @@ -71,7 +72,7 @@ function bigString(length){ return arr.join(''); } -function fixedLengthString(megabytes){ +function fixedLengthString(megabytes){// eslint-disable-line no-unused-vars let maxlength = 1024 * 1024 * megabytes / 2; let uint = new Uint8Array(maxlength); for (let i = 0; i < maxlength; i++){ @@ -83,7 +84,7 @@ function fixedLengthString(megabytes){ } // (Pseudo-)Random Uint8Array, given size in Megabytes -function bigUint8(megabytes){ +function bigUint8(megabytes){// eslint-disable-line no-unused-vars let maxlength = 1024 * 1024 * megabytes; let uint = new Uint8Array(maxlength); for (let i= 0; i < maxlength; i++){ @@ -92,11 +93,13 @@ function bigUint8(megabytes){ return uint; } -// (Pseudo-)Random string with very limited charset (ascii only, no control chars) -function bigBoringString(megabytes){ +// (Pseudo-)Random string with very limited charset +// (ascii only, no control chars) +function bigBoringString(megabytes){// eslint-disable-line no-unused-vars let maxlength = 1024 * 1024 * megabytes; let string = []; - let chars = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + let chars = + ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; for (let i= 0; i < maxlength; i++){ string.push(chars[Math.floor(Math.random() * chars.length)]); } @@ -105,12 +108,13 @@ function bigBoringString(megabytes){ // Some String with simple chars, with different characteristics, but still // expected to occur in an averag message +// eslint-disable-next-line no-unused-vars function slightlyLessBoringString(megabytes, set){ let maxlength = 1024 * 1024 * megabytes; let string = []; let chars = ''; if (set ===1 ) { - chars = '\n\"\r \''; + chars = '\n"\r \''; } else if (set === 2 ) { chars = '()=?`#+-{}[]'; } else if (set === 3){ @@ -118,7 +122,7 @@ function slightlyLessBoringString(megabytes, set){ } else if (set ===4) { chars = '???????~??||@'; } else { - chars = '*<>\n\"\r?$%&/()=?`#+-{}[] \''; + chars = '*<>\n"\r?$%&/()=?`#+-{}[] \''; } for (let i= 0; i < maxlength; i++){ string.push(chars[Math.floor(Math.random() * chars.length)]); @@ -127,7 +131,7 @@ function slightlyLessBoringString(megabytes, set){ } // Data encrypted with testKey -var encryptedData = +var encryptedData =// eslint-disable-line no-unused-vars '-----BEGIN PGP MESSAGE-----\n' + '\n' + 'hQEMA6B8jfIUScGEAQgAlANd3uyhmhYLzVcfz4LEqA8tgUC3n719YH0iuKEzG/dv\n' + @@ -141,3 +145,76 @@ var encryptedData = 'kSAQYOHplfA7YJWkrlRm\n' + '=zap6\n' + '-----END PGP MESSAGE-----\n'; + +var ImportablePublicKey = {// eslint-disable-line no-unused-vars + fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A', + key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + + '\n' + + 'mQENBFsPvK0BCACaIgoIN+3g05mrTITULK/YDTrfg4W7RdzIZBxch5CM0zdu/dby\n' + + 'esFwaJbVQIqu54CRz5xKAiWmRrQCaRvhvjY0na5r5UUIpbeQiOVrl65JtNbRmlik\n' + + 'd9Prn1kZDUOZiCPIKn+/M2ecJ92YedM7I4/BbpiaFB11cVrPFg4thepn0LB3+Whp\n' + + '9HDm4orH9rjy6IUr6yjWNIr+LYRY6/Ip2vWcMVjleEpTFznXrm83hrJ0n0INtyox\n' + + 'Nass4eDWkgo6ItxDFFLOORSmpfrToxZymSosWqgux/qG6sxHvLqlqy6Xe3ZYRFbG\n' + + '+JcA1oGdwOg/c0ndr6BYYiXTh8+uUJfEoZvzABEBAAG0HEJsYSBCbGEgPGJsYWJs\n' + + 'YUBleGFtcGxlLm9yZz6JAVQEEwEIAD4WIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUC\n' + + 'Ww+8rQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD2N5DBHmAn\n' + + 'igwIB/9K3E3Yev9taZP4KnXPhk1oMQRW1MWAsFGUr+70N85VwedpUawymW4vXi1+\n' + + 'hMeTc39QjmZ0+VqHkJttkqEN6bLcEvgmU/mOlOgKdzy6eUcasYAzgoAKUqSX1SPs\n' + + '0Imo7Tj04wnfnVwvKxaeadi0VmdqIYaW75UlrzIaltsBctyeYH8sBrvaTLscb4ON\n' + + '46OM3Yw2G9+dBF0P+4UYFHP3EYZMlzNxfwF+i2HsYcNDHlcLfjENr9GwKn5FJqpY\n' + + 'Iq3qmI37w1hVasHDxXdz1X06dpsa6Im4ACk6LXa7xIQlXxTgPAQV0sz2yB5eY+Md\n' + + 'uzEXPGW+sq0WRp3hynn7kVP6QQYvuQENBFsPvK0BCACwvBcmbnGJk8XhEBRu2QN3\n' + + 'jKgVs3CG5nE2Xh20JipZwAuGHugDLv6/jlizzz5jtj3SAHVtJB8lJW8I0cNSEIX8\n' + + 'bRYH4C7lP2DTb9CgMcGErQIyK480+HIsbsZhJSNHdjUUl6IPEEVfSQzWaufmuswe\n' + + 'e+giqHiTsaiW20ytXilwVGpjlHBaxn/bpskZ0YRasgnPqKgJD3d5kunNqWoyCpMc\n' + + 'FYgDERvPbhhceFbvFE9G/u3gbcuV15mx53dDX0ImvPcvJnDOyJS9yr7ApdOV312p\n' + + 'A1MLbxfPnbnVu+dGXn7D/VCDd5aBYVPm+5ANrk6z9lYKH9aO5wgXpLAdJvutCOL5\n' + + 'ABEBAAGJATwEGAEIACYWIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUCWw+8rQIbDAUJ\n' + + 'A8JnAAAKCRD2N5DBHmAnigMVB/484G2+3R0cAaj3V/z4gW3MRSMhcYqEMyJ/ACdo\n' + + '7y8eoreYW843JWWVDRY6/YcYYGuBBP47WO4JuP2wIlVn17XOCSgnNjmmjsIYiAzk\n' + + 'op772TB27o0VeiFX5iWcawy0EI7JCb23xpI+QP31ksL2yyRYFXCtXSUfcOrLpCY8\n' + + 'aEQMQbAGtkag1wHTo/Tf/Vip8q0ZEQ4xOKTR2/ll6+inP8kzGyzadElUnH1Q1OUX\n' + + 'd2Lj/7BpBHE2++hAjBQRgnyaONF7mpUNEuw64iBNs0Ce6Ki4RV2+EBLnFubnFNRx\n' + + 'fFJcYXcijhuf3YCdWzqYmPpU/CtF4TgDlfSsdxHxVOmnZkY3\n' + + '=qP6s\n' + + '-----END PGP PUBLIC KEY BLOCK-----\n', + + keyChangedUserId: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + + '\n' + + 'mQENBFsPvK0BCACaIgoIN+3g05mrTITULK/YDTrfg4W7RdzIZBxch5CM0zdu/dby\n' + + 'esFwaJbVQIqu54CRz5xKAiWmRrQCaRvhvjY0na5r5UUIpbeQiOVrl65JtNbRmlik\n' + + 'd9Prn1kZDUOZiCPIKn+/M2ecJ92YedM7I4/BbpiaFB11cVrPFg4thepn0LB3+Whp\n' + + '9HDm4orH9rjy6IUr6yjWNIr+LYRY6/Ip2vWcMVjleEpTFznXrm83hrJ0n0INtyox\n' + + 'Nass4eDWkgo6ItxDFFLOORSmpfrToxZymSosWqgux/qG6sxHvLqlqy6Xe3ZYRFbG\n' + + '+JcA1oGdwOg/c0ndr6BYYiXTh8+uUJfEoZvzABEBAAG0HEJsYSBCbGEgPGJsYWJs\n' + + 'YUBleGFtcGxlLm9yZz6JAVQEEwEIAD4WIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUC\n' + + 'Ww+8rQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD2N5DBHmAn\n' + + 'igwIB/9K3E3Yev9taZP4KnXPhk1oMQRW1MWAsFGUr+70N85VwedpUawymW4vXi1+\n' + + 'hMeTc39QjmZ0+VqHkJttkqEN6bLcEvgmU/mOlOgKdzy6eUcasYAzgoAKUqSX1SPs\n' + + '0Imo7Tj04wnfnVwvKxaeadi0VmdqIYaW75UlrzIaltsBctyeYH8sBrvaTLscb4ON\n' + + '46OM3Yw2G9+dBF0P+4UYFHP3EYZMlzNxfwF+i2HsYcNDHlcLfjENr9GwKn5FJqpY\n' + + 'Iq3qmI37w1hVasHDxXdz1X06dpsa6Im4ACk6LXa7xIQlXxTgPAQV0sz2yB5eY+Md\n' + + 'uzEXPGW+sq0WRp3hynn7kVP6QQYvtCZTb21lb25lIEVsc2UgPHNvbWVvbmVlbHNl\n' + + 'QGV4YW1wbGUub3JnPokBVAQTAQgAPhYhBHgDSUi6f10Om9tn5PY3kMEeYCeKBQJb\n' + + 'D705AhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEPY3kMEeYCeK\n' + + 'aIUH/2o+Ra+GzxgZrVexXLL+FCSmcu0cxeWfMhL8jd96c6uXIT21qQMRU2jgvnUp\n' + + 'Wdi/BeLKp5lYwywm04PFhmRVxWXLuLArCsDu+CFys+aPeybnjikPBZov6P8/cZV3\n' + + 'cd6zxFvqB9J15HjDMcl/r5v6d4CgSLKlFebrO5WKxHa6zGK9TRMQrqTu1heKHRf6\n' + + '4+Wj+MZmYnPzEQePjiBw/VkJ1Nm37Dd24gKdcN/qJFwEOqvbI5RIjB7xqoDslZk9\n' + + 'sAivBXwF0E9HKqvh4WZZeA7uaWNdGo/cQkD5rab5SdHGNPHLbzoRWScsM8WYtsME\n' + + 'dEMp5iPuG9M63+TD7losAkJ/TlS5AQ0EWw+8rQEIALC8FyZucYmTxeEQFG7ZA3eM\n' + + 'qBWzcIbmcTZeHbQmKlnAC4Ye6AMu/r+OWLPPPmO2PdIAdW0kHyUlbwjRw1IQhfxt\n' + + 'FgfgLuU/YNNv0KAxwYStAjIrjzT4cixuxmElI0d2NRSXog8QRV9JDNZq5+a6zB57\n' + + '6CKoeJOxqJbbTK1eKXBUamOUcFrGf9umyRnRhFqyCc+oqAkPd3mS6c2pajIKkxwV\n' + + 'iAMRG89uGFx4Vu8UT0b+7eBty5XXmbHnd0NfQia89y8mcM7IlL3KvsCl05XfXakD\n' + + 'UwtvF8+dudW750ZefsP9UIN3loFhU+b7kA2uTrP2Vgof1o7nCBeksB0m+60I4vkA\n' + + 'EQEAAYkBPAQYAQgAJhYhBHgDSUi6f10Om9tn5PY3kMEeYCeKBQJbD7ytAhsMBQkD\n' + + 'wmcAAAoJEPY3kMEeYCeKAxUH/jzgbb7dHRwBqPdX/PiBbcxFIyFxioQzIn8AJ2jv\n' + + 'Lx6it5hbzjclZZUNFjr9hxhga4EE/jtY7gm4/bAiVWfXtc4JKCc2OaaOwhiIDOSi\n' + + 'nvvZMHbujRV6IVfmJZxrDLQQjskJvbfGkj5A/fWSwvbLJFgVcK1dJR9w6sukJjxo\n' + + 'RAxBsAa2RqDXAdOj9N/9WKnyrRkRDjE4pNHb+WXr6Kc/yTMbLNp0SVScfVDU5Rd3\n' + + 'YuP/sGkEcTb76ECMFBGCfJo40XualQ0S7DriIE2zQJ7oqLhFXb4QEucW5ucU1HF8\n' + + 'UlxhdyKOG5/dgJ1bOpiY+lT8K0XhOAOV9Kx3EfFU6admRjc=\n' + + '=9WZ7\n' + + '-----END PGP PUBLIC KEY BLOCK-----\n' +}; diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js index 3480d81..8c4cba7 100644 --- a/lang/js/src/Connection.js +++ b/lang/js/src/Connection.js @@ -103,7 +103,7 @@ export class Connection{ } if (!message || !message instanceof GPGME_Message){ this.disconnect(); - return Promise.reject(gpgme_error('PARAM_WRONG'), message); + return Promise.reject(gpgme_error('PARAM_WRONG', 'Connection.post')); } if (message.isComplete !== true){ this.disconnect(); @@ -221,12 +221,13 @@ class Answer{ if (!this._response.hasOwnProperty(key)){ this._response[key] = []; } + if (Array.isArray(msg[key])) { for (let i=0; i< msg[key].length; i++) { this._response[key].push(msg[key][i]); } } else { - this._response[key].push(msg[key][i]); + this._response[key].push(msg[key]); } } else { diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js index 3b53eeb..2f2bfd5 100644 --- a/lang/js/src/Errors.js +++ b/lang/js/src/Errors.js @@ -74,7 +74,7 @@ const err_list = { 'KEY_NO_INIT': { msg:'This property has not been retrieved yet from GPG', type: 'error' - } + }, // generic 'PARAM_WRONG':{ msg: 'Invalid parameter was found', @@ -118,7 +118,11 @@ class GPGME_Error extends Error{ if (code === 'GNUPG_ERROR' && typeof(msg) === 'string'){ super(msg); } else if (err_list.hasOwnProperty(code)){ - super(err_list[code].msg); + if (msg){ + super(err_list[code].msg + "--" + msg); + } else { + super(err_list[code].msg); + } } else { super(err_list['GENERIC_ERROR'].msg); } diff --git a/lang/js/src/Helpers.js b/lang/js/src/Helpers.js index b26f40f..5064d03 100644 --- a/lang/js/src/Helpers.js +++ b/lang/js/src/Helpers.js @@ -29,7 +29,6 @@ import { GPGME_Key } from "./Key"; export function toKeyIdArray(input){ if (!input){ - gpgme_error('MSG_NO_KEYS'); return []; } if (!Array.isArray(input)){ @@ -61,7 +60,6 @@ export function toKeyIdArray(input){ } } if (result.length === 0){ - gpgme_error('MSG_NO_KEYS'); return []; } else { return result; diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index 454b191..d85c8b6 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -207,7 +207,7 @@ export class GPGME_Key { msg.setParameter('armor', true); msg.setParameter('keys', me._data.fingerprint); msg.post().then(function(result){ - me._data.armor = result.data; + me._data.armored = result.data; resolve(result.data); }, function(error){ reject(error); @@ -280,7 +280,7 @@ export class GPGME_Key { /** * Deletes the public Key from the GPG Keyring. Note that a deletion of a * secret key is not supported by the native backend. - * @returns {Boolean} Success if key was deleted, rejects with a GPG error + * @returns {Promise} Success if key was deleted, rejects with a GPG error * otherwise */ delete(){ diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index 9081cbe..c5e613e 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -18,9 +18,9 @@ * SPDX-License-Identifier: LGPL-2.1+ */ -import {createMessage} from './Message' -import {GPGME_Key, createKey} from './Key' -import { isFingerprint, toKeyIdArray } from './Helpers'; +import {createMessage} from './Message'; +import {createKey} from './Key'; +import { isFingerprint } from './Helpers'; import { gpgme_error } from './Errors'; export class GPGME_Keyring { @@ -39,10 +39,8 @@ export class GPGME_Keyring { * */ getKeys(pattern, prepare_sync){ - let me = this; return new Promise(function(resolve, reject) { - let msg; - msg = createMessage('keylist'); + let msg = createMessage('keylist'); if (pattern !== undefined){ msg.setParameter('keys', pattern); } @@ -50,25 +48,28 @@ export class GPGME_Keyring { msg.post().then(function(result){ let resultset = []; let promises = []; - // TODO check if result.key is not empty - for (let i=0; i< result.keys.length; i++){ - let k = createKey(result.keys[i].fingerprint, me); - k.setKeyData(result.keys[i]); - if (prepare_sync === true){ - promises.push(k.getArmor()); - promises.push(k.getHasSecret()); + if (result.keys.length === 0){ + resolve([]); + } else { + for (let i=0; i< result.keys.length; i++){ + let k = createKey(result.keys[i].fingerprint); + k.setKeyData(result.keys[i]); + if (prepare_sync === true){ + promises.push(k.getArmor()); + promises.push(k.getHasSecret()); + } + resultset.push(k); } - resultset.push(k); - } - if (promises.length > 0) { - Promise.all(promises).then(function (res){ + if (promises.length > 0) { + Promise.all(promises).then(function() { + resolve(resultset); + }, function(error){ + reject(error); + }); + } else { resolve(resultset); - }, function(error){ - reject(error); - }); + } } - }, function(error){ - reject(error); }); }); } @@ -80,7 +81,6 @@ export class GPGME_Keyring { * @returns {Promise} Armored Key blocks */ getKeysArmored(pattern) { - if (pattern) return new Promise(function(resolve, reject) { let msg = createMessage('export'); msg.setParameter('armor', true); @@ -92,10 +92,102 @@ export class GPGME_Keyring { }, function(error){ reject(error); }); + }); } // getDefaultKey() Big TODO - // importKeys(armoredKeys) - // generateKey --> TODO (Andre noch anfragen!) -}; + /** + * + * @param {String} armored Armored Key block of the Kex(s) to be imported into gnupg + * @param {Boolean} prepare_sync prepare the keys for synched use (see getKeys()). + * @returns {Promise>} An array of objects for the Keys considered. + * Key.key The key itself as a GPGME_Key + * Key.status String: + * 'nochange' if the Key was not changed, + * 'newkey' if the Key was imported in gpg, and did not exist previously, + * 'change' if the key existed, but details were updated. For details, + * Key.changes is available. + * Key.changes.userId: Boolean userIds changed + * Key.changes.signature: Boolean signatures changed + * Key.changes.subkey: Boolean subkeys changed + * // TODO: not yet implemented: Information about Keys that failed + * (e.g. malformed Keys, secretKeys are not accepted) + */ + importKey(armored, prepare_sync) { + if (!armored || typeof(armored) !== 'string'){ + return Promise.reject(gpgme_error('PARAM_WRONG')); + } + let me = this; + return new Promise(function(resolve, reject){ + let msg = createMessage('import'); + msg.setParameter('data', armored); + msg.post().then(function(response){ + let infos = {}; + let fprs = []; + for (var res=0; res < response.result[0].imports.length; res++) { + let result = response.result[0].imports[res]; + let status = ''; + if (result.status === 0){ + status = 'nochange'; + } else if ((result.status & 1) === 1){ + status = 'newkey'; + } else { + status = 'change'; + } + let changes = {}; + changes.userId = (result.status & 2) === 2; + changes.signature = (result.status & 4) === 4; + changes.subkey = (result.status & 8) === 8; + //16 new secret key: not implemented + + fprs.push(result.fingerprint); + infos[result.fingerprint] = { + changes: changes, + status: status + }; + } + let resultset = []; + if (prepare_sync === true){ + me.getKeys(fprs, true).then(function(result){ + for (let i=0; i < result.length; i++) { + resultset.push({ + key: result[i], + changes: infos[result[i].fingerprint].changes, + status: infos[result[i].fingerprint].status + }); + } + resolve(resultset); + }, function(error){ + reject(error); + }); + } else { + for (let i=0; i < fprs.length; i++) { + resultset.push({ + key: createKey(fprs[i]), + changes: infos[fprs[i]].changes, + status: infos[fprs[i]].status + }); + } + resolve(resultset); + } + + }, function(error){ + reject(error); + }); + + + }); + + + } + + deleteKey(fingerprint){ + if (isFingerprint(fingerprint) === true) { + let key = createKey(fingerprint); + key.delete(); + } + } + + // generateKey +} diff --git a/lang/js/unittest_inputvalues.js b/lang/js/unittest_inputvalues.js index 2a21a6a..07147ba 100644 --- a/lang/js/unittest_inputvalues.js +++ b/lang/js/unittest_inputvalues.js @@ -1,5 +1,5 @@ -import {Connection} from "./src/Connection"; -import {createKey} from "./src/Key"; +import {Connection} from './src/Connection'; +import {createKey} from './src/Key'; let conn = new Connection; @@ -23,14 +23,14 @@ export const helper_params = { valid_openpgplike: { primaryKey: { getFingerprint: function(){ return '85DE2A8BA5A5AB3A8A7BE2000B8AED24D7534BC2';} - } } -} + } +}; export const message_params = { invalid_op_action : 'dance', invalid_op_type : [234, 34, '<>'], - valid_encrypt_data: "????? ???????", + valid_encrypt_data: '????? ???????', invalid_param_test: { valid_op: 'encrypt', invalid_param_names: [22,'dance', {}], @@ -38,18 +38,89 @@ export const message_params = { invalid_values_0: [2134, 'All your passwords', createKey('12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08', conn), null] } -} +}; export const whatever_params = { four_invalid_params: ['<(((-<', '>?;==;~~', '^^', '{{{{o}}}}'], -} +}; export const key_params = { // A Key you own (= having a secret Key) in GPG. See testkey.pub/testkey.sec validKeyFingerprint: 'D41735B91236FDB882048C5A2301635EEFF0CB05', -// A Key you do not own (= having no secret Key) in GPG. See testkey2.pub + // A Key you do not own (= having no secret Key) in GPG. See testkey2.pub validFingerprintNoSecret: 'E059A1E0866D31AE131170884D9A2E13304153D1', -// A Key not in your Keyring. This is just a random hex string. + // A Key not in your Keyring. This is just a random hex string. invalidKeyFingerprint: 'CDC3A2B2860625CCBFC5AAAAAC6D1B604967FC4A', validKeyProperties: ['expired', 'disabled','invalid','can_encrypt', - 'can_sign','can_certify','can_authenticate','secret','is_qualified'] -} + 'can_sign','can_certify','can_authenticate','secret','is_qualified'] +}; +export const armoredKey = { + fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A', + key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + + '\n' + + 'mQENBFsPvK0BCACaIgoIN+3g05mrTITULK/YDTrfg4W7RdzIZBxch5CM0zdu/dby\n' + + 'esFwaJbVQIqu54CRz5xKAiWmRrQCaRvhvjY0na5r5UUIpbeQiOVrl65JtNbRmlik\n' + + 'd9Prn1kZDUOZiCPIKn+/M2ecJ92YedM7I4/BbpiaFB11cVrPFg4thepn0LB3+Whp\n' + + '9HDm4orH9rjy6IUr6yjWNIr+LYRY6/Ip2vWcMVjleEpTFznXrm83hrJ0n0INtyox\n' + + 'Nass4eDWkgo6ItxDFFLOORSmpfrToxZymSosWqgux/qG6sxHvLqlqy6Xe3ZYRFbG\n' + + '+JcA1oGdwOg/c0ndr6BYYiXTh8+uUJfEoZvzABEBAAG0HEJsYSBCbGEgPGJsYWJs\n' + + 'YUBleGFtcGxlLm9yZz6JAVQEEwEIAD4WIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUC\n' + + 'Ww+8rQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD2N5DBHmAn\n' + + 'igwIB/9K3E3Yev9taZP4KnXPhk1oMQRW1MWAsFGUr+70N85VwedpUawymW4vXi1+\n' + + 'hMeTc39QjmZ0+VqHkJttkqEN6bLcEvgmU/mOlOgKdzy6eUcasYAzgoAKUqSX1SPs\n' + + '0Imo7Tj04wnfnVwvKxaeadi0VmdqIYaW75UlrzIaltsBctyeYH8sBrvaTLscb4ON\n' + + '46OM3Yw2G9+dBF0P+4UYFHP3EYZMlzNxfwF+i2HsYcNDHlcLfjENr9GwKn5FJqpY\n' + + 'Iq3qmI37w1hVasHDxXdz1X06dpsa6Im4ACk6LXa7xIQlXxTgPAQV0sz2yB5eY+Md\n' + + 'uzEXPGW+sq0WRp3hynn7kVP6QQYvuQENBFsPvK0BCACwvBcmbnGJk8XhEBRu2QN3\n' + + 'jKgVs3CG5nE2Xh20JipZwAuGHugDLv6/jlizzz5jtj3SAHVtJB8lJW8I0cNSEIX8\n' + + 'bRYH4C7lP2DTb9CgMcGErQIyK480+HIsbsZhJSNHdjUUl6IPEEVfSQzWaufmuswe\n' + + 'e+giqHiTsaiW20ytXilwVGpjlHBaxn/bpskZ0YRasgnPqKgJD3d5kunNqWoyCpMc\n' + + 'FYgDERvPbhhceFbvFE9G/u3gbcuV15mx53dDX0ImvPcvJnDOyJS9yr7ApdOV312p\n' + + 'A1MLbxfPnbnVu+dGXn7D/VCDd5aBYVPm+5ANrk6z9lYKH9aO5wgXpLAdJvutCOL5\n' + + 'ABEBAAGJATwEGAEIACYWIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUCWw+8rQIbDAUJ\n' + + 'A8JnAAAKCRD2N5DBHmAnigMVB/484G2+3R0cAaj3V/z4gW3MRSMhcYqEMyJ/ACdo\n' + + '7y8eoreYW843JWWVDRY6/YcYYGuBBP47WO4JuP2wIlVn17XOCSgnNjmmjsIYiAzk\n' + + 'op772TB27o0VeiFX5iWcawy0EI7JCb23xpI+QP31ksL2yyRYFXCtXSUfcOrLpCY8\n' + + 'aEQMQbAGtkag1wHTo/Tf/Vip8q0ZEQ4xOKTR2/ll6+inP8kzGyzadElUnH1Q1OUX\n' + + 'd2Lj/7BpBHE2++hAjBQRgnyaONF7mpUNEuw64iBNs0Ce6Ki4RV2+EBLnFubnFNRx\n' + + 'fFJcYXcijhuf3YCdWzqYmPpU/CtF4TgDlfSsdxHxVOmnZkY3\n' + + '=qP6s\n' + + '-----END PGP PUBLIC KEY BLOCK-----\n', + keyChangedUserId: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + + '\n' + + 'mQENBFsPvK0BCACaIgoIN+3g05mrTITULK/YDTrfg4W7RdzIZBxch5CM0zdu/dby\n' + + 'esFwaJbVQIqu54CRz5xKAiWmRrQCaRvhvjY0na5r5UUIpbeQiOVrl65JtNbRmlik\n' + + 'd9Prn1kZDUOZiCPIKn+/M2ecJ92YedM7I4/BbpiaFB11cVrPFg4thepn0LB3+Whp\n' + + '9HDm4orH9rjy6IUr6yjWNIr+LYRY6/Ip2vWcMVjleEpTFznXrm83hrJ0n0INtyox\n' + + 'Nass4eDWkgo6ItxDFFLOORSmpfrToxZymSosWqgux/qG6sxHvLqlqy6Xe3ZYRFbG\n' + + '+JcA1oGdwOg/c0ndr6BYYiXTh8+uUJfEoZvzABEBAAG0HEJsYSBCbGEgPGJsYWJs\n' + + 'YUBleGFtcGxlLm9yZz6JAVQEEwEIAD4WIQR4A0lIun9dDpvbZ+T2N5DBHmAnigUC\n' + + 'Ww+8rQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD2N5DBHmAn\n' + + 'igwIB/9K3E3Yev9taZP4KnXPhk1oMQRW1MWAsFGUr+70N85VwedpUawymW4vXi1+\n' + + 'hMeTc39QjmZ0+VqHkJttkqEN6bLcEvgmU/mOlOgKdzy6eUcasYAzgoAKUqSX1SPs\n' + + '0Imo7Tj04wnfnVwvKxaeadi0VmdqIYaW75UlrzIaltsBctyeYH8sBrvaTLscb4ON\n' + + '46OM3Yw2G9+dBF0P+4UYFHP3EYZMlzNxfwF+i2HsYcNDHlcLfjENr9GwKn5FJqpY\n' + + 'Iq3qmI37w1hVasHDxXdz1X06dpsa6Im4ACk6LXa7xIQlXxTgPAQV0sz2yB5eY+Md\n' + + 'uzEXPGW+sq0WRp3hynn7kVP6QQYvtCZTb21lb25lIEVsc2UgPHNvbWVvbmVlbHNl\n' + + 'QGV4YW1wbGUub3JnPokBVAQTAQgAPhYhBHgDSUi6f10Om9tn5PY3kMEeYCeKBQJb\n' + + 'D705AhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEPY3kMEeYCeK\n' + + 'aIUH/2o+Ra+GzxgZrVexXLL+FCSmcu0cxeWfMhL8jd96c6uXIT21qQMRU2jgvnUp\n' + + 'Wdi/BeLKp5lYwywm04PFhmRVxWXLuLArCsDu+CFys+aPeybnjikPBZov6P8/cZV3\n' + + 'cd6zxFvqB9J15HjDMcl/r5v6d4CgSLKlFebrO5WKxHa6zGK9TRMQrqTu1heKHRf6\n' + + '4+Wj+MZmYnPzEQePjiBw/VkJ1Nm37Dd24gKdcN/qJFwEOqvbI5RIjB7xqoDslZk9\n' + + 'sAivBXwF0E9HKqvh4WZZeA7uaWNdGo/cQkD5rab5SdHGNPHLbzoRWScsM8WYtsME\n' + + 'dEMp5iPuG9M63+TD7losAkJ/TlS5AQ0EWw+8rQEIALC8FyZucYmTxeEQFG7ZA3eM\n' + + 'qBWzcIbmcTZeHbQmKlnAC4Ye6AMu/r+OWLPPPmO2PdIAdW0kHyUlbwjRw1IQhfxt\n' + + 'FgfgLuU/YNNv0KAxwYStAjIrjzT4cixuxmElI0d2NRSXog8QRV9JDNZq5+a6zB57\n' + + '6CKoeJOxqJbbTK1eKXBUamOUcFrGf9umyRnRhFqyCc+oqAkPd3mS6c2pajIKkxwV\n' + + 'iAMRG89uGFx4Vu8UT0b+7eBty5XXmbHnd0NfQia89y8mcM7IlL3KvsCl05XfXakD\n' + + 'UwtvF8+dudW750ZefsP9UIN3loFhU+b7kA2uTrP2Vgof1o7nCBeksB0m+60I4vkA\n' + + 'EQEAAYkBPAQYAQgAJhYhBHgDSUi6f10Om9tn5PY3kMEeYCeKBQJbD7ytAhsMBQkD\n' + + 'wmcAAAoJEPY3kMEeYCeKAxUH/jzgbb7dHRwBqPdX/PiBbcxFIyFxioQzIn8AJ2jv\n' + + 'Lx6it5hbzjclZZUNFjr9hxhga4EE/jtY7gm4/bAiVWfXtc4JKCc2OaaOwhiIDOSi\n' + + 'nvvZMHbujRV6IVfmJZxrDLQQjskJvbfGkj5A/fWSwvbLJFgVcK1dJR9w6sukJjxo\n' + + 'RAxBsAa2RqDXAdOj9N/9WKnyrRkRDjE4pNHb+WXr6Kc/yTMbLNp0SVScfVDU5Rd3\n' + + 'YuP/sGkEcTb76ECMFBGCfJo40XualQ0S7DriIE2zQJ7oqLhFXb4QEucW5ucU1HF8\n' + + 'UlxhdyKOG5/dgJ1bOpiY+lT8K0XhOAOV9Kx3EfFU6admRjc=\n' + + '=9WZ7\n' + + '-----END PGP PUBLIC KEY BLOCK-----\n' +}; \ No newline at end of file diff --git a/lang/js/unittests.js b/lang/js/unittests.js index 443aa68..d111844 100644 --- a/lang/js/unittests.js +++ b/lang/js/unittests.js @@ -17,19 +17,19 @@ * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ */ -import "./node_modules/mocha/mocha"; -import "./node_modules/chai/chai"; -import { helper_params as hp } from "./unittest_inputvalues"; -import { message_params as mp } from "./unittest_inputvalues"; -import { whatever_params as wp } from "./unittest_inputvalues"; -import { key_params as kp } from "./unittest_inputvalues"; -import { Connection } from "./src/Connection"; -import { gpgme_error } from "./src/Errors"; -import { toKeyIdArray , isFingerprint } from "./src/Helpers"; -import { GPGME_Key , createKey } from "./src/Key"; -import { GPGME_Keyring } from "./src/Keyring"; -import {GPGME_Message, createMessage} from "./src/Message"; -import { setTimeout } from "timers"; + +import './node_modules/mocha/mocha'; /*global mocha, it, describe*/ +import './node_modules/chai/chai';/*global chai*/ +import { helper_params as hp } from './unittest_inputvalues'; +import { message_params as mp } from './unittest_inputvalues'; +import { whatever_params as wp } from './unittest_inputvalues'; +import { key_params as kp } from './unittest_inputvalues'; +import { Connection } from './src/Connection'; +import { gpgme_error } from './src/Errors'; +import { toKeyIdArray , isFingerprint } from './src/Helpers'; +import { GPGME_Key , createKey } from './src/Key'; +import { GPGME_Keyring } from './src/Keyring'; +import {GPGME_Message, createMessage} from './src/Message'; mocha.setup('bdd'); var expect = chai.expect; @@ -74,12 +74,14 @@ function unittests (){ expect(test0.code).to.equal('CONN_TIMEOUT'); }); - it('Error Object returns generic code if code is not listed', function(){ - let test0 = gpgme_error(hp.invalidErrorCode); + it('Error Object returns generic code if code is not listed', + function(){ + let test0 = gpgme_error(hp.invalidErrorCode); - expect(test0).to.be.an.instanceof(Error); - expect(test0.code).to.equal('GENERIC_ERROR'); - }); + expect(test0).to.be.an.instanceof(Error); + expect(test0.code).to.equal('GENERIC_ERROR'); + } + ); it('Warnings like PARAM_IGNORED should not return errors', function(){ let test0 = gpgme_error('PARAM_IGNORED'); @@ -201,7 +203,7 @@ function unittests (){ it('Non-cached key async armored Key', function (done){ let key = createKey(kp.validKeyFingerprint); - key.get('armor', false).then(function(result){ + key.get('armored', false).then(function(result){ expect(result).to.be.a('string'); expect(result).to.include('KEY BLOCK-----'); done(); @@ -233,7 +235,7 @@ function unittests (){ expect(error).to.be.an.instanceof(Error); expect(error.code).to.equal('KEY_NOKEY'); done(); - }); + }); }); it('createKey returns error if parameters are wrong', function(){ @@ -269,14 +271,74 @@ function unittests (){ keyring.getKeys(null, true).then(function(result){ expect(result).to.be.an('array'); expect(result[0]).to.be.an.instanceof(GPGME_Key); - expect(result[0].get('armor')).to.be.a('string'); - expect(result[0].get('armor')).to.include( + expect(result[0].get('armored')).to.be.a('string'); + expect(result[0].get('armored')).to.include( '-----END PGP PUBLIC KEY BLOCK-----'); done(); }); }); + + it('Loading specific Key from Keyring, to be used synchronously', function(done){ + let keyring = new GPGME_Keyring; + keyring.getKeys(kp.validKeyFingerprint, true).then(function(result){ + expect(result).to.be.an('array'); + expect(result[0]).to.be.an.instanceof(GPGME_Key); + expect(result[0].get('armored')).to.be.a('string'); + expect(result[0].get('armored')).to.include( + '-----END PGP PUBLIC KEY BLOCK-----'); + done(); + }); + }); + + it('Querying non-existing Key from Keyring', function(done){ + let keyring = new GPGME_Keyring; + keyring.getKeys(kp.invalidKeyFingerprint, true).then(function(result){ + expect(result).to.be.an('array'); + expect(result.length).to.equal(0); + done(); + }); + }); }); + // describe('Keyring import/export', function(){ + // before(function(done) { + // let keyring = new GPGME_Keyring; + + // keyring.getKeys(ak.fingerprint, false).then(function(result){ + // if (result.length === 1){ + // result[0].delete().then(function(delete_result){ + // if (delete_result === true){ + // done(); + // } + // }); + // } else { + // done(); + // } + // }); + // }); + // it('Import Public Key', function(done){ + // keyring.importKey(ak.key).then(function(result){ + // expect(result).to.be.an('array'); + // expect(result[0].key).to.be.an.instanceof(GPGME_Key); + // expect(result[0].changed).to.equal('newkey'); + // expect(result[0].key.keyring).to.equal(ak.fingerprint); + // done(); + // }); + // }); + + // it('Update Public Key', function(done){ + // keyring.importKey(ak.key).then(function(result){ + // expect(result).to.be.an('array'); + // expect(result[0].key).to.be.an.instanceof(GPGME_Key); + // expect(result[0].changed).to.equal('change'); + // expect(result[0].changes.userId).to.be.true; + // expect(result[0].changes.subkeys).to.be.false; + // expect(result[0].key.keyring).to.equal(ak.fingerprint); + // done(); + // }); + // }); + // }); + describe('GPGME_Message', function(){ it('creating encrypt Message', function(){ @@ -330,12 +392,12 @@ function unittests (){ let test0 = createMessage(mp.invalid_param_test.valid_op); for (let i=0; i < mp.invalid_param_test.invalid_param_names.length; i++){ - let ret = test0.setParameter( - mp.invalid_param_test.invalid_param_names[i], - 'Somevalue'); + let ret = test0.setParameter( + mp.invalid_param_test.invalid_param_names[i], + 'Somevalue'); - expect(ret).to.be.an.instanceof(Error); - expect(ret.code).to.equal('PARAM_WRONG'); + expect(ret).to.be.an.instanceof(Error); + expect(ret.code).to.equal('PARAM_WRONG'); } }); @@ -343,12 +405,12 @@ function unittests (){ let test0 = createMessage(mp.invalid_param_test.valid_op); for (let j=0; j < mp.invalid_param_test.invalid_values_0.length; j++){ - let ret = test0.setParameter( - mp.invalid_param_test.validparam_name_0, - mp.invalid_param_test.invalid_values_0[j]); + let ret = test0.setParameter( + mp.invalid_param_test.validparam_name_0, + mp.invalid_param_test.invalid_values_0[j]); - expect(ret).to.be.an.instanceof(Error); - expect(ret.code).to.equal('PARAM_WRONG'); + expect(ret).to.be.an.instanceof(Error); + expect(ret.code).to.equal('PARAM_WRONG'); } }); }); ----------------------------------------------------------------------- Summary of changes: lang/js/.eslintrc.json | 29 +++++ lang/js/BrowserTestExtension/browsertest.html | 1 + .../BrowserTestExtension/tests/KeyImportExport.js | 83 ++++++++++++ .../tests/encryptDecryptTest.js | 5 +- lang/js/BrowserTestExtension/tests/inputvalues.js | 105 +++++++++++++-- lang/js/src/Connection.js | 5 +- lang/js/src/Errors.js | 8 +- lang/js/src/Helpers.js | 2 - lang/js/src/Key.js | 4 +- lang/js/src/Keyring.js | 144 +++++++++++++++++---- lang/js/unittest_inputvalues.js | 93 +++++++++++-- lang/js/unittests.js | 126 +++++++++++++----- 12 files changed, 511 insertions(+), 94 deletions(-) create mode 100644 lang/js/.eslintrc.json create mode 100644 lang/js/BrowserTestExtension/tests/KeyImportExport.js hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 12:06:21 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 12:06:21 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-137-g257661d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 257661d6ae0ca376df758c38fabab2316d10e3a9 (commit) from d2e6b3ea1d70db1039a828fb3a978a4504f8f0c5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 257661d6ae0ca376df758c38fabab2316d10e3a9 Author: Werner Koch Date: Wed Jun 6 11:50:58 2018 +0200 gpg: New command --show-keys. * g10/gpg.c (aShowKeys): New const. (opts): New command --show-keys. (main): Implement command. * g10/import.c (import_keys_internal): Don't print stats in show-only mode. (import_one): Be silent in show-only mode. -- Using --import --import-options show-only to look at a key is too cumbersome. Provide this shortcut and also remove some diagnostic cruft in this case. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index a12b5af..642805f 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -353,6 +353,14 @@ may thus be used to see what keys @command{@gpgname} might use. In particular external methods as defined by @option{--auto-key-locate} may be used to locate a key. Only public keys are listed. + at item --show-keys + at opindex show-keys +This commands takes OpenPGP keys as input and prints information about +them in the same way the command @option{--list-keys} does for +imported key. No internal state is changed. For automated processing +this command should be combined with the option + at option{--with-colons}. + @item --fingerprint @opindex fingerprint List all keys (or the specified ones) along with their @@ -2305,7 +2313,8 @@ opposite meaning. The options are: Show a listing of the key as imported right before it is stored. This can be combined with the option @option{--dry-run} to only look at keys; the option @option{show-only} is a shortcut for this - combination. Note that suffixes like '#' for "sec" and "sbb" lines + combination. The command @option{--show-keys} is another shortcut + for this. Note that suffixes like '#' for "sec" and "sbb" lines may or may not be printed. @item import-export diff --git a/g10/gpg.c b/g10/gpg.c index 70bdddf..499c005 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -150,6 +150,7 @@ enum cmd_and_opt_values aSearchKeys, aRefreshKeys, aFetchKeys, + aShowKeys, aExport, aExportSecret, aExportSecretSub, @@ -500,6 +501,7 @@ static ARGPARSE_OPTS opts[] = { N_("update all keys from a keyserver")), ARGPARSE_c (aLocateKeys, "locate-keys", "@"), ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ), + ARGPARSE_c (aShowKeys, "show-keys" , "@" ), ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ), ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ), ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ), @@ -740,6 +742,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aListKeys, "list-key", "@"), /* alias */ ARGPARSE_c (aListSigs, "list-sig", "@"), /* alias */ ARGPARSE_c (aCheckKeys, "check-sig", "@"), /* alias */ + ARGPARSE_c (aShowKeys, "show-key", "@"), /* alias */ ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"), ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"), ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"), @@ -2642,6 +2645,13 @@ main (int argc, char **argv) greeting=1; break; + case aShowKeys: + set_cmd (&cmd, pargs.r_opt); + opt.import_options |= IMPORT_SHOW; + opt.import_options |= IMPORT_DRY_RUN; + opt.import_options &= ~IMPORT_REPAIR_KEYS; + break; + case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; case aDecryptFiles: multifile=1; /* fall through */ @@ -4638,6 +4648,7 @@ main (int argc, char **argv) case aFastImport: opt.import_options |= IMPORT_FAST; /* fall through */ case aImport: + case aShowKeys: import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options, opt.key_origin, opt.key_origin_url); break; diff --git a/g10/import.c b/g10/import.c index 9fc769d..d35c720 100644 --- a/g10/import.c +++ b/g10/import.c @@ -494,7 +494,9 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, if (!stats_handle) { - import_print_stats (stats); + if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN)) + != (IMPORT_SHOW | IMPORT_DRY_RUN)) + import_print_stats (stats); import_release_stats_handle (stats); } @@ -1653,6 +1655,10 @@ import_one (ctrl_t ctrl, int any_filter = 0; KEYDB_HANDLE hd = NULL; + /* If show-only is active we don't won't any extra output. */ + if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN))) + silent = 1; + /* Get the key and print some info about it. */ node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); if (!node ) ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 11 ++++++++++- g10/gpg.c | 11 +++++++++++ g10/import.c | 8 +++++++- 3 files changed, 28 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 12:07:51 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 12:07:51 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-12-gdc87a33 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via dc87a3341f28ddac1113e90a3861d062be2610e2 (commit) from 7c004dd58f28c182c1289bfa071cd1ec8892529d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dc87a3341f28ddac1113e90a3861d062be2610e2 Author: Werner Koch Date: Wed Jun 6 11:50:58 2018 +0200 gpg: New command --show-keys. * g10/gpg.c (aShowKeys): New const. (opts): New command --show-keys. (main): Implement command. * g10/import.c (import_keys_internal): Don't print stats in show-only mode. (import_one): Be silent in show-only mode. -- Using --import --import-options show-only to look at a key is too cumbersome. Provide this shortcut and also remove some diagnostic cruft in this case. Signed-off-by: Werner Koch (cherry picked from commit 257661d6ae0ca376df758c38fabab2316d10e3a9) diff --git a/doc/gpg.texi b/doc/gpg.texi index 260b9f3..4dab238 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -353,6 +353,14 @@ may thus be used to see what keys @command{@gpgname} might use. In particular external methods as defined by @option{--auto-key-locate} may be used to locate a key. Only public keys are listed. + at item --show-keys + at opindex show-keys +This commands takes OpenPGP keys as input and prints information about +them in the same way the command @option{--list-keys} does for +imported key. No internal state is changed. For automated processing +this command should be combined with the option + at option{--with-colons}. + @item --fingerprint @opindex fingerprint List all keys (or the specified ones) along with their @@ -2295,7 +2303,8 @@ opposite meaning. The options are: Show a listing of the key as imported right before it is stored. This can be combined with the option @option{--dry-run} to only look at keys; the option @option{show-only} is a shortcut for this - combination. Note that suffixes like '#' for "sec" and "sbb" lines + combination. The command @option{--show-keys} is another shortcut + for this. Note that suffixes like '#' for "sec" and "sbb" lines may or may not be printed. @item import-export diff --git a/g10/gpg.c b/g10/gpg.c index 2c181c2..b76a039 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -149,6 +149,7 @@ enum cmd_and_opt_values aSearchKeys, aRefreshKeys, aFetchKeys, + aShowKeys, aExport, aExportSecret, aExportSecretSub, @@ -498,6 +499,7 @@ static ARGPARSE_OPTS opts[] = { N_("update all keys from a keyserver")), ARGPARSE_c (aLocateKeys, "locate-keys", "@"), ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ), + ARGPARSE_c (aShowKeys, "show-keys" , "@" ), ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ), ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ), ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ), @@ -733,6 +735,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aListKeys, "list-key", "@"), /* alias */ ARGPARSE_c (aListSigs, "list-sig", "@"), /* alias */ ARGPARSE_c (aCheckKeys, "check-sig", "@"), /* alias */ + ARGPARSE_c (aShowKeys, "show-key", "@"), /* alias */ ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"), ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"), ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"), @@ -2602,6 +2605,13 @@ main (int argc, char **argv) greeting=1; break; + case aShowKeys: + set_cmd (&cmd, pargs.r_opt); + opt.import_options |= IMPORT_SHOW; + opt.import_options |= IMPORT_DRY_RUN; + opt.import_options &= ~IMPORT_REPAIR_KEYS; + break; + case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; case aDecryptFiles: multifile=1; /* fall through */ @@ -4556,6 +4566,7 @@ main (int argc, char **argv) case aFastImport: opt.import_options |= IMPORT_FAST; /* fall through */ case aImport: + case aShowKeys: import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options, opt.key_origin, opt.key_origin_url); break; diff --git a/g10/import.c b/g10/import.c index c07f67f..10fbd42 100644 --- a/g10/import.c +++ b/g10/import.c @@ -494,7 +494,9 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, if (!stats_handle) { - import_print_stats (stats); + if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN)) + != (IMPORT_SHOW | IMPORT_DRY_RUN)) + import_print_stats (stats); import_release_stats_handle (stats); } @@ -1635,6 +1637,10 @@ import_one (ctrl_t ctrl, int any_filter = 0; KEYDB_HANDLE hd = NULL; + /* If show-only is active we don't won't any extra output. */ + if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN))) + silent = 1; + /* Get the key and print some info about it. */ node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); if (!node ) ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 11 ++++++++++- g10/gpg.c | 11 +++++++++++ g10/import.c | 8 +++++++- 3 files changed, 28 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 13:10:26 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Wed, 06 Jun 2018 13:10:26 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-54-gbfd3799 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via bfd3799d39df265882deedeee083fd5246a2f35d (commit) from 0356a667c5a8b4fdb4404cebb57475ed3f39ade9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bfd3799d39df265882deedeee083fd5246a2f35d Author: Maximilian Krambach Date: Wed Jun 6 13:05:53 2018 +0200 js: code cleanup (eslint) -- * trying to stick to eslint from now on for readability * As some attribution was lost in previous git confusions, I added my name into some of the licence headers diff --git a/lang/js/.eslintrc.json b/lang/js/.eslintrc.json index 65253cf..ad82400 100644 --- a/lang/js/.eslintrc.json +++ b/lang/js/.eslintrc.json @@ -24,6 +24,9 @@ "error", "always" ], + "no-var": [ + "warn" + ], "max-len": 1 } } \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/popup.js b/lang/js/BrowserTestExtension/popup.js index 12beb1e..794620b 100644 --- a/lang/js/BrowserTestExtension/popup.js +++ b/lang/js/BrowserTestExtension/popup.js @@ -16,27 +16,13 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ - */ -/* gpgme.js - Javascript integration for gpgme - * Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik - * - * This file is part of GPGME. - * - * GPGME is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. * - * GPGME is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . - * SPDX-License-Identifier: LGPL-2.1+ + * Author(s): + * Maximilian Krambach */ +/* global chrome */ + document.addEventListener('DOMContentLoaded', function() { chrome.tabs.create({ url: './index.html' diff --git a/lang/js/BrowserTestExtension/runbrowsertest.js b/lang/js/BrowserTestExtension/runbrowsertest.js index 39bc3fb..c46eb12 100644 --- a/lang/js/BrowserTestExtension/runbrowsertest.js +++ b/lang/js/BrowserTestExtension/runbrowsertest.js @@ -16,6 +16,11 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ +/* global mocha */ + mocha.run(); diff --git a/lang/js/BrowserTestExtension/rununittests.js b/lang/js/BrowserTestExtension/rununittests.js index f85ed8b..df31589 100644 --- a/lang/js/BrowserTestExtension/rununittests.js +++ b/lang/js/BrowserTestExtension/rununittests.js @@ -16,6 +16,12 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ + +/* global Gpgmejs_test, mocha*/ + Gpgmejs_test.unittests(); mocha.run(); diff --git a/lang/js/BrowserTestExtension/setup_testing.js b/lang/js/BrowserTestExtension/setup_testing.js index 7f70d34..52aeac5 100644 --- a/lang/js/BrowserTestExtension/setup_testing.js +++ b/lang/js/BrowserTestExtension/setup_testing.js @@ -16,7 +16,13 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ + +/* global mocha, chai */ + mocha.setup('bdd'); -var expect = chai.expect; +const expect = chai.expect; //eslint-disable-line no-unused-vars chai.config.includeStack = true; \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/tests/KeyImportExport.js b/lang/js/BrowserTestExtension/tests/KeyImportExport.js index e6eb5a3..6b29804 100644 --- a/lang/js/BrowserTestExtension/tests/KeyImportExport.js +++ b/lang/js/BrowserTestExtension/tests/KeyImportExport.js @@ -16,6 +16,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ /* global describe, it, expect, Gpgmejs, ImportablePublicKey */ diff --git a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js index e5c2f74..a84be27 100644 --- a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js +++ b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js @@ -1,4 +1,3 @@ - /* gpgme.js - Javascript integration for gpgme * Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik * @@ -17,23 +16,31 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ +/* global describe, it, expect, Gpgmejs */ +/* global inputvalues, encryptedData, bigString, bigBoringString */ + describe('Encryption and Decryption', function () { it('Successful encrypt and decrypt simple string', function (done) { let prm = Gpgmejs.init(); prm.then(function (context) { context.encrypt( inputvalues.encrypt.good.data, - inputvalues.encrypt.good.fingerprint).then(function (answer) { + inputvalues.encrypt.good.fingerprint).then( + function (answer) { expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); + expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); context.decrypt(answer.data).then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); - expect(result.data).to.equal(inputvalues.encrypt.good.data); + expect(result.data).to.equal( + inputvalues.encrypt.good.data); done(); }); }); @@ -51,7 +58,7 @@ describe('Encryption and Decryption', function () { expect(result.data).to.equal( '??u?erste ?? f?r ?oquis at h?me! ?????? ????\n'); done(); - }); + }); }); }).timeout(3000); @@ -64,7 +71,7 @@ describe('Encryption and Decryption', function () { inputvalues.encrypt.good.fingerprint).then( function (answer) { expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); + expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( @@ -79,39 +86,41 @@ describe('Encryption and Decryption', function () { }); }); }); - }).timeout(5000); + }).timeout(5000); for (let j = 0; j < inputvalues.encrypt.good.data_nonascii_32.length; j++){ - it('Roundtrip with >1MB non-ascii input meeting default chunksize (' + (j + 1) + '/' + inputvalues.encrypt.good.data_nonascii_32.length + ')', - function (done) { - let input = inputvalues.encrypt.good.data_nonascii_32[j]; - expect(input).to.have.length(32); - let prm = Gpgmejs.init(); - prm.then(function (context) { - let data = ''; - for (let i=0; i < 34 * 1024; i++){ - data += input; - } - context.encrypt(data, - inputvalues.encrypt.good.fingerprint).then( - function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); - expect(answer.data).to.include( - 'BEGIN PGP MESSAGE'); - expect(answer.data).to.include( - 'END PGP MESSAGE'); - context.decrypt(answer.data).then( - function (result) { - expect(result).to.not.be.empty; - expect(result.data).to.be.a('string'); - expect(result.data).to.equal(data); - done(); - }); - }); - }); + it('Roundtrip with >1MB non-ascii input meeting default chunksize (' + + (j + 1) + '/' + + inputvalues.encrypt.good.data_nonascii_32.length + ')', + function (done) { + let input = inputvalues.encrypt.good.data_nonascii_32[j]; + expect(input).to.have.length(32); + let prm = Gpgmejs.init(); + prm.then(function (context) { + let data = ''; + for (let i=0; i < 34 * 1024; i++){ + data += input; + } + context.encrypt(data, + inputvalues.encrypt.good.fingerprint).then( + function (answer) { + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include( + 'BEGIN PGP MESSAGE'); + expect(answer.data).to.include( + 'END PGP MESSAGE'); + context.decrypt(answer.data).then( + function (result) { + expect(result).to.not.be.empty; + expect(result.data).to.be.a('string'); + expect(result.data).to.equal(data); + done(); + }); + }); + }); }).timeout(3000); - }; + } it('Random data, as string', function (done) { let data = bigString(1000); @@ -121,7 +130,7 @@ describe('Encryption and Decryption', function () { inputvalues.encrypt.good.fingerprint).then( function (answer) { expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); + expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( @@ -143,10 +152,10 @@ describe('Encryption and Decryption', function () { let prm = Gpgmejs.init(); prm.then(function (context) { context.encrypt(b64data, - inputvalues.encrypt.good.fingerprint,).then( + inputvalues.encrypt.good.fingerprint).then( function (answer) { expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); + expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( @@ -171,7 +180,7 @@ describe('Encryption and Decryption', function () { inputvalues.encrypt.good.fingerprint, true).then( function (answer) { expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); + expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( @@ -196,7 +205,7 @@ describe('Encryption and Decryption', function () { inputvalues.encrypt.good.fingerprint).then( function (answer) { expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); + expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); diff --git a/lang/js/BrowserTestExtension/tests/encryptTest.js b/lang/js/BrowserTestExtension/tests/encryptTest.js index a16f993..2cb4e58 100644 --- a/lang/js/BrowserTestExtension/tests/encryptTest.js +++ b/lang/js/BrowserTestExtension/tests/encryptTest.js @@ -16,7 +16,14 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ + +/* global describe, it, expect, Gpgmejs */ +/* global inputvalues, fixedLengthString */ + describe('Encryption', function () { it('Successful encrypt', function (done) { let prm = Gpgmejs.init(); @@ -24,12 +31,12 @@ describe('Encryption', function () { context.encrypt( inputvalues.encrypt.good.data, inputvalues.encrypt.good.fingerprint).then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); - expect(answer.data).to.include('BEGIN PGP MESSAGE'); - expect(answer.data).to.include('END PGP MESSAGE'); - done(); - }); + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include('BEGIN PGP MESSAGE'); + expect(answer.data).to.include('END PGP MESSAGE'); + done(); + }); }); }); @@ -40,12 +47,12 @@ describe('Encryption', function () { context.encrypt( data, inputvalues.encrypt.good.fingerprint).then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); - expect(answer.data).to.include('BEGIN PGP MESSAGE'); - expect(answer.data).to.include('END PGP MESSAGE'); - done(); - }); + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include('BEGIN PGP MESSAGE'); + expect(answer.data).to.include('END PGP MESSAGE'); + done(); + }); }); }).timeout(10000); @@ -56,12 +63,12 @@ describe('Encryption', function () { context.encrypt( data, inputvalues.encrypt.good.fingerprint).then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); - expect(answer.data).to.include('BEGIN PGP MESSAGE'); - expect(answer.data).to.include('END PGP MESSAGE'); - done(); - }); + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include('BEGIN PGP MESSAGE'); + expect(answer.data).to.include('END PGP MESSAGE'); + done(); + }); }); }).timeout(20000); @@ -72,12 +79,12 @@ describe('Encryption', function () { context.encrypt( data, inputvalues.encrypt.good.fingerprint).then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); - expect(answer.data).to.include('BEGIN PGP MESSAGE'); - expect(answer.data).to.include('END PGP MESSAGE'); - done(); - }); + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include('BEGIN PGP MESSAGE'); + expect(answer.data).to.include('END PGP MESSAGE'); + done(); + }); }); }).timeout(20000); @@ -87,12 +94,12 @@ describe('Encryption', function () { context.encrypt( inputvalues.encrypt.good.data, null).then(function (answer) { - expect(answer).to.be.undefined; - }, function(error){ - expect(error).to.be.an('Error'); - expect(error.code).to.equal('MSG_INCOMPLETE'); - done(); - }); + expect(answer).to.be.undefined; + }, function(error){ + expect(error).to.be.an('Error'); + expect(error.code).to.equal('MSG_INCOMPLETE'); + done(); + }); }); }); @@ -101,12 +108,12 @@ describe('Encryption', function () { prm.then(function (context) { context.encrypt( null, inputvalues.encrypt.good.keyid).then(function (answer) { - expect(answer).to.be.undefined; - }, function (error) { - expect(error).to.be.an.instanceof(Error); - expect(error.code).to.equal('MSG_INCOMPLETE'); - done(); - }); + expect(answer).to.be.undefined; + }, function (error) { + expect(error).to.be.an.instanceof(Error); + expect(error.code).to.equal('MSG_INCOMPLETE'); + done(); + }); }); }); @@ -116,15 +123,15 @@ describe('Encryption', function () { context.encrypt( inputvalues.encrypt.good.data, inputvalues.encrypt.bad.fingerprint).then(function (answer) { - expect(answer).to.be.undefined; - }, function(error){ - expect(error).to.be.an('Error'); - expect(error.code).to.not.be.undefined; - expect(error.code).to.equal('GNUPG_ERROR'); - done(); - }); + expect(answer).to.be.undefined; + }, function(error){ + expect(error).to.be.an('Error'); + expect(error.code).to.not.be.undefined; + expect(error.code).to.equal('GNUPG_ERROR'); + done(); + }); }); - }).timeout(5000);; + }).timeout(5000); it('Overly large message ( > 65MB) is rejected', function (done) { let prm = Gpgmejs.init(); @@ -132,15 +139,15 @@ describe('Encryption', function () { context.encrypt( fixedLengthString(65), inputvalues.encrypt.good.fingerprint).then(function (answer) { - expect(answer).to.be.undefined; - }, function(error){ - expect(error).to.be.an.instanceof(Error); - // expect(error.code).to.equal('GNUPG_ERROR'); - // TODO: there is a 64 MB hard limit at least in chrome at: - // chromium//extensions/renderer/messaging_util.cc: - // kMaxMessageLength - done(); - }); + expect(answer).to.be.undefined; + }, function(error){ + expect(error).to.be.an.instanceof(Error); + // expect(error.code).to.equal('GNUPG_ERROR'); + // TODO: there is a 64 MB hard limit at least in chrome at: + // chromium//extensions/renderer/messaging_util.cc: + // kMaxMessageLength + done(); + }); }); }).timeout(8000); diff --git a/lang/js/BrowserTestExtension/tests/inputvalues.js b/lang/js/BrowserTestExtension/tests/inputvalues.js index 9dc1332..024aad2 100644 --- a/lang/js/BrowserTestExtension/tests/inputvalues.js +++ b/lang/js/BrowserTestExtension/tests/inputvalues.js @@ -16,9 +16,12 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ -var inputvalues = {// eslint-disable-line no-unused-vars +const inputvalues = {// eslint-disable-line no-unused-vars encrypt: { good:{ data : 'Hello World.', @@ -131,7 +134,7 @@ function slightlyLessBoringString(megabytes, set){ } // Data encrypted with testKey -var encryptedData =// eslint-disable-line no-unused-vars +const encryptedData =// eslint-disable-line no-unused-vars '-----BEGIN PGP MESSAGE-----\n' + '\n' + 'hQEMA6B8jfIUScGEAQgAlANd3uyhmhYLzVcfz4LEqA8tgUC3n719YH0iuKEzG/dv\n' + @@ -146,7 +149,7 @@ var encryptedData =// eslint-disable-line no-unused-vars '=zap6\n' + '-----END PGP MESSAGE-----\n'; -var ImportablePublicKey = {// eslint-disable-line no-unused-vars +const ImportablePublicKey = {// eslint-disable-line no-unused-vars fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A', key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + '\n' + diff --git a/lang/js/BrowserTestExtension/tests/longRunningTests.js b/lang/js/BrowserTestExtension/tests/longRunningTests.js index 5c588f2..eefe126 100644 --- a/lang/js/BrowserTestExtension/tests/longRunningTests.js +++ b/lang/js/BrowserTestExtension/tests/longRunningTests.js @@ -1,39 +1,78 @@ +/* gpgme.js - Javascript integration for gpgme + * Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach + */ +/* global describe, it, expect, Gpgmejs */ +/* global bigString, inputvalues */ + describe('Long running Encryption/Decryption', function () { for (let i=0; i < 100; i++) { - it('Successful encrypt/decrypt completely random data ' + (i+1) + '/100', function (done) { + it('Successful encrypt/decrypt completely random data ' + + (i+1) + '/100', function (done) { let prm = Gpgmejs.init(); let data = bigString(2*1024*1024); - prm.then(function (context) { - context.encrypt(data, - inputvalues.encrypt.good.fingerprint).then( - function (answer){ - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a("string"); - expect(answer.data).to.include( - 'BEGIN PGP MESSAGE'); - expect(answer.data).to.include( - 'END PGP MESSAGE'); - context.decrypt(answer.data).then( - function(result){ - expect(result).to.not.be.empty; - expect(result.data).to.be.a('string'); - if (result.data.length !== data.length) { - console.log('diff: ' + (result.data.length - data.length)); - for (let i=0; i < result.data.length; i++){ - if (result.data[i] !== data[i]){ - console.log('position: ' + i); - console.log('result : '+ result.data.charCodeAt(i) + result.data[i-2] + result.data[i-1] + result.data[i] + result.data[i+1] + result.data[i+2]); - console.log('original: ' + data.charCodeAt(i) + data[i-2] + data[i-1] + data[i] + data[i+1] + data[i+2]); - break; - } - } + prm.then(function (context) { + context.encrypt(data, + inputvalues.encrypt.good.fingerprint).then( + function (answer){ + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include( + 'BEGIN PGP MESSAGE'); + expect(answer.data).to.include( + 'END PGP MESSAGE'); + context.decrypt(answer.data).then( + function(result){ + expect(result).to.not.be.empty; + expect(result.data).to.be.a('string'); + if (result.data.length !== data.length) { + // console.log('diff: ' + + // (result.data.length - data.length)); + for (let i=0; i < result.data.length; i++){ + if (result.data[i] !== data[i]){ + // console.log('position: ' + i); + // console.log('result : ' + + // result.data.charCodeAt(i) + + // result.data[i-2] + + // result.data[i-1] + + // result.data[i] + + // result.data[i+1] + + // result.data[i+2]); + // console.log('original: ' + + // data.charCodeAt(i) + + // data[i-2] + + // data[i-1] + + // data[i] + + // data[i+1] + + // data[i+2]); + break; } - expect(result.data).to.equal(data); - done(); - }); - }); - }); + } + } + expect(result.data).to.equal(data); + done(); + }); + }); + }); }).timeout(8000); - }; + } }); diff --git a/lang/js/BrowserTestExtension/tests/signTest.js b/lang/js/BrowserTestExtension/tests/signTest.js index 2e5edb3..ffd2d5d 100644 --- a/lang/js/BrowserTestExtension/tests/signTest.js +++ b/lang/js/BrowserTestExtension/tests/signTest.js @@ -16,7 +16,14 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ + +/* global describe, it, expect, Gpgmejs */ +/* global bigString, inputvalues */ + describe('Signing', function () { it('Sign a message', function (done) { let prm = Gpgmejs.init(); @@ -25,12 +32,12 @@ describe('Signing', function () { context.sign( data, inputvalues.encrypt.good.fingerprint).then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a('string'); - expect(answer.data).to.include('BEGIN PGP SIGNATURE'); - expect(answer.data).to.include('END PGP SIGNATURE'); - expect(answer.data).to.include(data); - done(); + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include('BEGIN PGP SIGNATURE'); + expect(answer.data).to.include('END PGP SIGNATURE'); + expect(answer.data).to.include(data); + done(); }); }); }); @@ -43,12 +50,12 @@ describe('Signing', function () { inputvalues.encrypt.good.fingerprint, 'detached' ).then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a('string'); - expect(answer.data).to.include(data); - expect(answer.signature).to.be.a('string'); - expect(answer.signature).to.be.a('string'); - done(); + expect(answer).to.not.be.empty; + expect(answer.data).to.be.a('string'); + expect(answer.data).to.include(data); + expect(answer.signature).to.be.a('string'); + expect(answer.signature).to.be.a('string'); + done(); }); }); }); diff --git a/lang/js/BrowserTestExtension/tests/startup.js b/lang/js/BrowserTestExtension/tests/startup.js index 7d13ea4..d434b6d 100644 --- a/lang/js/BrowserTestExtension/tests/startup.js +++ b/lang/js/BrowserTestExtension/tests/startup.js @@ -16,25 +16,31 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ - describe('GPGME context', function(){ +/* global describe, it, expect, Gpgmejs */ +/* global inputvalues */ + +describe('GPGME context', function(){ it('Starting a GpgME instance', function(done){ let prm = Gpgmejs.init(); prm.then( - function(context){ - expect(context).to.be.an('object'); - expect(context.encrypt).to.be.a('function'); - expect(context.decrypt).to.be.a('function'); - done(); - }); + function(context){ + expect(context).to.be.an('object'); + expect(context.encrypt).to.be.a('function'); + expect(context.decrypt).to.be.a('function'); + done(); + }); }); }); describe('GPGME does not start with invalid parameters', function(){ for (let i=0; i < inputvalues.init.invalid_startups.length; i++){ it('Parameter '+ i, function(done){ - let prm = Gpgmejs.init(inputvalues.init.invalid_startups[i]); + let prm = Gpgmejs.init(inputvalues.init.invalid_startups[i]); prm.then(function(context){ expect(context).to.be.undefined; done(); @@ -43,6 +49,6 @@ describe('GPGME does not start with invalid parameters', function(){ expect(error.code).to.equal('PARAM_WRONG'); done(); }); - }) + }); } }); \ No newline at end of file diff --git a/lang/js/CHECKLIST b/lang/js/CHECKLIST index 278f39d..fe26018 100644 --- a/lang/js/CHECKLIST +++ b/lang/js/CHECKLIST @@ -6,20 +6,25 @@ receiving an answer [*] nativeConnection successfull on Windows, macOS, Linux [X] nativeConnection with delayed, multipart (> 1MB) answer - [*] Message handling (encrypt, decrypt verify, sign) + [x] Message handling (encrypt, decrypt verify, sign) [x] encrypt, decrypt - [ ] verify - [ ] sign + [x] verify + [x] sign [*] Key handling (import/export, modifying, status queries) + [x] Import (not importing secret) + [x] Export (not exporting secret) + [x] status queries + [ ] key generation + [ ] modification [*] Configuration handling [ ] check for completeness Communication with other implementations - - [ ] option to export SECRET Key into localstore used by e.g. mailvelope - + [-] option to export SECRET Key into localstore used by e.g. mailvelope? + current discussion states that this won't be possible due to security + concerns Management: [*] Define the gpgme interface [x] check Permissions (e.g. csp) for the different envs - [X] agree on license + [x] agree on license [*] tests diff --git a/lang/js/DemoExtension/entry.js b/lang/js/DemoExtension/entry.js index 6258342..77b96f9 100644 --- a/lang/js/DemoExtension/entry.js +++ b/lang/js/DemoExtension/entry.js @@ -17,7 +17,12 @@ * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ * + * Author(s): + * Maximilian Krambach */ + +/* global chrome */ + document.addEventListener('DOMContentLoaded', function() { chrome.tabs.create({ url: './mainui.html' diff --git a/lang/js/DemoExtension/maindemo.js b/lang/js/DemoExtension/maindemo.js index b2cb4c2..5cde1ce 100644 --- a/lang/js/DemoExtension/maindemo.js +++ b/lang/js/DemoExtension/maindemo.js @@ -17,39 +17,41 @@ * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ * + * Author(s): + * Maximilian Krambach */ +/* global document, Gpgmejs */ + document.addEventListener('DOMContentLoaded', function() { Gpgmejs.init().then(function(gpgmejs){ - document.getElementById("buttonencrypt").addEventListener("click", + document.getElementById('buttonencrypt').addEventListener('click', function(){ let data = document.getElementById('cleartext').value; let keyId = document.getElementById('pubkey').value; gpgmejs.encrypt(data, keyId).then( function(answer){ - console.log(answer); if (answer.data){ - console.log(answer.data); - document.getElementById('answer').value = answer.data; + document.getElementById( + 'answer').value = answer.data; } }, function(errormsg){ alert( errormsg.code + ' ' + errormsg.msg); - }); + }); }); - document.getElementById("buttondecrypt").addEventListener("click", - function(){ - let data = document.getElementById("ciphertext").value; - gpgmejs.decrypt(data).then( - function(answer){ - console.log(answer); - if (answer.data){ - document.getElementById('answer').value = answer.data; - } - }, function(errormsg){ - alert( errormsg.code + ' ' + errormsg.msg); + document.getElementById('buttondecrypt').addEventListener('click', + function(){ + let data = document.getElementById('ciphertext').value; + gpgmejs.decrypt(data).then( + function(answer){ + if (answer.data){ + document.getElementById( + 'answer').value = answer.data; + } + }, function(errormsg){ + alert( errormsg.code + ' ' + errormsg.msg); + }); }); - }); - }, - function(error){console.log(error)}); + }); }); diff --git a/lang/js/package.json b/lang/js/package.json index be52a55..acf8911 100644 --- a/lang/js/package.json +++ b/lang/js/package.json @@ -1,7 +1,7 @@ { "name": "gpgmejs", - "version": "0.0.1", - "description": "javascript part of a nativeMessaging gnupg integration", + "version": "0.0.1-dev", + "description": "Javascript part of the GPGME nativeMessaging integration", "main": "src/index.js", "private": true, "keywords": [], diff --git a/lang/js/src/Config.js b/lang/js/src/Config.js index e85bbb8..8a3ef49 100644 --- a/lang/js/src/Config.js +++ b/lang/js/src/Config.js @@ -16,6 +16,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ export const availableConf = { diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js index 8c4cba7..e9c0b21 100644 --- a/lang/js/src/Connection.js +++ b/lang/js/src/Connection.js @@ -16,16 +16,16 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ -/** - * A connection port will be opened for each communication between gpgmejs and - * gnupg. It should be alive as long as there are additional messages to be - * expected. - */ -import { permittedOperations } from './permittedOperations' -import { gpgme_error } from "./Errors" -import { GPGME_Message, createMessage } from "./Message"; +/* global chrome */ + +import { permittedOperations } from './permittedOperations'; +import { gpgme_error } from './Errors'; +import { GPGME_Message, createMessage } from './Message'; /** * A Connection handles the nativeMessaging interaction. @@ -55,7 +55,7 @@ export class Connection{ return this.post(createMessage('version')); } else { let me = this; - return new Promise(function(resolve,reject) { + return new Promise(function(resolve) { Promise.race([ me.post(createMessage('version')), new Promise(function(resolve, reject){ @@ -63,9 +63,9 @@ export class Connection{ reject(gpgme_error('CONN_TIMEOUT')); }, 500); }) - ]).then(function(result){ - resolve(true); - }, function(reject){ + ]).then(function(){ // success + resolve(true); + }, function(){ // failure resolve(false); }); }); @@ -98,12 +98,10 @@ export class Connection{ * information. */ post(message){ - if (!this._connection) { - - } - if (!message || !message instanceof GPGME_Message){ + if (!message || !(message instanceof GPGME_Message)){ this.disconnect(); - return Promise.reject(gpgme_error('PARAM_WRONG', 'Connection.post')); + return Promise.reject(gpgme_error( + 'PARAM_WRONG', 'Connection.post')); } if (message.isComplete !== true){ this.disconnect(); @@ -114,10 +112,10 @@ export class Connection{ let answer = new Answer(message); let listener = function(msg) { if (!msg){ - me._connection.onMessage.removeListener(listener) + me._connection.onMessage.removeListener(listener); me._connection.disconnect(); reject(gpgme_error('CONN_EMPTY_GPG_ANSWER')); - } else if (msg.type === "error"){ + } else if (msg.type === 'error'){ me._connection.onMessage.removeListener(listener); me._connection.disconnect(); reject(gpgme_error('GNUPG_ERROR', msg.msg)); @@ -130,7 +128,7 @@ export class Connection{ } else if (msg.more === true){ me._connection.postMessage({'op': 'getmore'}); } else { - me._connection.onMessage.removeListener(listener) + me._connection.onMessage.removeListener(listener); me._connection.disconnect(); resolve(answer.message); } @@ -148,9 +146,9 @@ export class Connection{ reject(gpgme_error('CONN_TIMEOUT')); }, 5000); }]).then(function(result){ - return result; + return result; }, function(reject){ - if(!reject instanceof Error) { + if(!(reject instanceof Error)) { me._connection.disconnect(); return gpgme_error('GNUPG_ERROR', reject); } else { @@ -159,13 +157,14 @@ export class Connection{ }); } }); - } -}; + } +} /** * A class for answer objects, checking and processing the return messages of * the nativeMessaging communication. - * @param {String} operation The operation, to look up validity of returning messages + * @param {String} operation The operation, to look up validity of returning + * messages */ class Answer{ @@ -191,49 +190,49 @@ class Answer{ for (let i= 0; i < messageKeys.length; i++){ let key = messageKeys[i]; switch (key) { - case 'type': - if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){ - return gpgme_error('CONN_UNEXPECTED_ANSWER'); + case 'type': + if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){ + return gpgme_error('CONN_UNEXPECTED_ANSWER'); + } + break; + case 'more': + break; + default: + //data should be concatenated + if (poa.data.indexOf(key) >= 0){ + if (!this._response.hasOwnProperty(key)){ + this._response[key] = ''; } - break; - case 'more': - break; - default: - //data should be concatenated - if (poa.data.indexOf(key) >= 0){ - if (!this._response.hasOwnProperty(key)){ - this._response[key] = ''; - } - this._response[key] += msg[key]; + this._response[key] += msg[key]; + } + //params should not change through the message + else if (poa.params.indexOf(key) >= 0){ + if (!this._response.hasOwnProperty(key)){ + this._response[key] = msg[key]; } - //params should not change through the message - else if (poa.params.indexOf(key) >= 0){ - if (!this._response.hasOwnProperty(key)){ - this._response[key] = msg[key]; - } - else if (this._response[key] !== msg[key]){ - return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]); - } + else if (this._response[key] !== msg[key]){ + return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]); + } + } + //infos may be json objects etc. Not yet defined. + // Pushing them into arrays for now + else if (poa.infos.indexOf(key) >= 0){ + if (!this._response.hasOwnProperty(key)){ + this._response[key] = []; } - //infos may be json objects etc. Not yet defined. - // Pushing them into arrays for now - else if (poa.infos.indexOf(key) >= 0){ - if (!this._response.hasOwnProperty(key)){ - this._response[key] = []; - } - if (Array.isArray(msg[key])) { - for (let i=0; i< msg[key].length; i++) { - this._response[key].push(msg[key][i]); - } - } else { - this._response[key].push(msg[key]); + if (Array.isArray(msg[key])) { + for (let i=0; i< msg[key].length; i++) { + this._response[key].push(msg[key][i]); } + } else { + this._response[key].push(msg[key]); } - else { - return gpgme_error('CONN_UNEXPECTED_ANSWER'); - } - break; + } + else { + return gpgme_error('CONN_UNEXPECTED_ANSWER'); + } + break; } } return true; @@ -256,10 +255,11 @@ class Answer{ msg[keys[i]] = this._response[keys[i]]; } else { msg[keys[i]] = decodeURIComponent( - atob(this._response[keys[i]]).split('').map(function(c) { - return '%' + + atob(this._response[keys[i]]).split('').map( + function(c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }).join('')); + }).join('')); } } else { msg[keys[i]] = this._response[keys[i]]; diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js index 2f2bfd5..dabf6a5 100644 --- a/lang/js/src/Errors.js +++ b/lang/js/src/Errors.js @@ -16,6 +16,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ const err_list = { @@ -102,6 +105,7 @@ export function gpgme_error(code = 'GENERIC_ERROR', info){ return new GPGME_Error(code); } if (err_list[code].type === 'warning'){ + // eslint-disable-next-line no-console console.warn(code + ': ' + err_list[code].msg); } return null; @@ -119,7 +123,7 @@ class GPGME_Error extends Error{ super(msg); } else if (err_list.hasOwnProperty(code)){ if (msg){ - super(err_list[code].msg + "--" + msg); + super(err_list[code].msg + '--' + msg); } else { super(err_list[code].msg); } diff --git a/lang/js/src/Helpers.js b/lang/js/src/Helpers.js index 5064d03..b01fbc3 100644 --- a/lang/js/src/Helpers.js +++ b/lang/js/src/Helpers.js @@ -16,14 +16,18 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ -import { gpgme_error } from "./Errors"; -import { GPGME_Key } from "./Key"; + +import { gpgme_error } from './Errors'; +import { GPGME_Key } from './Key'; /** * Tries to return an array of fingerprints, either from input fingerprints or - * from Key objects - * @param {Key |Array| GPGME_Key | Array|String|Array} input + * from Key objects (openpgp Keys or GPGME_Keys are both expected) + * @param {Object |Array| String|Array} input * @returns {Array} Array of fingerprints. */ @@ -48,7 +52,7 @@ export function toKeyIdArray(input){ fpr = input[i].fingerprint; } else if (input[i].hasOwnProperty('primaryKey') && input[i].primaryKey.hasOwnProperty('getFingerprint')){ - fpr = input[i].primaryKey.getFingerprint(); + fpr = input[i].primaryKey.getFingerprint(); } if (isFingerprint(fpr) === true){ result.push(fpr); @@ -64,7 +68,7 @@ export function toKeyIdArray(input){ } else { return result; } -}; +} /** * check if values are valid hexadecimal values of a specified length @@ -72,7 +76,7 @@ export function toKeyIdArray(input){ * @param {int} len the expected length of the value */ function hextest(key, len){ - if (!key || typeof(key) !== "string"){ + if (!key || typeof(key) !== 'string'){ return false; } if (key.length !== len){ @@ -80,23 +84,18 @@ function hextest(key, len){ } let regexp= /^[0-9a-fA-F]*$/i; return regexp.test(key); -}; +} /** * check if the input is a valid Hex string with a length of 40 */ export function isFingerprint(string){ return hextest(string, 40); -}; +} /** * check if the input is a valid Hex string with a length of 16 */ export function isLongId(string){ return hextest(string, 16); -}; - -// TODO still not needed anywhere -function isShortId(string){ - return hextest(string, 8); -}; +} diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index d85c8b6..8c8726a 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -16,20 +16,14 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ - */ - -/** - * The key class allows to query the information defined in gpgme Key Objects - * (see https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html) - * - * This is a stub, as the gpgme-json side is not yet implemented * + * Author(s): + * Maximilian Krambach */ -import { isFingerprint, isLongId } from './Helpers' -import { gpgme_error } from './Errors' +import { isFingerprint, isLongId } from './Helpers'; +import { gpgme_error } from './Errors'; import { createMessage } from './Message'; -import { permittedOperations } from './permittedOperations'; /** * Validates the fingerprint. @@ -44,6 +38,11 @@ export function createKey(fingerprint){ /** * Representing the Keys as stored in GPG + * It allows to query almost all information defined in gpgme Key Objects + * Refer to validKeyProperties for available information, and the gpgme + * documentation on their meaning + * (https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html) + * */ export class GPGME_Key { @@ -102,22 +101,22 @@ export class GPGME_Key { return gpgme_error('KEY_INVALID'); } switch (dataKeys[i]){ - case 'subkeys': - this._data.subkeys = []; - for (let i=0; i< data.subkeys.length; i++) { - this._data.subkeys.push( - new GPGME_Subkey(data.subkeys[i])); - } - break; - case 'userids': - this._data.userids = []; - for (let i=0; i< data.userids.length; i++) { - this._data.userids.push( - new GPGME_UserId(data.userids[i])); - } - break; - default: - this._data[dataKeys[i]] = data[dataKeys[i]]; + case 'subkeys': + this._data.subkeys = []; + for (let i=0; i< data.subkeys.length; i++) { + this._data.subkeys.push( + new GPGME_Subkey(data.subkeys[i])); + } + break; + case 'userids': + this._data.userids = []; + for (let i=0; i< data.userids.length; i++) { + this._data.userids.push( + new GPGME_UserId(data.userids[i])); + } + break; + default: + this._data[dataKeys[i]] = data[dataKeys[i]]; } } return this; @@ -162,11 +161,6 @@ export class GPGME_Key { } } - get armored () { - return this.get('armored'); - //TODO exception if empty - } - /** * Reloads the Key from gnupg */ @@ -188,7 +182,7 @@ export class GPGME_Key { } }, function (error) { reject(gpgme_error('GNUPG_ERROR'), error); - }) + }); }); } @@ -197,7 +191,7 @@ export class GPGME_Key { * from gpg. * @returns {Promise} */ - getArmor(){ + getArmor(){ let me = this; return new Promise(function(resolve, reject) { if (!me._data.fingerprint){ @@ -249,15 +243,16 @@ export class GPGME_Key { } } } else { - reject(gpgme_error('CONN_UNEXPECTED_ANSWER')) + reject(gpgme_error('CONN_UNEXPECTED_ANSWER')); } }, function(error){ - }) + reject(error); + }); }); } /** - * Convenience function to be directly used as properties of the Key + * Convenience functions to be directly used as properties of the Key * Notice that these rely on cached info and may be outdated. Use the async * get(property, false) if you need the most current info */ @@ -280,8 +275,8 @@ export class GPGME_Key { /** * Deletes the public Key from the GPG Keyring. Note that a deletion of a * secret key is not supported by the native backend. - * @returns {Promise} Success if key was deleted, rejects with a GPG error - * otherwise + * @returns {Promise} Success if key was deleted, rejects with a + * GPG error otherwise */ delete(){ let me = this; @@ -295,7 +290,7 @@ export class GPGME_Key { resolve(result.success); }, function(error){ reject(error); - }) + }); }); } } @@ -378,37 +373,37 @@ const validUserIdProperties = { }, 'uid': function(value){ if (typeof(value) === 'string' || value === ''){ - return true;; + return true; } return false; }, 'validity': function(value){ if (typeof(value) === 'string'){ - return true;; + return true; } return false; }, 'name': function(value){ if (typeof(value) === 'string' || value === ''){ - return true;; + return true; } return false; }, 'email': function(value){ if (typeof(value) === 'string' || value === ''){ - return true;; + return true; } return false; }, 'address': function(value){ if (typeof(value) === 'string' || value === ''){ - return true;; + return true; } return false; }, 'comment': function(value){ if (typeof(value) === 'string' || value === ''){ - return true;; + return true; } return false; }, @@ -449,8 +444,8 @@ const validSubKeyProperties = { return typeof(value) === 'boolean'; }, 'pubkey_algo_name': function(value){ - return typeof(value) === 'string'; - // TODO: check against list of known?[''] + return typeof(value) === 'string'; + // TODO: check against list of known?[''] }, 'pubkey_algo_string': function(value){ return typeof(value) === 'string'; @@ -471,7 +466,7 @@ const validSubKeyProperties = { 'expires': function(value){ return (Number.isInteger(value) && value > 0); } -} +}; const validKeyProperties = { //TODO better validation? 'fingerprint': function(value){ @@ -546,4 +541,4 @@ const validKeyProperties = { return typeof(value) === 'boolean'; } -} +}; diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index c5e613e..7158587 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -16,8 +16,12 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ + import {createMessage} from './Message'; import {createKey} from './Key'; import { isFingerprint } from './Helpers'; @@ -99,18 +103,22 @@ export class GPGME_Keyring { /** * - * @param {String} armored Armored Key block of the Kex(s) to be imported into gnupg - * @param {Boolean} prepare_sync prepare the keys for synched use (see getKeys()). - * @returns {Promise>} An array of objects for the Keys considered. - * Key.key The key itself as a GPGME_Key - * Key.status String: + * @param {String} armored Armored Key block of the Kex(s) to be imported + * into gnupg + * @param {Boolean} prepare_sync prepare the keys for synched use + * (see getKeys()). + * @returns {Promise>} An array of objects for the Keys + * considered: + * Key.key : The key itself as a GPGME_Key + * Key.status : * 'nochange' if the Key was not changed, - * 'newkey' if the Key was imported in gpg, and did not exist previously, - * 'change' if the key existed, but details were updated. For details, - * Key.changes is available. - * Key.changes.userId: Boolean userIds changed - * Key.changes.signature: Boolean signatures changed - * Key.changes.subkey: Boolean subkeys changed + * 'newkey' if the Key was imported in gpg, and did not exist + * previously, + * 'change' if the key existed, but details were updated. For + * details, Key.changes is available. + * Key.changes.userId: userIds changed + * Key.changes.signature: signatures changed + * Key.changes.subkey: subkeys changed * // TODO: not yet implemented: Information about Keys that failed * (e.g. malformed Keys, secretKeys are not accepted) */ @@ -125,7 +133,7 @@ export class GPGME_Keyring { msg.post().then(function(response){ let infos = {}; let fprs = []; - for (var res=0; res < response.result[0].imports.length; res++) { + for (let res=0; res < response.result[0].imports.length; res++){ let result = response.result[0].imports[res]; let status = ''; if (result.status === 0){ diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js index 5664f72..0ddda6c 100644 --- a/lang/js/src/Message.js +++ b/lang/js/src/Message.js @@ -16,9 +16,13 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ -import { permittedOperations } from './permittedOperations' -import { gpgme_error } from './Errors' + +import { permittedOperations } from './permittedOperations'; +import { gpgme_error } from './Errors'; import { Connection } from './Connection'; export function createMessage(operation){ @@ -46,7 +50,7 @@ export class GPGME_Message { } set operation (op){ - if (typeof(op) === "string"){ + if (typeof(op) === 'string'){ if (!this._msg){ this._msg = {}; } @@ -67,10 +71,10 @@ export class GPGME_Message { } get expected() { - if (this._expected === "base64"){ - return this._expected; - } - return "string"; + if (this._expected === 'base64'){ + return this._expected; + } + return 'string'; } /** @@ -98,52 +102,50 @@ export class GPGME_Message { } let checktype = function(val){ switch(typeof(val)){ - case 'string': - if (poparam.allowed.indexOf(typeof(val)) >= 0 + case 'string': + if (poparam.allowed.indexOf(typeof(val)) >= 0 && val.length > 0) { - return true; - } - return gpgme_error('PARAM_WRONG'); - break; - case 'number': - if ( - poparam.allowed.indexOf('number') >= 0 + return true; + } + return gpgme_error('PARAM_WRONG'); + case 'number': + if ( + poparam.allowed.indexOf('number') >= 0 && isNaN(value) === false){ - return true; + return true; + } + return gpgme_error('PARAM_WRONG'); + + case 'boolean': + if (poparam.allowed.indexOf('boolean') >= 0){ + return true; + } + return gpgme_error('PARAM_WRONG'); + case 'object': + if (Array.isArray(val)){ + if (poparam.array_allowed !== true){ + return gpgme_error('PARAM_WRONG'); } - return gpgme_error('PARAM_WRONG'); - break; - case 'boolean': - if (poparam.allowed.indexOf('boolean') >= 0){ + for (let i=0; i < val.length; i++){ + let res = checktype(val[i]); + if (res !== true){ + return res; + } + } + if (val.length > 0) { return true; } - return gpgme_error('PARAM_WRONG'); - break; - case 'object': - if (Array.isArray(val)){ - if (poparam.array_allowed !== true){ - return gpgme_error('PARAM_WRONG'); - } - for (let i=0; i < val.length; i++){ - let res = checktype(val[i]); - if (res !== true){ - return res; - } - } - if (val.length > 0) { - return true; - } - } else if (val instanceof Uint8Array){ - if (poparam.allowed.indexOf('Uint8Array') >= 0){ - return true; - } - return gpgme_error('PARAM_WRONG'); - } else { - return gpgme_error('PARAM_WRONG'); + } else if (val instanceof Uint8Array){ + if (poparam.allowed.indexOf('Uint8Array') >= 0){ + return true; } - break; - default: return gpgme_error('PARAM_WRONG'); + } else { + return gpgme_error('PARAM_WRONG'); + } + break; + default: + return gpgme_error('PARAM_WRONG'); } }; let typechecked = checktype(value); @@ -173,7 +175,6 @@ export class GPGME_Message { let msg_params = Object.keys(this._msg); for (let i=0; i < reqParams.length; i++){ if (msg_params.indexOf(reqParams[i]) < 0){ - console.log(reqParams[i] + ' missing'); return false; } } diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index 39f6a2f..cbad902 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -16,12 +16,16 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ -import {GPGME_Message, createMessage} from './Message' -import {toKeyIdArray} from "./Helpers" -import { gpgme_error } from "./Errors" -import { GPGME_Keyring } from "./Keyring"; + +import {GPGME_Message, createMessage} from './Message'; +import {toKeyIdArray} from './Helpers'; +import { gpgme_error } from './Errors'; +import { GPGME_Keyring } from './Keyring'; export class GpgME { /** @@ -32,7 +36,7 @@ export class GpgME { this._config = config; } - set Keyring(keyring){ + set Keyring(keyring){ if (keyring && keyring instanceof GPGME_Keyring){ this._Keyring = keyring; } @@ -47,13 +51,19 @@ export class GpgME { /** * Encrypt (and optionally sign) a Message - * @param {String|Object} data text/data to be encrypted as String. Also accepts Objects with a getText method - * @param {GPGME_Key|String|Array|Array} publicKeys Keys used to encrypt the message - * @param {GPGME_Key|String|Array|Array} secretKeys (optional) Keys used to sign the message - * @param {Boolean} base64 (optional) The data is already considered to be in base64 encoding + * @param {String|Object} data text/data to be encrypted as String. Also + * accepts Objects with a getText method + * @param {GPGME_Key|String|Array|Array} publicKeys + * Keys used to encrypt the message + * @param {GPGME_Key|String|Array|Array} secretKeys + * (optional) Keys used to sign the message + * @param {Boolean} base64 (optional) The data is already considered to be + * in base64 encoding * @param {Boolean} armor (optional) Request the output as armored block - * @param {Boolean} wildcard (optional) If true, recipient information will not be added to the message - * @param {Object} additional use additional gpg options (refer to src/permittedOperations) + * @param {Boolean} wildcard (optional) If true, recipient information will + * not be added to the message + * @param {Object} additional use additional gpg options + * (refer to src/permittedOperations) * @returns {Promise} Encrypted message: * data: The encrypted message * base64: Boolean indicating whether data is base64 encoded. @@ -64,7 +74,7 @@ export class GpgME { ){ let msg = createMessage('encrypt'); if (msg instanceof Error){ - return Promise.reject(msg) + return Promise.reject(msg); } msg.setParameter('armor', armor); msg.setParameter('always-trust', true); @@ -80,7 +90,7 @@ export class GpgME { putData(msg, data); if (wildcard === true){ msg.setParameter('throw-keyids', true); - }; + } if (additional){ let additional_Keys = Object.keys(additional); for (let k = 0; k < additional_Keys.length; k++) { @@ -97,14 +107,16 @@ export class GpgME { /** * Decrypt a Message - * @param {String|Object} data text/data to be decrypted. Accepts Strings and Objects with a getText method - * @param {Boolean} base64 (optional) Response is expected to be base64 encoded + * @param {String|Object} data text/data to be decrypted. Accepts Strings + * and Objects with a getText method + * @param {Boolean} base64 (optional) Response is expected to be base64 + * encoded * @returns {Promise} decrypted message: data: The decrypted data. This may be base64 encoded. base64: Boolean indicating whether data is base64 encoded. mime: A Boolean indicating whether the data is a MIME object. signatures: Array of signature Objects TODO not yet implemented. - // should be an object that can tell if all signatures are valid etc. + // should be an object that can tell if all signatures are valid . * @async */ decrypt(data, base64=false){ @@ -124,14 +136,16 @@ export class GpgME { /** * Sign a Message - * @param {String|Object} data text/data to be decrypted. Accepts Strings and Objects with a gettext methos - * @param {GPGME_Key|String|Array|Array} keys The key/keys to use for signing + * @param {String|Object} data text/data to be decrypted. Accepts Strings + * and Objects with a gettext methos + * @param {GPGME_Key|String|Array|Array} keys The + * key/keys to use for signing * @param {*} mode The signing mode. Currently supported: * 'clearsign': (default) The Message is embedded into the signature * 'detached': The signature is stored separately * @param {*} base64 input is considered base64 * @returns {Promise} - * data: The resulting data. In clearsign mode this includes the signature + * data: The resulting data. Includes the signature in clearsign mode * signature: The detached signature (if in detached mode) * @async */ @@ -154,7 +168,6 @@ export class GpgME { if (mode === 'detached') { msg.expected = 'base64'; } - let me = this; return new Promise(function(resolve,reject) { msg.post().then( function(message) { if (mode === 'clearsign'){ @@ -169,7 +182,7 @@ export class GpgME { } }, function(error){ reject(error); - }) + }); }); } } @@ -180,7 +193,7 @@ export class GpgME { * @param {*} data The data to enter */ function putData(message, data){ - if (!message || !message instanceof GPGME_Message ) { + if (!message || !(message instanceof GPGME_Message) ) { return gpgme_error('PARAM_WRONG'); } if (!data){ diff --git a/lang/js/src/index.js b/lang/js/src/index.js index 220a698..1b13ec4 100644 --- a/lang/js/src/index.js +++ b/lang/js/src/index.js @@ -16,16 +16,21 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ -import { GpgME } from "./gpgmejs"; -import { gpgme_error } from "./Errors"; -import { Connection } from "./Connection"; -import { defaultConf, availableConf } from "./Config"; + +import { GpgME } from './gpgmejs'; +import { gpgme_error } from './Errors'; +import { Connection } from './Connection'; +import { defaultConf, availableConf } from './Config'; /** * Initializes a nativeMessaging Connection and returns a GPGMEjs object - * @param {Object} config Configuration. See Config.js for available parameters. Still TODO + * @param {Object} config Configuration. See Config.js for available parameters. + * Still TODO */ function init(config){ let _conf = parseconfiguration(config); @@ -41,16 +46,16 @@ function init(config){ } else { reject(gpgme_error('CONN_NO_CONNECT')); } - }, function(error){ + }, function(){ //unspecific connection error. Should not happen reject(gpgme_error('CONN_NO_CONNECT')); - }); + }); }); } function parseconfiguration(rawconfig = {}){ if ( typeof(rawconfig) !== 'object'){ return gpgme_error('PARAM_WRONG'); - }; + } let result_config = {}; let conf_keys = Object.keys(rawconfig); @@ -75,8 +80,8 @@ function parseconfiguration(rawconfig = {}){ } } return result_config; -}; +} export default { init: init -} \ No newline at end of file +}; \ No newline at end of file diff --git a/lang/js/src/permittedOperations.js b/lang/js/src/permittedOperations.js index e4f9bd2..445a40c 100644 --- a/lang/js/src/permittedOperations.js +++ b/lang/js/src/permittedOperations.js @@ -16,9 +16,12 @@ * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach */ - /** +/** * Definition of the possible interactions with gpgme-json. * operation: required: Array @@ -41,7 +44,7 @@ infos: Array<*> arbitrary information that may result in a list } } - */ +*/ export const permittedOperations = { encrypt: { @@ -65,7 +68,7 @@ export const permittedOperations = { array_allowed: true }, 'chunksize': { - allowed: ['number'] + allowed: ['number'] }, 'base64': { allowed: ['boolean'] @@ -154,7 +157,8 @@ export const permittedOperations = { }, 'mode': { allowed: ['string'], - allowed_data: ['detached', 'clearsign'] // TODO 'opaque' not used + allowed_data: ['detached', 'clearsign'] + // TODO 'opaque' is not used, but available on native app }, 'base64': { allowed: ['boolean'] @@ -166,14 +170,17 @@ export const permittedOperations = { answer: { type: ['signature', 'ciphertext'], data: ['data'], // Unless armor mode is used a Base64 encoded binary - // signature. In armor mode a string with an armored - // OpenPGP or a PEM message. + // signature. In armor mode a string with an armored + // OpenPGP or a PEM message. params: ['base64'] } }, + // note: For the meaning of the optional keylist flags, refer to + // https://www.gnupg.org/documentation/manuals/gpgme/Key-Listing-Mode.html keylist:{ required: {}, + optional: { 'protocol': { allowed: ['string'], @@ -182,8 +189,6 @@ export const permittedOperations = { 'chunksize': { allowed: ['number'], }, - // note: For the meaning of the flags, refer to - // https://www.gnupg.org/documentation/manuals/gpgme/Key-Listing-Mode.html 'secret': { allowed: ['boolean'] }, @@ -305,11 +310,6 @@ export const permittedOperations = { infos: [] } }, - /** - *TBD get armored secret different treatment from keyinfo! - * TBD key modification? - - */ version: { required: {}, @@ -321,4 +321,11 @@ export const permittedOperations = { params:[] } } -} + + /** + * TBD handling of secrets + * TBD key modification? + * TBD: key generation + */ + +}; diff --git a/lang/js/unittests.js b/lang/js/unittests.js index d111844..ce1dd0c 100644 --- a/lang/js/unittests.js +++ b/lang/js/unittests.js @@ -32,7 +32,7 @@ import { GPGME_Keyring } from './src/Keyring'; import {GPGME_Message, createMessage} from './src/Message'; mocha.setup('bdd'); -var expect = chai.expect; +const expect = chai.expect; chai.config.includeStack = true; function unittests (){ @@ -266,78 +266,48 @@ function unittests (){ expect(keyring.getKeys).to.be.a('function'); }); - it('Loading Keys from Keyring, to be used synchronously', function(done){ - let keyring = new GPGME_Keyring; - keyring.getKeys(null, true).then(function(result){ - expect(result).to.be.an('array'); - expect(result[0]).to.be.an.instanceof(GPGME_Key); - expect(result[0].get('armored')).to.be.a('string'); - expect(result[0].get('armored')).to.include( - '-----END PGP PUBLIC KEY BLOCK-----'); - done(); - }); - }); + it('Loading Keys from Keyring, to be used synchronously', + function(done){ + let keyring = new GPGME_Keyring; + keyring.getKeys(null, true).then(function(result){ + expect(result).to.be.an('array'); + expect(result[0]).to.be.an.instanceof(GPGME_Key); + expect(result[0].get('armored')).to.be.a('string'); + expect(result[0].get('armored')).to.include( + '-----END PGP PUBLIC KEY BLOCK-----'); + done(); + }); + } + ); - it('Loading specific Key from Keyring, to be used synchronously', function(done){ - let keyring = new GPGME_Keyring; - keyring.getKeys(kp.validKeyFingerprint, true).then(function(result){ - expect(result).to.be.an('array'); - expect(result[0]).to.be.an.instanceof(GPGME_Key); - expect(result[0].get('armored')).to.be.a('string'); - expect(result[0].get('armored')).to.include( - '-----END PGP PUBLIC KEY BLOCK-----'); - done(); - }); - }); + it('Loading specific Key from Keyring, to be used synchronously', + function(done){ + let keyring = new GPGME_Keyring; + keyring.getKeys(kp.validKeyFingerprint, true).then( + function(result){ + expect(result).to.be.an('array'); + expect(result[0]).to.be.an.instanceof(GPGME_Key); + expect(result[0].get('armored')).to.be.a('string'); + expect(result[0].get('armored')).to.include( + '-----END PGP PUBLIC KEY BLOCK-----'); + done(); + } + ); + } + ); it('Querying non-existing Key from Keyring', function(done){ let keyring = new GPGME_Keyring; - keyring.getKeys(kp.invalidKeyFingerprint, true).then(function(result){ - expect(result).to.be.an('array'); - expect(result.length).to.equal(0); - done(); - }); + keyring.getKeys(kp.invalidKeyFingerprint, true).then( + function(result){ + expect(result).to.be.an('array'); + expect(result.length).to.equal(0); + done(); + } + ); }); - }); - // describe('Keyring import/export', function(){ - // before(function(done) { - // let keyring = new GPGME_Keyring; - - // keyring.getKeys(ak.fingerprint, false).then(function(result){ - // if (result.length === 1){ - // result[0].delete().then(function(delete_result){ - // if (delete_result === true){ - // done(); - // } - // }); - // } else { - // done(); - // } - // }); - // }); - // it('Import Public Key', function(done){ - // keyring.importKey(ak.key).then(function(result){ - // expect(result).to.be.an('array'); - // expect(result[0].key).to.be.an.instanceof(GPGME_Key); - // expect(result[0].changed).to.equal('newkey'); - // expect(result[0].key.keyring).to.equal(ak.fingerprint); - // done(); - // }); - // }); - - // it('Update Public Key', function(done){ - // keyring.importKey(ak.key).then(function(result){ - // expect(result).to.be.an('array'); - // expect(result[0].key).to.be.an.instanceof(GPGME_Key); - // expect(result[0].changed).to.equal('change'); - // expect(result[0].changes.userId).to.be.true; - // expect(result[0].changes.subkeys).to.be.false; - // expect(result[0].key.keyring).to.equal(ak.fingerprint); - // done(); - // }); - // }); - // }); + }); describe('GPGME_Message', function(){ ----------------------------------------------------------------------- Summary of changes: lang/js/.eslintrc.json | 3 + lang/js/BrowserTestExtension/popup.js | 22 +--- lang/js/BrowserTestExtension/runbrowsertest.js | 5 + lang/js/BrowserTestExtension/rununittests.js | 6 + lang/js/BrowserTestExtension/setup_testing.js | 8 +- .../BrowserTestExtension/tests/KeyImportExport.js | 3 + .../tests/encryptDecryptTest.js | 91 ++++++++------- lang/js/BrowserTestExtension/tests/encryptTest.js | 113 +++++++++--------- lang/js/BrowserTestExtension/tests/inputvalues.js | 9 +- .../BrowserTestExtension/tests/longRunningTests.js | 101 +++++++++++----- lang/js/BrowserTestExtension/tests/signTest.js | 31 +++-- lang/js/BrowserTestExtension/tests/startup.js | 24 ++-- lang/js/CHECKLIST | 19 +-- lang/js/DemoExtension/entry.js | 5 + lang/js/DemoExtension/maindemo.js | 40 ++++--- lang/js/package.json | 4 +- lang/js/src/Config.js | 3 + lang/js/src/Connection.js | 130 ++++++++++----------- lang/js/src/Errors.js | 6 +- lang/js/src/Helpers.js | 29 +++-- lang/js/src/Key.js | 93 +++++++-------- lang/js/src/Keyring.js | 32 +++-- lang/js/src/Message.js | 95 +++++++-------- lang/js/src/gpgmejs.js | 57 +++++---- lang/js/src/index.js | 25 ++-- lang/js/src/permittedOperations.js | 35 +++--- lang/js/unittests.js | 104 ++++++----------- 27 files changed, 595 insertions(+), 498 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 15:29:14 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Wed, 06 Jun 2018 15:29:14 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-55-g7a07227 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via 7a072270ac031152ee034df0f5b6ef5e8bf7d394 (commit) from bfd3799d39df265882deedeee083fd5246a2f35d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7a072270ac031152ee034df0f5b6ef5e8bf7d394 Author: Maximilian Krambach Date: Wed Jun 6 15:29:21 2018 +0200 js: change Keyinfo timestamps into javascript date -- * src/Key.js diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index 8c8726a..5986254 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -115,6 +115,9 @@ export class GPGME_Key { new GPGME_UserId(data.userids[i])); } break; + case 'last_update': + this._data[dataKeys[i]] = new Date( data[dataKeys[i]] * 1000 ); + break; default: this._data[dataKeys[i]] = data[dataKeys[i]]; } @@ -124,7 +127,6 @@ export class GPGME_Key { /** * Query any property of the Key list - * (TODO: armor not in here, might be unexpected) * @param {String} property Key property to be retreived * @param {*} cached (optional) if false, the data will be directly queried * from gnupg. @@ -313,7 +315,11 @@ class GPGME_Subkey { } if (validSubKeyProperties.hasOwnProperty(property)){ if (validSubKeyProperties[property](value) === true) { - this._data[property] = value; + if (property === 'timestamp' || property === 'expires'){ + this._data[property] = new Date(value * 1000); + } else { + this._data[property] = value; + } } } } @@ -346,9 +352,14 @@ class GPGME_UserId { } if (validUserIdProperties.hasOwnProperty(property)){ if (validUserIdProperties[property](value) === true) { - this._data[property] = value; + if (property === 'last_update'){ + this._data[property] = new Date(value*1000); + } else { + this._data[property] = value; + } } } + } /** ----------------------------------------------------------------------- Summary of changes: lang/js/src/Key.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 15:56:39 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 15:56:39 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-138-g344b548 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 344b548dc71657d0285d93f78f17a2663b5e586f (commit) from 257661d6ae0ca376df758c38fabab2316d10e3a9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 344b548dc71657d0285d93f78f17a2663b5e586f Author: Werner Koch Date: Wed Jun 6 15:46:24 2018 +0200 gpg: Also detect a plaintext packet before an encrypted packet. * g10/mainproc.c (proc_encrypted): Print warning and later force an error. -- Note that when this error is triggered the plaintext from the literal data packet has already been outputted before the BEGIN_DECRYPTION status line. We fail only later to get more information. Callers need to check and act upon the decryption error code anyway. Thanks to Marcus for pointing out this case. GnuPG-bug-id: 4000 Signed-off-by: Werner Koch diff --git a/g10/mainproc.c b/g10/mainproc.c index 5689d73..d2ceec2 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -615,6 +615,14 @@ static void proc_encrypted (CTX c, PACKET *pkt) { int result = 0; + int early_plaintext = literals_seen; + + if (early_plaintext) + { + log_info (_("WARNING: multiple plaintexts seen\n")); + write_status_errcode ("decryption.early_plaintext", GPG_ERR_BAD_DATA); + /* We fail only later so that we can print some more info first. */ + } if (!opt.quiet) { @@ -734,6 +742,10 @@ proc_encrypted (CTX c, PACKET *pkt) if (!result) result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek ); + /* Trigger the deferred error. */ + if (!result && early_plaintext) + result = gpg_error (GPG_ERR_BAD_DATA); + if (result == -1) ; else if (!result ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 15:58:31 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 15:58:31 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-13-g054a187 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 054a187f24b19313cec59414fa924640e1b8c79c (commit) from dc87a3341f28ddac1113e90a3861d062be2610e2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 054a187f24b19313cec59414fa924640e1b8c79c Author: Werner Koch Date: Wed Jun 6 15:46:24 2018 +0200 gpg: Also detect a plaintext packet before an encrypted packet. * g10/mainproc.c (proc_encrypted): Print warning and later force an error. -- Note that when this error is triggered the plaintext from the literal data packet has already been outputted before the BEGIN_DECRYPTION status line. We fail only later to get more information. Callers need to check and act upon the decryption error code anyway. Thanks to Marcus for pointing out this case. GnuPG-bug-id: 4000 Signed-off-by: Werner Koch (cherry picked from commit 344b548dc71657d0285d93f78f17a2663b5e586f) diff --git a/g10/mainproc.c b/g10/mainproc.c index e3be894..116b72a 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -532,6 +532,14 @@ static void proc_encrypted (CTX c, PACKET *pkt) { int result = 0; + int early_plaintext = literals_seen; + + if (early_plaintext) + { + log_info (_("WARNING: multiple plaintexts seen\n")); + write_status_errcode ("decryption.early_plaintext", GPG_ERR_BAD_DATA); + /* We fail only later so that we can print some more info first. */ + } if (!opt.quiet) { @@ -651,6 +659,10 @@ proc_encrypted (CTX c, PACKET *pkt) if (!result) result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek ); + /* Trigger the deferred error. */ + if (!result && early_plaintext) + result = gpg_error (GPG_ERR_BAD_DATA); + if (result == -1) ; else if (!result ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 16:28:58 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 16:28:58 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-49-g2c4c569 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 2c4c5692472f5870f907c2c3f01870879cb0c34b (commit) from 998fec8a4fbc46315fe6836980954eed402b38c5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2c4c5692472f5870f907c2c3f01870879cb0c34b Author: Werner Koch Date: Wed Jun 6 16:20:27 2018 +0200 core: Return a better error code on certain decryption failures. * src/decrypt.c (op_data_t): Add field first_status_error. (parse_status_error): Set it. (_gpgme_decrypt_status_handler): Prefer an ERROR code over a NO_SECKEY. -- GnuPG-bug-id: 3983 Signed-off-by: Werner Koch diff --git a/src/decrypt.c b/src/decrypt.c index 8c95ebe..f5b93d7 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -53,7 +53,7 @@ typedef struct * status lines for each key the message has been encrypted to but * that secret key is not available. This can't be done for hidden * recipients, though. We track it here to allow for a better error - * message that the general DECRYPTION_FAILED. */ + * message than the general DECRYPTION_FAILED. */ int any_no_seckey; /* If the engine emits a DECRYPTION_INFO status and that does not @@ -61,6 +61,10 @@ typedef struct * is set. */ int not_integrity_protected; + /* The error code from the first ERROR line. This is in some cases + * used to return a better matching error code to the caller. */ + gpg_error_t first_status_error; + /* A pointer to the next pointer of the last recipient in the list. This makes appending new invalid signers painless while preserving the order. */ @@ -222,6 +226,10 @@ parse_status_error (char *args, op_data_t opd) opd->not_integrity_protected = 1; } + /* Record the first error code. */ + if (err && !opd->first_status_error) + opd->first_status_error = err; + free (args2); return 0; @@ -360,17 +368,43 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, * only a warning. * Fixme: These error values should probably be attributed to * the underlying crypto engine (as error source). */ - if (opd->failed && opd->pkdecrypt_failed) - return opd->pkdecrypt_failed; - else if (opd->failed && opd->any_no_seckey) - return gpg_error (GPG_ERR_NO_SECKEY); - else if (opd->failed || (opd->not_integrity_protected - && !ctx->ignore_mdc_error)) - return gpg_error (GPG_ERR_DECRYPT_FAILED); + if (opd->failed) + { + /* This comes from a specialized ERROR status line. */ + if (opd->pkdecrypt_failed) + return opd->pkdecrypt_failed; + + /* For an integrity failure return just DECRYPTION_FAILED; + * the actual cause can be taken from an already set + * decryption result flag. */ + if ((opd->not_integrity_protected && !ctx->ignore_mdc_error)) + return gpg_error (GPG_ERR_DECRYPT_FAILED); + + /* If we have any other ERROR code we prefer that over + * NO_SECKEY because it is probably the better matching + * code. For example a garbled message with multiple + * plaintext will return BAD_DATA here but may also have + * indicated a NO_SECKEY. */ + if (opd->first_status_error) + return opd->first_status_error; + + /* No secret key is pretty common reason. */ + if (opd->any_no_seckey) + return gpg_error (GPG_ERR_NO_SECKEY); + + /* Generic decryption failed error code. */ + return gpg_error (GPG_ERR_DECRYPT_FAILED); + } else if (!opd->okay) - return gpg_error (GPG_ERR_NO_DATA); + { + /* No data was found. */ + return gpg_error (GPG_ERR_NO_DATA); + } else if (opd->failure_code) - return opd->failure_code; + { + /* The engine returned failure code at program exit. */ + return opd->failure_code; + } break; case GPGME_STATUS_DECRYPTION_INFO: @@ -389,8 +423,9 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, case GPGME_STATUS_ERROR: /* Note that this is an informational status code which should - not lead to an error return unless it is something not - related to the backend. */ + * not lead to an error return unless it is something not + * related to the backend. However, it is used to return a + * better matching final error code. */ err = parse_status_error (args, opd); if (err) return err; ----------------------------------------------------------------------- Summary of changes: src/decrypt.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 12 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 17:34:37 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 17:34:37 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-14-g8c0e1fa Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 8c0e1fac960f6e6bbc1bd09c3c788192e838e16a (commit) from 054a187f24b19313cec59414fa924640e1b8c79c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8c0e1fac960f6e6bbc1bd09c3c788192e838e16a Author: Werner Koch Date: Wed Jun 6 17:25:51 2018 +0200 doc: Typo fixes -- Reported-by: Claus Assmann Signed-off-by: Werner Koch (cherry picked from commit 70f26e4263364f4b521c7856c38ba7ee59e38445) diff --git a/doc/gpg.texi b/doc/gpg.texi index 4dab238..ca13047 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -328,7 +328,7 @@ following the "sig" tag (and thus before the flags described below. A "!" indicates that the signature has been successfully verified, a "-" denotes a bad signature and a "%" is used if an error occurred while checking the signature (e.g. a non supported algorithm). Signatures -where the public key is not availabale are not listed; to see their +where the public key is not available are not listed; to see their keyids the command @option{--list-sigs} can be used. For each signature listed, there are several flags in between the @@ -3334,7 +3334,7 @@ absolute date in the form YYYY-MM-DD. Defaults to "0". @opindex default-new-key-algo @var{string} This option can be used to change the default algorithms for key generation. The @var{string} is similar to the arguments required for -the command @option{--quick-add-key} but slighly different. For +the command @option{--quick-add-key} but slightly different. For example the current default of @code{"rsa2048/cert,sign+rsa2048/encr"} (or @code{"rsa3072"}) can be changed to the value of what we currently call future default, which is @code{"ed25519/cert,sign+cv25519/encr"}. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index a9e6d1e..81af281 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -399,7 +399,7 @@ comes with almost all German banking cards. This application adds read-only support for keys and certificates stored on a @uref{http://www.smartcard-hsm.com, SmartCard-HSM}. -To generate keys and store certifiates you may use +To generate keys and store certificates you may use @uref{https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM, OpenSC} or the tools from @uref{http://www.openscdp.org, OpenSCDP}. diff --git a/doc/tools.texi b/doc/tools.texi index 9301334..7becf67 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -290,7 +290,7 @@ Check the options for the component @var{component}. Apply the configuration settings listed in @var{file} to the configuration files. If @var{file} has no suffix and no slashes the command first tries to read a file with the suffix @code{.prf} from -the the data directory (@code{gpgconf --list-dirs datadir}) before it +the data directory (@code{gpgconf --list-dirs datadir}) before it reads the file verbatim. A profile is divided into sections using the bracketed component name. Each section then lists the option which shall go into the respective configuration file. ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 ++-- doc/scdaemon.texi | 2 +- doc/tools.texi | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 17:34:42 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 17:34:42 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-139-g70f26e4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 70f26e4263364f4b521c7856c38ba7ee59e38445 (commit) from 344b548dc71657d0285d93f78f17a2663b5e586f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 70f26e4263364f4b521c7856c38ba7ee59e38445 Author: Werner Koch Date: Wed Jun 6 17:25:51 2018 +0200 doc: Typo fixes -- Reported-by: Claus Assmann Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 642805f..9db2365 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -328,7 +328,7 @@ following the "sig" tag (and thus before the flags described below. A "!" indicates that the signature has been successfully verified, a "-" denotes a bad signature and a "%" is used if an error occurred while checking the signature (e.g. a non supported algorithm). Signatures -where the public key is not availabale are not listed; to see their +where the public key is not available are not listed; to see their keyids the command @option{--list-sigs} can be used. For each signature listed, there are several flags in between the @@ -3377,7 +3377,7 @@ absolute date in the form YYYY-MM-DD. Defaults to "0". @opindex default-new-key-algo @var{string} This option can be used to change the default algorithms for key generation. The @var{string} is similar to the arguments required for -the command @option{--quick-add-key} but slighly different. For +the command @option{--quick-add-key} but slightly different. For example the current default of @code{"rsa2048/cert,sign+rsa2048/encr"} (or @code{"rsa3072"}) can be changed to the value of what we currently call future default, which is @code{"ed25519/cert,sign+cv25519/encr"}. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index a9e6d1e..81af281 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -399,7 +399,7 @@ comes with almost all German banking cards. This application adds read-only support for keys and certificates stored on a @uref{http://www.smartcard-hsm.com, SmartCard-HSM}. -To generate keys and store certifiates you may use +To generate keys and store certificates you may use @uref{https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM, OpenSC} or the tools from @uref{http://www.openscdp.org, OpenSCDP}. diff --git a/doc/tools.texi b/doc/tools.texi index 9301334..7becf67 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -290,7 +290,7 @@ Check the options for the component @var{component}. Apply the configuration settings listed in @var{file} to the configuration files. If @var{file} has no suffix and no slashes the command first tries to read a file with the suffix @code{.prf} from -the the data directory (@code{gpgconf --list-dirs datadir}) before it +the data directory (@code{gpgconf --list-dirs datadir}) before it reads the file verbatim. A profile is divided into sections using the bracketed component name. Each section then lists the option which shall go into the respective configuration file. ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 ++-- doc/scdaemon.texi | 2 +- doc/tools.texi | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 18:38:04 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 18:38:04 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-140-g7ffc1ac Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 7ffc1ac7dd95d4cc1897a4c36d5cd628741c12f2 (commit) from 70f26e4263364f4b521c7856c38ba7ee59e38445 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7ffc1ac7dd95d4cc1897a4c36d5cd628741c12f2 Author: Werner Koch Date: Wed Jun 6 18:28:44 2018 +0200 agent: Add DBUS_SESSION_BUS_ADDRESS et al. to the startup list. * agent/gpg-agent.c (agent_copy_startup_env): Replace explicit list with the standard list. -- Although the function agent_copy_startup_env is newer than session_env_list_stdenvnames the latter was not used. When DBUS_SESSION_BUS_ADDRESS was added to the latter it was forgotten to add it to the former as well. Having all stdnames here seems to be the Right Thing (tm) to do. GnuPG-bug-id: 3947 Signed-off-by: Werner Koch diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index bd9a471..1fdc94d 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1979,15 +1979,15 @@ agent_deinit_default_ctrl (ctrl_t ctrl) gpg_error_t agent_copy_startup_env (ctrl_t ctrl) { - static const char *names[] = - {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL}; gpg_error_t err = 0; - int idx; - const char *value; + int iterator = 0; + const char *name, *value; - for (idx=0; !err && names[idx]; idx++) - if ((value = session_env_getenv (opt.startup_env, names[idx]))) - err = session_env_setenv (ctrl->session_env, names[idx], value); + while (!err && (name = session_env_list_stdenvnames (&iterator, NULL))) + { + if ((value = session_env_getenv (opt.startup_env, name))) + err = session_env_setenv (ctrl->session_env, name, value); + } if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype) if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype))) ----------------------------------------------------------------------- Summary of changes: agent/gpg-agent.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 18:38:37 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 18:38:37 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-15-gc5c8fb1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via c5c8fb1ec7c8690495de6189ec2c3a322db4e881 (commit) from 8c0e1fac960f6e6bbc1bd09c3c788192e838e16a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c5c8fb1ec7c8690495de6189ec2c3a322db4e881 Author: Werner Koch Date: Wed Jun 6 18:28:44 2018 +0200 agent: Add DBUS_SESSION_BUS_ADDRESS et al. to the startup list. * agent/gpg-agent.c (agent_copy_startup_env): Replace explicit list with the standard list. -- Although the function agent_copy_startup_env is newer than session_env_list_stdenvnames the latter was not used. When DBUS_SESSION_BUS_ADDRESS was added to the latter it was forgotten to add it to the former as well. Having all stdnames here seems to be the Right Thing (tm) to do. GnuPG-bug-id: 3947 Signed-off-by: Werner Koch (cherry picked from commit 7ffc1ac7dd95d4cc1897a4c36d5cd628741c12f2) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index bd9a471..1fdc94d 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1979,15 +1979,15 @@ agent_deinit_default_ctrl (ctrl_t ctrl) gpg_error_t agent_copy_startup_env (ctrl_t ctrl) { - static const char *names[] = - {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL}; gpg_error_t err = 0; - int idx; - const char *value; + int iterator = 0; + const char *name, *value; - for (idx=0; !err && names[idx]; idx++) - if ((value = session_env_getenv (opt.startup_env, names[idx]))) - err = session_env_setenv (ctrl->session_env, names[idx], value); + while (!err && (name = session_env_list_stdenvnames (&iterator, NULL))) + { + if ((value = session_env_getenv (opt.startup_env, name))) + err = session_env_setenv (ctrl->session_env, name, value); + } if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype) if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype))) ----------------------------------------------------------------------- Summary of changes: agent/gpg-agent.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 6 19:07:48 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Jun 2018 19:07:48 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-70-g7b6c2af Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 7b6c2afd699e889f5f054cc3d202a61bd0ee1dcf (commit) via 6606ae44e0de1069b29dd4215ee9748280940e1b (commit) from 61dbb7c08ab11c10060e193b52e3e1d2ec6dd062 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7b6c2afd699e889f5f054cc3d202a61bd0ee1dcf Author: Werner Koch Date: Tue Jun 5 14:33:01 2018 +0200 ecc: Improve gcry_mpi_ec_curve_point * mpi/ec.c (_gcry_mpi_ec_curve_point): Check range of coordinates. * tests/t-mpi-point.c (point_on_curve): New. -- Due to the conversion to affine coordinates we didn't detected points with values >= P. The solution here might not be the best according to the NIST standard (it is done there at an earlier opportunity) but it reliably detects points we do not expect to receive. The new test vectors have been compared against gnutls/nettle. Reported-by: Stephan M?ller Signed-off-by: Werner Koch diff --git a/mpi/ec.c b/mpi/ec.c index 2c396a7..97afbfe 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1731,6 +1731,15 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) y = mpi_new (0); w = mpi_new (0); + /* Check that the point is in range. This needs to be done here and + * not after conversion to affine coordinates. */ + if (mpi_cmpabs (point->x, ctx->p) >= 0) + goto leave; + if (mpi_cmpabs (point->y, ctx->p) >= 0) + goto leave; + if (mpi_cmpabs (point->z, ctx->p) >= 0) + goto leave; + switch (ctx->model) { case MPI_EC_WEIERSTRASS: diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 1eaa08a..f2378bf 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -1045,6 +1045,271 @@ twistededwards_math (void) } +/* Check the point on curve function. */ +static void +point_on_curve (void) +{ + static struct { + const char *curve; + int oncurve; /* Point below is on the curve. */ + const char *qx; + const char *qy; + } t[] = { + { + "NIST P-256", 0, + "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974", + "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3" + }, { + "NIST P-256", 0, + "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651", + "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D" + }, { + "NIST P-256", 0, + "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291", + "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023" + }, { + "NIST P-256", 1, + "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B", + "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63" + }, { + "NIST P-256", 0, + "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53", + "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600" + }, { + "NIST P-256", 1, + "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36", + "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E" + }, { + "NIST P-256", 0, + "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990", + "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E" + }, { + "NIST P-256", 1, + "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE", + "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D" + }, { + "NIST P-256", 1, + "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945", + "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63" + }, { + "NIST P-256", 0, + "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84", + "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F" + }, { + "NIST P-256", 0, + "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC", + "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902" + }, { + "NIST P-256", 0, + "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C", + "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0" + } , { + "NIST P-384", 0, + "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00" + "83EC46A8F2FF3203C5C7F8C7E722A5EF", + "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922" + "96470753DCF46173C9AA4A8A4C2FBE51" + }, { + "NIST P-384", 0, + "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752" + "02CE06CCBE705EA8A38AA2894D4BEEE6", + "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F" + "8E0875F4C4BB1E3D0F8535C7A52306FB82" + }, { + "NIST P-384", 1, + "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23" + "D719ED4116E2CC907AEB92CF22331A60", + "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E" + "9FC63F61EF19DE9B3CEA98D163ABF254" + }, { + "NIST P-384", 0, + "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24" + "EC2F0CA62FF1F90B6515DE356EC2A404", + "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692" + "72F4D3A87E88529754E109BB9B61B03B" + }, { + "NIST P-384", 0, + "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2" + "9A440AD51C94CF5BC28817C8C6E2D302", + "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1" + "8306976291F3ADC0B5ABA42DED376EA9A5" + }, { + "NIST P-384", 0, + "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03" + "B958BF28B022E54E320672C4BAD4EEC0", + "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA" + "9E558E9F58ED1D324C9DCBCB4E8F2A5970" + }, { + "NIST P-384", 0, + "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293" + "18BCB9FC60499D009F949298F3F9F47B", + "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86" + "CFE9C552E2E720F5DA5806503D3784CD" + }, { + "NIST P-384", 0, + "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20" + "823CA8F84D2BBF4EA687885437DE7839", + "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1" + "69F3656C322DE45C4A70DC6DB9A661E599" + }, { + "NIST P-384", 1, + "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3" + "89B92C9A55573A596123415FBFA26991", + "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B" + "F3B04F46DBFFE08151E0F0950CC70081" + }, { + "NIST P-384", 0, + "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB" + "4C0F876575DDEC1BDB3F3F04061C9AE4", + "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352" + "D7BBEEFB803F6CC8FC7895E47F348D33" + }, { + "NIST P-384", 1, + "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36" + "F1D8325E45734D5A0FDD103F4DF6F83E", + "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B" + "F26E8D87EC175577E782AD51A6A12C02" + }, { + "NIST P-384", 1, + "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C" + "187BECA23369DFD6C15CC0DA0629958F", + "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB" + "73DE6AA96140B5C457B7486E06D318CE" + }, { + "NIST P-521", 0, + "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024" + "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70", + "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90" + "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0" + }, { + "NIST P-521", 0, + "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437" + "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3", + "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D" + "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48" + }, { + "NIST P-521", 1, + "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4" + "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8", + "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE" + "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97" + }, { + "NIST P-521", 0, + "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E" + "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D", + "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5" + "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF" + }, { + "NIST P-521", 0, + "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489" + "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117", + "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E" + "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD" + }, { + "NIST P-521", 1, + "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55" + "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56", + "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B" + "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004" + }, { + "NIST P-521", 0, + "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A" + "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023", + "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C" + "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291" + }, { + "NIST P-521", 0, + "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86" + "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE", + "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125" + "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4" + }, { + "NIST P-521", 0, + "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1" + "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03", + "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF" + "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89" + }, { + "NIST P-521", 0, + "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9" + "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93", + "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B" + "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B" + }, { + "NIST P-521", 1, + "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056" + "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C", + "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901" + "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080" + }, { + "NIST P-521", 1, + "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5" + "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1", + "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635" + "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9" + } + }; + gpg_error_t err; + int tidx; + const char *lastcurve = NULL; + gcry_ctx_t ctx = NULL; + gcry_mpi_t qx = NULL; + gcry_mpi_t qy = NULL; + gcry_mpi_point_t Q; + int oncurve; + + wherestr = "point_on_curve"; + for (tidx=0; tidx < DIM (t); tidx++) + { + if (!t[tidx].curve) + { + if (!lastcurve || !ctx) + die ("invalid test vectors at idx %d\n", tidx); + } + else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve)) + { + lastcurve = t[tidx].curve; + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, NULL, lastcurve); + if (err) + die ("error creating context for curve %s at idx %d: %s\n", + lastcurve, tidx, gpg_strerror (err)); + + info ("checking points on curve %s\n", lastcurve); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + qx = hex2mpi (t[tidx].qx); + qy = hex2mpi (t[tidx].qy); + + Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE); + if (!Q) + die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx); + + oncurve = gcry_mpi_ec_curve_point (Q, ctx); + + if (t[tidx].oncurve && !oncurve) + { + fail ("point expected on curve but not identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + else if (!t[tidx].oncurve && oncurve) + { + fail ("point not expected on curve but identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + gcry_mpi_point_release (Q); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + gcry_ctx_release (ctx); +} + + int main (int argc, char **argv) { @@ -1067,6 +1332,7 @@ main (int argc, char **argv) context_alloc (); context_param (); basic_ec_math (); + point_on_curve (); /* The tests are for P-192 and ed25519 which are not supported in FIPS mode. */ commit 6606ae44e0de1069b29dd4215ee9748280940e1b Author: Werner Koch Date: Tue Jun 5 14:29:53 2018 +0200 mpi: New internal function _gcry_mpi_cmpabs. * mpi/mpi-cmp.c (_gcry_mpi_cmp): Factor out to ... (do_mpi_cmp): New. Add arg absmode. (_gcry_mpi_cmpabs): New. * src/gcrypt-int.h (mpi_cmpabs): New macro. Signed-off-by: Werner Koch diff --git a/mpi/mpi-cmp.c b/mpi/mpi-cmp.c index 838a7c9..66e0961 100644 --- a/mpi/mpi-cmp.c +++ b/mpi/mpi-cmp.c @@ -54,15 +54,19 @@ _gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) } -int -_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) +/* Helper for _gcry_mpi_cmp and _gcry_mpi_cmpabs. */ +static int +do_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v, int absmode) { mpi_size_t usize; mpi_size_t vsize; + int usign; + int vsign; int cmp; if (mpi_is_opaque (u) || mpi_is_opaque (v)) { + /* We have no signan and thus ABSMODE has no efeect here. */ if (mpi_is_opaque (u) && !mpi_is_opaque (v)) return -1; if (!mpi_is_opaque (u) && mpi_is_opaque (v)) @@ -82,26 +86,42 @@ _gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) usize = u->nlimbs; vsize = v->nlimbs; + usign = absmode? 0 : u->sign; + vsign = absmode? 0 : v->sign; /* Compare sign bits. */ - if (!u->sign && v->sign) + if (!usign && vsign) return 1; - if (u->sign && !v->sign) + if (usign && !vsign) return -1; /* U and V are either both positive or both negative. */ - if (usize != vsize && !u->sign && !v->sign) + if (usize != vsize && !usign && !vsign) return usize - vsize; - if (usize != vsize && u->sign && v->sign) + if (usize != vsize && usign && vsign) return vsize + usize; if (!usize ) return 0; if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) return 0; - if ((cmp < 0?1:0) == (u->sign?1:0)) + if ((cmp < 0?1:0) == (usign?1:0)) return 1; } return -1; } + + +int +_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) +{ + return do_mpi_cmp (u, v, 0); +} + +/* Compare only the absolute values. */ +int +_gcry_mpi_cmpabs (gcry_mpi_t u, gcry_mpi_t v) +{ + return do_mpi_cmp (u, v, 1); +} diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h index e88f868..7934f14 100644 --- a/src/gcrypt-int.h +++ b/src/gcrypt-int.h @@ -368,6 +368,7 @@ int _gcry_mpi_is_neg (gcry_mpi_t a); void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u); void _gcry_mpi_abs (gcry_mpi_t w); int _gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); +int _gcry_mpi_cmpabs (const gcry_mpi_t u, const gcry_mpi_t v); int _gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); gpg_err_code_t _gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, const void *buffer, size_t buflen, @@ -469,6 +470,7 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); #define mpi_abs( w ) _gcry_mpi_abs( (w) ) #define mpi_neg( w, u) _gcry_mpi_neg( (w), (u) ) #define mpi_cmp( u, v ) _gcry_mpi_cmp( (u), (v) ) +#define mpi_cmpabs( u, v ) _gcry_mpi_cmpabs( (u), (v) ) #define mpi_cmp_ui( u, v ) _gcry_mpi_cmp_ui( (u), (v) ) #define mpi_is_neg( a ) _gcry_mpi_is_neg ((a)) ----------------------------------------------------------------------- Summary of changes: mpi/ec.c | 9 ++ mpi/mpi-cmp.c | 34 +++++-- src/gcrypt-int.h | 2 + tests/t-mpi-point.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 304 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 01:53:32 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 07 Jun 2018 01:53:32 +0200 Subject: [git] GPGME - branch, ben/key-import, created. gpgme-1.11.1-50-g167847f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/key-import has been created at 167847f1bcfb1b573bd40fe897f39d4ee4167176 (commit) - Log ----------------------------------------------------------------- commit 167847f1bcfb1b573bd40fe897f39d4ee4167176 Author: Ben McGinnes Date: Thu Jun 7 09:46:56 2018 +1000 python bindings: import keys * Adapted from prior submissions by Tobias Mueller and Jacob Adams. * key_import function added to gpg.core.Context(). * Two example scripts added to to examples/howto: import-key-file.py imports keys from a local file and import-keys.py accesses the SKS keyserver pool using the requests module to search for keys (includes check for key IDs which may not include the leading 0x). * Added documentation demonstrating the use of the key_import() function with a large number of keys matching one domain (eff.org; the example shows how EFF staff are following their own advice issued last month). diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 3325c08..31929fa 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -454,6 +454,85 @@ literals with the fingerprint when getting a key in this way. +** Importing keys + :PROPERTIES: + :CUSTOM_ID: howto-import-key + :END: + + Importing keys is possible with the =key_import()= method and takes + one argument which is a bytes literal object containing either the + binary or ASCII armoured key data for one or more keys. + + In the following example a key will be retrieved from the SKS + keyservers via the web using the requests module. Since requests + returns the content as a bytes literal object, we can then use that + directly to import the resulting data into our keybox. In order to + demonstrate multiple imports this example searches for all the keys + of users at a particular domain name; in this case the EFF. + + #+begin_src python + import gpg + import os.path + import requests + + c = gpg.Context() + + homedir = input("Enter the GPG configuration directory path (optional): ") + pattern = input("The pattern to search for in key or user IDs: ") + url = "https://sks-keyservers.net/pks/lookup" + payload = { "op": "get", "search": pattern } + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + r = requests.get(url, verify=True, params=payload) + incoming = c.key_import(r.content) + + summary = """ + Total number of keys: {0} + Total number imported: {1} + Number of version 3 keys ignored: {2} + + Number of imported key objects or updates: {3} + Number of unchanged keys: {4} + Number of new signatures: {5} + Number of revoked keys: {6} + """.format(incoming.considered, len(incoming.imports), + incoming.skipped_v3_keys, incoming.imported, incoming.unchanged, + incoming.new_signatures, incoming.new_revocations) + + print(summary) + #+end_src + + The resulting output in that case, where the search pattern entered + was =@eff.org= was: + + #+begin_src shell + Total number of keys: 272 + Total number imported: 249 + Number of version 3 keys ignored: 23 + + Number of imported key objects or updates: 180 + Number of unchanged keys: 66 + Number of new signatures: 7 + Number of revoked keys: 0 + #+end_src + + The examples for this document in =lang/python/examples/howto/ now + include to variations of this; one for searching the SKS keyserver + pool and the other for importing from a local file. + + The example above and the corresponding executable script included + in the examples requires Kenneth Reitz's excellent [[http://docs.python-requests.org/en/master/][Requests module]]. + + * Basic Functions :PROPERTIES: :CUSTOM_ID: howto-the-basics diff --git a/lang/python/examples/howto/import-key-file.py b/lang/python/examples/howto/import-key-file.py new file mode 100755 index 0000000..26ec524 --- /dev/null +++ b/lang/python/examples/howto/import-key-file.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path + +print(""" +This script imports a key or keys matching a pattern from the SKS keyserver +pool. +""") + +c = gpg.Context() + +homedir = input("Enter the GPG configuration directory path (optional): ") +keyfile = input("Enter the path and filename to the file of key(s): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +with open(keyfile, "rb") as f: + kdata = f.read() + +incoming = c.key_import(kdata) + +summary = """ +Total number of keys: {0} +Total number imported: {1} +Number of version 3 keys ignored: {2} + +Number of imported key objects or updates: {3} +Number of unchanged keys: {4} +Number of new signatures: {5} +Number of revoked keys: {6} +""".format(incoming.considered, len(incoming.imports), + incoming.skipped_v3_keys, incoming.imported, incoming.unchanged, + incoming.new_signatures, incoming.new_revocations) + +print(summary) + +# EOF diff --git a/lang/python/examples/howto/import-keys.py b/lang/python/examples/howto/import-keys.py new file mode 100755 index 0000000..455b8e0 --- /dev/null +++ b/lang/python/examples/howto/import-keys.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import requests + +print(""" +This script imports a key or keys matching a pattern from the SKS keyserver +pool. + +Uses the requests module. +""") + +c = gpg.Context() + +homedir = input("Enter the GPG configuration directory path (optional): ") +pattern = input("The pattern to search for in key or user IDs: ") +url = "https://sks-keyservers.net/pks/lookup" +payload = { "op": "get", "search": pattern } +hexload = { "op": "get", "search": "0x{0}".format(pattern) } + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +resp = requests.get(url, verify=True, params=payload) +if resp.ok is False: + rhex = requests.get(url, verify=True, params=hexload) + incoming = c.key_import(rhex.content) +else: + incoming = c.key_import(resp.content) + +summary = """ +Total number of keys: {0} +Total number imported: {1} +Number of version 3 keys ignored: {2} + +Number of imported key objects or updates: {3} +Number of unchanged keys: {4} +Number of new signatures: {5} +Number of revoked keys: {6} +""".format(incoming.considered, len(incoming.imports), + incoming.skipped_v3_keys, incoming.imported, incoming.unchanged, + incoming.new_signatures, incoming.new_revocations) + +print(summary) + +# EOF diff --git a/lang/python/src/core.py b/lang/python/src/core.py index bd95d23..10db3d6 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -509,6 +509,28 @@ class Context(GpgmeWrapper): return results + def key_import(self, keydata): + """Importing keys + + Arguments: + keydata -- Binary or ASCII armored key(s) to be imported + + Returns + -- an object describing the results of keys imported or + updated + + Raises: + GPGMEError -- as signaled by the underlying library + """ + if keydata is not None: + try: + self.op_import(keydata) + result = self.op_import_result() + except GPGMEError as e: + result = e + else: + result = "No keys found." + def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, source=None): ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 07:11:44 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 07 Jun 2018 07:11:44 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-50-ga3a0858 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via a3a08584d6e57c4b2a40d74dc52a7d8c5c11b501 (commit) from 2c4c5692472f5870f907c2c3f01870879cb0c34b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a3a08584d6e57c4b2a40d74dc52a7d8c5c11b501 Author: Ben McGinnes Date: Thu Jun 7 15:06:20 2018 +1000 examples: python howto * Uses the groups module to prepare a list of recipients and encrypt to those. * The main version (encrypt-to-group.py) tries to check for invalid recipients, but still falls back to always trust for the second encryption attempt. * The gullible version doesn't try pruning the recipient list at all, it just tries to encrypt and if it fails, switches straight to always trust. * The trustno1 version doesn't use the always trust model at all and only attempts pruning the list of invalid recipients. diff --git a/lang/python/examples/howto/encrypt-to-group-gullible.py b/lang/python/examples/howto/encrypt-to-group-gullible.py new file mode 100755 index 0000000..7ebfb6b --- /dev/null +++ b/lang/python/examples/howto/encrypt-to-group-gullible.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys +from groups import group_lists + +""" +Uses the groups module to encrypt to multiple recipients. + +""" + +c = gpg.Context(armor=True) + +if len(sys.argv) > 3: + group_id = sys.argv[1] + filepath = sys.argv[2:] +elif len(sys.argv) == 3: + group_id = sys.argv[1] + filepath = sys.argv[2] +elif len(sys.argv) == 2: + group_id = sys.argv[1] + filepath = input("Enter the filename to encrypt: ") +else: + group_id = input("Enter the group name to encrypt to: ") + filepath = input("Enter the filename to encrypt: ") + +with open(filepath, "rb") as f: + text = f.read() + +for i in range(len(group_lists)): + if group_lists[i][0] == group_id: + klist = group_lists[i][1] + else: + klist = None + +logrus = [] + +if klist is not None: + for i in range(len(klist)): + apattern = list(c.keylist(pattern=klist[i], secret=False)) + if apattern[0].can_encrypt == 1: + logrus.append(apattern[0]) + else: + pass + try: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True) + except: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True, + always_trust=True) + with open("{0}.asc".format(filepath), "wb") as f: + f.write(ciphertext) +else: + pass + +# EOF diff --git a/lang/python/examples/howto/encrypt-to-group-trustno1.py b/lang/python/examples/howto/encrypt-to-group-trustno1.py new file mode 100755 index 0000000..736c5f1 --- /dev/null +++ b/lang/python/examples/howto/encrypt-to-group-trustno1.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys +from groups import group_lists + +""" +Uses the groups module to encrypt to multiple recipients. + +""" + +c = gpg.Context(armor=True) + +if len(sys.argv) > 3: + group_id = sys.argv[1] + filepath = sys.argv[2:] +elif len(sys.argv) == 3: + group_id = sys.argv[1] + filepath = sys.argv[2] +elif len(sys.argv) == 2: + group_id = sys.argv[1] + filepath = input("Enter the filename to encrypt: ") +else: + group_id = input("Enter the group name to encrypt to: ") + filepath = input("Enter the filename to encrypt: ") + +with open(filepath, "rb") as f: + text = f.read() + +for i in range(len(group_lists)): + if group_lists[i][0] == group_id: + klist = group_lists[i][1] + else: + klist = None + +logrus = [] + +if klist is not None: + for i in range(len(klist)): + apattern = list(c.keylist(pattern=klist[i], secret=False)) + if apattern[0].can_encrypt == 1: + logrus.append(apattern[0]) + else: + pass + try: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True) + except gpg.errors.InvalidRecipients as e: + for i in range(len(e.recipients)): + for n in range(len(logrus)): + if logrus[n].fpr == e.recipients[i].fpr: + logrus.remove(logrus[n]) + else: + pass + try: + ciphertext, result, sign_result = c.encrypt(text, + recipients=logrus, + add_encrypt_to=True) + except: + pass + with open("{0}.asc".format(filepath), "wb") as f: + f.write(ciphertext) +else: + pass + +# EOF diff --git a/lang/python/examples/howto/encrypt-to-group.py b/lang/python/examples/howto/encrypt-to-group.py new file mode 100755 index 0000000..84f8d10 --- /dev/null +++ b/lang/python/examples/howto/encrypt-to-group.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import sys +from groups import group_lists + +""" +Uses the groups module to encrypt to multiple recipients. + +""" + +c = gpg.Context(armor=True) + +if len(sys.argv) > 3: + group_id = sys.argv[1] + filepath = sys.argv[2:] +elif len(sys.argv) == 3: + group_id = sys.argv[1] + filepath = sys.argv[2] +elif len(sys.argv) == 2: + group_id = sys.argv[1] + filepath = input("Enter the filename to encrypt: ") +else: + group_id = input("Enter the group name to encrypt to: ") + filepath = input("Enter the filename to encrypt: ") + +with open(filepath, "rb") as f: + text = f.read() + +for i in range(len(group_lists)): + if group_lists[i][0] == group_id: + klist = group_lists[i][1] + else: + klist = None + +logrus = [] + +if klist is not None: + for i in range(len(klist)): + apattern = list(c.keylist(pattern=klist[i], secret=False)) + if apattern[0].can_encrypt == 1: + logrus.append(apattern[0]) + else: + pass + try: + ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, + add_encrypt_to=True) + except gpg.errors.InvalidRecipients as e: + for i in range(len(e.recipients)): + for n in range(len(logrus)): + if logrus[n].fpr == e.recipients[i].fpr: + logrus.remove(logrus[n]) + else: + pass + try: + ciphertext, result, sign_result = c.encrypt(text, + recipients=logrus, + add_encrypt_to=True, + always_trust=True) + except: + pass + with open("{0}.asc".format(filepath), "wb") as f: + f.write(ciphertext) +else: + pass + +# EOF ----------------------------------------------------------------------- Summary of changes: .../examples/howto/encrypt-to-group-gullible.py | 81 +++++++++++++++++++ .../examples/howto/encrypt-to-group-trustno1.py | 90 +++++++++++++++++++++ lang/python/examples/howto/encrypt-to-group.py | 91 ++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100755 lang/python/examples/howto/encrypt-to-group-gullible.py create mode 100755 lang/python/examples/howto/encrypt-to-group-trustno1.py create mode 100755 lang/python/examples/howto/encrypt-to-group.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 11:45:41 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jun 2018 11:45:41 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-52-g906ea48 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 906ea48df3e178bea3e2c744ddd834b23fe553fb (commit) via 7e18c7a07a1e2c58ef4d5ddeed46bcce098bdf6c (commit) from a3a08584d6e57c4b2a40d74dc52a7d8c5c11b501 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 906ea48df3e178bea3e2c744ddd834b23fe553fb Author: Andre Heinecke Date: Thu Jun 7 11:42:47 2018 +0200 json: Add direct way to query a config option * src/gpgme-json.c (op_config_opt, hlp_config_opt): New operation. (process_request, hlp_help): Add it. -- This is more conveniant API for most query operations where a single option is required. An example would be: { "op": "config_opt", "component": "gpg", "option": "default-key" } Which results in: { "option": { "name": "default-key", "description": "use NAME as default secret key", "argname": "NAME", "flags": 0, "level": 0, "type": 1, "alt_type": 1, "value": [{ "string": "F462B6B1", "is_none": false }] } } diff --git a/src/gpgme-json.c b/src/gpgme-json.c index de62dcc..1199ca2 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -2460,6 +2460,102 @@ leave: } +static const char hlp_config_opt[] = + "op: \"config_opt\"\n" + "component: The component of the option.\n" + "option: The name of the option.\n" + "\n" + "Response on success:\n" + "\n" + "option: Information about the option.\n" + " String values:\n" + " name: The name of the option\n" + " description: Localized description of the opt.\n" + " argname: Thhe argument name e.g. --verbose\n" + " default_description\n" + " no_arg_description\n" + " Number values:\n" + " flags: Flags for this option.\n" + " level: the level of the description. See gpgme_conf_level_t.\n" + " type: The type of the option. See gpgme_conf_type_t.\n" + " alt_type: Alternate type of the option. See gpgme_conf_type_t\n" + " Arg type values: (see desc. below)\n" + " default_value: Array of the default value.\n" + " no_arg_value: Array of the value if it is not set.\n" + " value: Array for the current value if the option is set.\n" + "\n" + "If the response is empty the option was not found\n" + ""; +static gpg_error_t +op_config_opt (cjson_t request, cjson_t result) +{ + gpg_error_t err; + gpgme_ctx_t ctx = NULL; + gpgme_conf_comp_t conf = NULL; + gpgme_conf_comp_t comp = NULL; + cjson_t j_tmp; + char *comp_name = NULL; + char *opt_name = NULL; + + ctx = get_context (GPGME_PROTOCOL_GPGCONF); + + j_tmp = cJSON_GetObjectItem (request, "component"); + if (!j_tmp || !cjson_is_string (j_tmp)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + comp_name = j_tmp->valuestring; + + + j_tmp = cJSON_GetObjectItem (request, "option"); + if (!j_tmp || !cjson_is_string (j_tmp)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + opt_name = j_tmp->valuestring; + + /* Load the config */ + err = gpgme_op_conf_load (ctx, &conf); + if (err) + { + goto leave; + } + + comp = conf; + for (comp = conf; comp; comp = comp->next) + { + gpgme_conf_opt_t opt = NULL; + int found = 0; + if (!comp->name || strcmp (comp->name, comp_name)) + { + /* Skip components if a single one is specified */ + continue; + } + for (opt = comp->options; opt; opt = opt->next) + { + if (!opt->name || strcmp (opt->name, opt_name)) + { + /* Skip components if a single one is specified */ + continue; + } + xjson_AddItemToObject (result, "option", conf_opt_to_json (opt)); + found = 1; + break; + } + if (found) + break; + } + +leave: + gpgme_conf_release (conf); + release_context (ctx); + + return err; +} + + static const char hlp_config[] = "op: \"config\"\n" "\n" @@ -2688,18 +2784,19 @@ process_request (const char *request) gpg_error_t (*handler)(cjson_t request, cjson_t result); const char * const helpstr; } optbl[] = { - { "config", op_config, hlp_config }, - { "encrypt", op_encrypt, hlp_encrypt }, - { "export", op_export, hlp_export }, - { "decrypt", op_decrypt, hlp_decrypt }, - { "delete", op_delete, hlp_delete }, - { "keylist", op_keylist, hlp_keylist }, - { "import", op_import, hlp_import }, - { "sign", op_sign, hlp_sign }, - { "verify", op_verify, hlp_verify }, - { "version", op_version, hlp_version }, - { "getmore", op_getmore, hlp_getmore }, - { "help", op_help, hlp_help }, + { "config", op_config, hlp_config }, + { "config_opt", op_config_opt, hlp_config_opt }, + { "encrypt", op_encrypt, hlp_encrypt }, + { "export", op_export, hlp_export }, + { "decrypt", op_decrypt, hlp_decrypt }, + { "delete", op_delete, hlp_delete }, + { "keylist", op_keylist, hlp_keylist }, + { "import", op_import, hlp_import }, + { "sign", op_sign, hlp_sign }, + { "verify", op_verify, hlp_verify }, + { "version", op_version, hlp_version }, + { "getmore", op_getmore, hlp_getmore }, + { "help", op_help, hlp_help }, { NULL } }; size_t erroff; commit 7e18c7a07a1e2c58ef4d5ddeed46bcce098bdf6c Author: Andre Heinecke Date: Thu Jun 7 11:23:14 2018 +0200 json: Add op_config to query gpgconf * src/gpgme-json.c (op_config, hlp_config): New. (hlp_help, process_request): Add config. (conf_arg_to_json, conf_opt_to_json, conf_comp_to_json): New helpers. diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 56b4bc1..de62dcc 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -565,7 +565,7 @@ _create_new_context (gpgme_protocol_t proto) static gpgme_ctx_t get_context (gpgme_protocol_t proto) { - static gpgme_ctx_t ctx_openpgp, ctx_cms; + static gpgme_ctx_t ctx_openpgp, ctx_cms, ctx_conf; if (proto == GPGME_PROTOCOL_OpenPGP) { @@ -579,6 +579,12 @@ get_context (gpgme_protocol_t proto) ctx_cms = _create_new_context (proto); return ctx_cms; } + else if (proto == GPGME_PROTOCOL_GPGCONF) + { + if (!ctx_conf) + ctx_conf = _create_new_context (proto); + return ctx_conf; + } else log_bug ("invalid protocol %d requested\n", proto); } @@ -1115,6 +1121,119 @@ import_result_to_json (gpgme_import_result_t imp) } +/* Create a JSON object from a gpgconf arg */ +static cjson_t +conf_arg_to_json (gpgme_conf_arg_t arg, gpgme_conf_type_t type) +{ + cjson_t result = xjson_CreateObject (); + int is_none = 0; + switch (type) + { + case GPGME_CONF_STRING: + case GPGME_CONF_PATHNAME: + case GPGME_CONF_LDAP_SERVER: + case GPGME_CONF_KEY_FPR: + case GPGME_CONF_PUB_KEY: + case GPGME_CONF_SEC_KEY: + case GPGME_CONF_ALIAS_LIST: + xjson_AddStringToObject0 (result, "string", arg->value.string); + break; + + case GPGME_CONF_UINT32: + xjson_AddNumberToObject (result, "number", arg->value.uint32); + break; + + case GPGME_CONF_INT32: + xjson_AddNumberToObject (result, "number", arg->value.int32); + break; + + case GPGME_CONF_NONE: + default: + is_none = 1; + break; + } + xjson_AddBoolToObject (result, "is_none", is_none); + return result; +} + + +/* Create a JSON object from a gpgconf option */ +static cjson_t +conf_opt_to_json (gpgme_conf_opt_t opt) +{ + cjson_t result = xjson_CreateObject (); + + xjson_AddStringToObject0 (result, "name", opt->name); + xjson_AddStringToObject0 (result, "description", opt->description); + xjson_AddStringToObject0 (result, "argname", opt->argname); + xjson_AddStringToObject0 (result, "default_description", + opt->default_description); + xjson_AddStringToObject0 (result, "no_arg_description", + opt->no_arg_description); + + xjson_AddNumberToObject (result, "flags", opt->flags); + xjson_AddNumberToObject (result, "level", opt->level); + xjson_AddNumberToObject (result, "type", opt->type); + xjson_AddNumberToObject (result, "alt_type", opt->alt_type); + + if (opt->default_value) + { + cjson_t array = xjson_CreateArray (); + gpgme_conf_arg_t arg; + + for (arg = opt->default_value; arg; arg = arg->next) + cJSON_AddItemToArray (array, conf_arg_to_json (arg, opt->alt_type)); + xjson_AddItemToObject (result, "default_value", array); + } + + if (opt->no_arg_value) + { + cjson_t array = xjson_CreateArray (); + gpgme_conf_arg_t arg; + + for (arg = opt->no_arg_value; arg; arg = arg->next) + cJSON_AddItemToArray (array, conf_arg_to_json (arg, opt->alt_type)); + xjson_AddItemToObject (result, "no_arg_value", array); + } + + if (opt->value) + { + cjson_t array = xjson_CreateArray (); + gpgme_conf_arg_t arg; + + for (arg = opt->value; arg; arg = arg->next) + cJSON_AddItemToArray (array, conf_arg_to_json (arg, opt->alt_type)); + xjson_AddItemToObject (result, "value", array); + } + return result; +} + + +/* Create a JSON object from a gpgconf component*/ +static cjson_t +conf_comp_to_json (gpgme_conf_comp_t cmp) +{ + cjson_t result = xjson_CreateObject (); + + xjson_AddStringToObject0 (result, "name", cmp->name); + xjson_AddStringToObject0 (result, "description", cmp->description); + xjson_AddStringToObject0 (result, "program_name", cmp->program_name); + + + if (cmp->options) + { + cjson_t array = xjson_CreateArray (); + gpgme_conf_opt_t opt; + + for (opt = cmp->options; opt; opt = opt->next) + cJSON_AddItemToArray (array, conf_opt_to_json (opt)); + xjson_AddItemToObject (result, "options", array); + } + + return result; +} + + /* Create a gpgme_data from json string data named "name" * in the request. Takes the base64 option into account. * @@ -2341,6 +2460,91 @@ leave: } +static const char hlp_config[] = + "op: \"config\"\n" + "\n" + "Optional parameters:\n" + "component: Component of entries to list.\n" + " Default: all\n" + "\n" + "Response on success:\n" + " components: Array of the component program configs.\n" + " name: The component name.\n" + " description: Description of the component.\n" + " program_name: The absolute path to the program.\n" + " options: Array of config options\n" + " String values:\n" + " name: The name of the option\n" + " description: Localized description of the opt.\n" + " argname: Thhe argument name e.g. --verbose\n" + " default_description\n" + " no_arg_description\n" + " Number values:\n" + " flags: Flags for this option.\n" + " level: the level of the description. See gpgme_conf_level_t.\n" + " type: The type of the option. See gpgme_conf_type_t.\n" + " alt_type: Alternate type of the option. See gpgme_conf_type_t\n" + " Arg type values: (see desc. below)\n" + " default_value: Array of the default value.\n" + " no_arg_value: Array of the value if it is not set.\n" + " value: Array for the current value if the option is set.\n" + "\n" + "Conf type values are an array of values that are either\n" + "of type number named \"number\" or of type string,\n" + "named \"string\".\n" + "If the type is none the bool value is_none is true.\n" + ""; +static gpg_error_t +op_config (cjson_t request, cjson_t result) +{ + gpg_error_t err; + gpgme_ctx_t ctx = NULL; + gpgme_conf_comp_t conf = NULL; + gpgme_conf_comp_t comp = NULL; + cjson_t j_tmp; + char *comp_name = NULL; + cjson_t j_comps = xjson_CreateArray (); + + ctx = get_context (GPGME_PROTOCOL_GPGCONF); + + j_tmp = cJSON_GetObjectItem (request, "component"); + if (j_tmp && cjson_is_string (j_tmp)) + { + comp_name = j_tmp->valuestring; + } + else if (j_tmp && !cjson_is_string (j_tmp)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + + /* Load the config */ + err = gpgme_op_conf_load (ctx, &conf); + if (err) + { + goto leave; + } + + comp = conf; + for (comp = conf; comp; comp = comp->next) + { + if (comp_name && comp->name && strcmp (comp->name, comp_name)) + { + /* Skip components if a single one is specified */ + continue; + } + cJSON_AddItemToArray (j_comps, conf_comp_to_json (comp)); + } + xjson_AddItemToObject (result, "components", j_comps); + +leave: + gpgme_conf_release (conf); + release_context (ctx); + + return err; +} + + static const char hlp_getmore[] = "op: \"getmore\"\n" @@ -2436,6 +2640,7 @@ static const char hlp_help[] = "operation is not performned but a string with the documentation\n" "returned. To list all operations it is allowed to leave out \"op\" in\n" "help mode. Supported values for \"op\" are:\n\n" + " config Read configuration values.\n" " decrypt Decrypt data.\n" " delete Delete a key.\n" " encrypt Encrypt data.\n" @@ -2483,6 +2688,7 @@ process_request (const char *request) gpg_error_t (*handler)(cjson_t request, cjson_t result); const char * const helpstr; } optbl[] = { + { "config", op_config, hlp_config }, { "encrypt", op_encrypt, hlp_encrypt }, { "export", op_export, hlp_export }, { "decrypt", op_decrypt, hlp_decrypt }, ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 315 insertions(+), 12 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 16:08:06 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jun 2018 16:08:06 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-53-ge48f4a1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via e48f4a18f807ee42b31968b84f6ae7811d8d8a45 (commit) from 906ea48df3e178bea3e2c744ddd834b23fe553fb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e48f4a18f807ee42b31968b84f6ae7811d8d8a45 Author: Andre Heinecke Date: Thu Jun 7 16:05:15 2018 +0200 json: Rework verify_result_to_json * src/gpgme-json.c (sigsum_to_json): Add bool repr. (signature_to_json, verify_result_to_json): Extend and follow better pattern. (hlp_decrypt, hlp_verify): Expand doc. -- This should make it more clear which values are mapped as the naming is more direct and clear and help to use the gpgme documentation to understand the verify_result values. diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 1199ca2..d3309b8 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -726,41 +726,68 @@ create_keylist_patterns (cjson_t request, const char *name) static cjson_t sigsum_to_json (gpgme_sigsum_t summary) { - cjson_t result = xjson_CreateArray (); + cjson_t result = xjson_CreateObject (); + cjson_t sigsum_array = xjson_CreateArray (); if ( (summary & GPGME_SIGSUM_VALID )) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("valid")); if ( (summary & GPGME_SIGSUM_GREEN )) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("green")); if ( (summary & GPGME_SIGSUM_RED )) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("red")); if ( (summary & GPGME_SIGSUM_KEY_REVOKED)) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("revoked")); if ( (summary & GPGME_SIGSUM_KEY_EXPIRED)) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("key-expired")); if ( (summary & GPGME_SIGSUM_SIG_EXPIRED)) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("sig-expired")); if ( (summary & GPGME_SIGSUM_KEY_MISSING)) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("key-missing")); if ( (summary & GPGME_SIGSUM_CRL_MISSING)) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("crl-missing")); if ( (summary & GPGME_SIGSUM_CRL_TOO_OLD)) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("crl-too-old")); if ( (summary & GPGME_SIGSUM_BAD_POLICY )) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("bad-policy")); if ( (summary & GPGME_SIGSUM_SYS_ERROR )) - cJSON_AddItemToArray (result, + cJSON_AddItemToArray (sigsum_array, cJSON_CreateString ("sys-error")); + /* The signature summary as string array. */ + xjson_AddItemToObject (result, "sigsum", sigsum_array); + + /* Bools for the same. */ + xjson_AddBoolToObject (result, "valid", + (summary & GPGME_SIGSUM_VALID )); + xjson_AddBoolToObject (result, "green", + (summary & GPGME_SIGSUM_GREEN )); + xjson_AddBoolToObject (result, "red", + (summary & GPGME_SIGSUM_RED )); + xjson_AddBoolToObject (result, "revoked", + (summary & GPGME_SIGSUM_KEY_REVOKED)); + xjson_AddBoolToObject (result, "key-expired", + (summary & GPGME_SIGSUM_KEY_EXPIRED)); + xjson_AddBoolToObject (result, "sig-expired", + (summary & GPGME_SIGSUM_SIG_EXPIRED)); + xjson_AddBoolToObject (result, "key-missing", + (summary & GPGME_SIGSUM_KEY_MISSING)); + xjson_AddBoolToObject (result, "crl-missing", + (summary & GPGME_SIGSUM_CRL_MISSING)); + xjson_AddBoolToObject (result, "crl-too-old", + (summary & GPGME_SIGSUM_CRL_TOO_OLD)); + xjson_AddBoolToObject (result, "bad-policy", + (summary & GPGME_SIGSUM_BAD_POLICY )); + xjson_AddBoolToObject (result, "sys-error", + (summary & GPGME_SIGSUM_SYS_ERROR )); return result; } @@ -1014,18 +1041,38 @@ signature_to_json (gpgme_signature_t sig) { cjson_t result = xjson_CreateObject (); - xjson_AddStringToObject0 (result, "status", - gpgme_strerror (sig->status)); + xjson_AddItemToObject (result, "summary", sigsum_to_json (sig->summary)); - xjson_AddStringToObject0 (result, "validity", - validity_to_string (sig->validity)); + xjson_AddBoolToObject (result, "wrong_key_usage", sig->wrong_key_usage); + xjson_AddBoolToObject (result, "chain_model", sig->chain_model); + xjson_AddBoolToObject (result, "is_de_vs", sig->is_de_vs); + + xjson_AddStringToObject0 (result, "status_string", + gpgme_strerror (sig->status)); xjson_AddStringToObject0 (result, "fingerprint", sig->fpr); + xjson_AddStringToObject0 (result, "validity_string", + validity_to_string (sig->validity)); + xjson_AddStringToObject0 (result, "pubkey_algo_name", + gpgme_pubkey_algo_name (sig->pubkey_algo)); + xjson_AddStringToObject0 (result, "hash_algo_name", + gpgme_hash_algo_name (sig->hash_algo)); + xjson_AddStringToObject0 (result, "pka_address", sig->pka_address); - xjson_AddItemToObject (result, "summary", sigsum_to_json (sig->summary)); + xjson_AddNumberToObject (result, "status_code", sig->status); + xjson_AddNumberToObject (result, "timestamp", sig->timestamp); + xjson_AddNumberToObject (result, "exp_timestamp", sig->exp_timestamp); + xjson_AddNumberToObject (result, "pka_trust", sig->pka_trust); + xjson_AddNumberToObject (result, "validity", sig->validity); + xjson_AddNumberToObject (result, "validity_reason", sig->validity_reason); - xjson_AddNumberToObject (result, "created", sig->timestamp); - xjson_AddNumberToObject (result, "expired", sig->exp_timestamp); - xjson_AddNumberToObject (result, "code", sig->status); + if (sig->notations) + { + gpgme_sig_notation_t not; + cjson_t array = xjson_CreateArray (); + for (not = sig->notations; not; not = not->next) + cJSON_AddItemToArray (array, sig_notation_to_json (not)); + xjson_AddItemToObject (result, "notations", array); + } return result; } @@ -1035,7 +1082,10 @@ signature_to_json (gpgme_signature_t sig) static cjson_t verify_result_to_json (gpgme_verify_result_t verify_result) { - cjson_t response = xjson_CreateObject (); + cjson_t result = xjson_CreateObject (); + + xjson_AddStringToObject0 (result, "file_name", verify_result->file_name); + xjson_AddBoolToObject (result, "is_mime", verify_result->is_mime); if (verify_result->signatures) { @@ -1044,10 +1094,10 @@ verify_result_to_json (gpgme_verify_result_t verify_result) for (sig = verify_result->signatures; sig; sig = sig->next) cJSON_AddItemToArray (array, signature_to_json (sig)); - xjson_AddItemToObject (response, "signatures", array); + xjson_AddItemToObject (result, "signatures", array); } - return response; + return result; } @@ -1583,17 +1633,52 @@ static const char hlp_decrypt[] = "data: The decrypted data. This may be base64 encoded.\n" "base64: Boolean indicating whether data is base64 encoded.\n" "mime: A Boolean indicating whether the data is a MIME object.\n" - "info: An object with optional signature information.\n" + "info: An object with verification information. (gpgme_verify_result_t)\n" + " file_name: Optional string of the plaintext file name.\n" + " is_mime: Boolean that is true if the messages claims it is MIME.\n" + " signatures: Array of signatures\n" + " summary: Object containing summary information.\n" + " Boolean values: (Check gpgme_sigsum_t doc for meaning)\n" + " valid\n" + " green\n" + " red\n" + " revoked\n" + " key-expired\n" + " sig-expired\n" + " key-missing\n" + " crl-missing\n" + " crl-too-old\n" + " bad-policy\n" + " sys-error\n" + " sigsum: Array of strings representing the sigsum.\n" + " Boolean values:\n" + " wrong_key_usage: Key should not have been used for signing.\n" + " chain_model: Validity has been verified using the chain model.\n" + " is_de_vs: signature is in compliance to the de-vs mode.\n" + " String values:\n" + " status_string: The status code as localized gpg-error string\n" + " fingerprint: The fingerprint of the signing key.\n" + " validity_string: The validity as string.\n" + " pubkey_algo_name: gpgme_pubkey_algo_name of used algo.\n" + " hash_algo_name: gpgme_hash_algo_name of used hash algo\n" + " pka_address: The mailbox from the PKA information.\n" + " Number values:\n" + " status_code: The status as a number. (gpg_error_t)\n" + " timestamp: Signature creation time. (secs since epoch)\n" + " exp_timestamp: Signature expiration or 0. (secs since epoch)\n" + " pka_trust: PKA status: 0 = not available, 1 = bad, 2 = okay, 3 = RFU.\n" + " validity: validity as number (gpgme_validity_t)\n" + " validity_reason: (gpg_error_t)\n" " Array values:\n" - " signatures\n" + " notations: Notation data and policy urls (gpgme_sig_notation_t)\n" + " Boolean values:\n" + " human_readable\n" + " critical\n" " String values:\n" - " status: The status of the signature.\n" - " fingerprint: The fingerprint of the signing key.\n" - " validity: The validity as string.\n" + " name\n" + " value\n" " Number values:\n" - " code: The status as a number.\n" - " Array values:\n" - " summary: A string array of the sig summary.\n" + " flags\n" "more: Optional boolean indicating that \"getmore\" is required."; static gpg_error_t op_decrypt (cjson_t request, cjson_t result) @@ -1829,17 +1914,52 @@ static const char hlp_verify[] = "type: \"plaintext\"\n" "data: The verified data. This may be base64 encoded.\n" "base64: Boolean indicating whether data is base64 encoded.\n" - "info: An object with signature information.\n" + "info: An object with verification information (gpgme_verify_result_t).\n" + " file_name: Optional string of the plaintext file name.\n" + " is_mime: Boolean that is true if the messages claims it is MIME.\n" + " signatures: Array of signatures\n" + " summary: Object containing summary information.\n" + " Boolean values: (Check gpgme_sigsum_t doc for meaning)\n" + " valid\n" + " green\n" + " red\n" + " revoked\n" + " key-expired\n" + " sig-expired\n" + " key-missing\n" + " crl-missing\n" + " crl-too-old\n" + " bad-policy\n" + " sys-error\n" + " sigsum: Array of strings representing the sigsum.\n" + " Boolean values:\n" + " wrong_key_usage: Key should not have been used for signing.\n" + " chain_model: Validity has been verified using the chain model.\n" + " is_de_vs: signature is in compliance to the de-vs mode.\n" + " String values:\n" + " status_string: The status code as localized gpg-error string\n" + " fingerprint: The fingerprint of the signing key.\n" + " validity_string: The validity as string.\n" + " pubkey_algo_name: gpgme_pubkey_algo_name of used algo.\n" + " hash_algo_name: gpgme_hash_algo_name of used hash algo\n" + " pka_address: The mailbox from the PKA information.\n" + " Number values:\n" + " status_code: The status as a number. (gpg_error_t)\n" + " timestamp: Signature creation time. (secs since epoch)\n" + " exp_timestamp: Signature expiration or 0. (secs since epoch)\n" + " pka_trust: PKA status: 0 = not available, 1 = bad, 2 = okay, 3 = RFU.\n" + " validity: validity as number (gpgme_validity_t)\n" + " validity_reason: (gpg_error_t)\n" " Array values:\n" - " signatures\n" + " notations: Notation data and policy urls (gpgme_sig_notation_t)\n" + " Boolean values:\n" + " human_readable\n" + " critical\n" " String values:\n" - " status: The status of the signature.\n" - " fingerprint: The fingerprint of the signing key.\n" - " validity: The validity as string.\n" + " name\n" + " value\n" " Number values:\n" - " code: The status as a number.\n" - " Array values:\n" - " summary: A string array of the sig summary.\n" + " flags\n" "more: Optional boolean indicating that \"getmore\" is required."; static gpg_error_t op_verify (cjson_t request, cjson_t result) ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 198 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 159 insertions(+), 39 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 17:31:23 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Jun 2018 17:31:23 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-142-g26bce2f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 26bce2f01d2029ea2b8a8dbbe36118e3c83c5cba (commit) via 1bc6b5174248ba4d83d648ef6d6f4550540d1f20 (commit) from 7ffc1ac7dd95d4cc1897a4c36d5cd628741c12f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 26bce2f01d2029ea2b8a8dbbe36118e3c83c5cba Author: Werner Koch Date: Thu Jun 7 17:22:58 2018 +0200 gpg: Fix import's repair-key duplicate signature detection. * g10/packet.h (PKG_siganture): Add field 'help_counter'. * g10/key-check.c (sig_comparison): Take care of HELP_COUNTER. (key_check_all_keysigs): De-duplicate on a per-block base. -- The key_check_all_keysigs first does a detection of duplicate signature. This is done over all signatures at once. The problem here is for example: key uid_1 sig_uid_1.1 sig_uid_1.2 subkey_1 sig_sub_1.1 subkey_2 sig_sub_2.1 sig_sub_2.2 (duplicate of sig_sub_1.1) Now the de-duplication deletes the first signature and keeps the second. That works in most cases for foreign signature on userids but in the above constellation the code simply removes sig_sub_1.1 so that subkey_1 has no binding signature anymore. In a later step during import the missing binding is detected and subkey_1 is removed because it is not anymore valid. The sig_sub_2.2 will also be removed later because it does not check out for subkey_2 (that is as expected). The fix is to let the de-duplication work only on blocks (ie. within the signatures of a user id or a subkey). This will not detect all duplicates but that does not harm because later steps will detect and remove them. In the above case (with this patch applied) the second phase of key_check_all_keysigs will reorder key signatures and move the duplicate sig_sub_2.2 directly after sig_sub_1.1. This duplicates the signature and for cleanness we should kick the de-duplication process again. This will be done with a followup patch. GnuPG-bug-id: 3994 Signed-off-by: Werner Koch diff --git a/g10/key-check.c b/g10/key-check.c index 86b1e76..17f2dae 100644 --- a/g10/key-check.c +++ b/g10/key-check.c @@ -72,6 +72,13 @@ sig_comparison (const void *av, const void *bv) a = an->pkt->pkt.signature; b = bn->pkt->pkt.signature; + /* Signatures with a different help counter are not identical for + * our purpose. */ + if (a->help_counter < b->help_counter) + return -1; + if (a->help_counter > b->help_counter) + return 1; + if (a->digest_algo < b->digest_algo) return -1; if (a->digest_algo > b->digest_algo) @@ -133,6 +140,7 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, int bad_signature = 0; int missing_selfsig = 0; int modified = 0; + PKT_signature *sig; log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY); pk = kb->pkt->pkt.public_key; @@ -143,6 +151,7 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, kbnode_t *sigs; int i; int last_i; + int block; /* Count the sigs. */ for (nsigs = 0, n = kb; n; n = n->next) @@ -166,14 +175,31 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, } i = 0; + block = 0; for (n = kb; n; n = n->next) { if (is_deleted_kbnode (n)) continue; if (n->pkt->pkttype != PKT_SIGNATURE) - continue; - + { + switch (n->pkt->pkttype) + { + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_SUBKEY: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + /* Bump the block number so that we only consider + * signatures below the same object as duplicates. */ + block++; + break; + default: + break; + } + continue; + } + sig = n->pkt->pkt.signature; + sig->help_counter = block; sigs[i] = n; i ++; } @@ -194,7 +220,7 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, { if (DBG_PACKET) { - PKT_signature *sig = sigs[i]->pkt->pkt.signature; + sig = sigs[i]->pkt->pkt.signature; log_debug ("Signature appears multiple times, " "deleting duplicate:\n"); @@ -244,7 +270,6 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, { PACKET *p; int processed_current_component; - PKT_signature *sig; int rc; int dump_sig_params = 0; @@ -577,7 +602,6 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, { int has_selfsig = 0; PACKET *p; - PKT_signature *sig; current_component = NULL; for (n = kb; n; n = n->next) diff --git a/g10/packet.h b/g10/packet.h index e8397ea..40a8c4b 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -234,6 +234,7 @@ typedef struct const byte *trust_regexp; struct revocation_key *revkey; int numrevkeys; + int help_counter; /* Used internally bu some fucntions. */ pka_info_t *pka_info; /* Malloced PKA data or NULL if not available. See also flags.pka_tried. */ char *signers_uid; /* Malloced value of the SIGNERS_UID commit 1bc6b5174248ba4d83d648ef6d6f4550540d1f20 Author: Werner Koch Date: Thu Jun 7 10:30:07 2018 +0200 gpg: Improve verbose output during import. * g10/import.c (chk_self_sigs): Print the subkeyid in addition to the keyid. (delete_inv_parts): Ditto. Signed-off-by: Werner Koch diff --git a/g10/import.c b/g10/import.c index d35c720..1a98e2a 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2750,8 +2750,9 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) } -/* Loop over the keyblock and check all self signatures. On return - * the following bis in the node flags are set: +/* Loop over the KEYBLOCK and check all self signatures. KEYID is the + * keyid of the primary key for reporting purposes. On return the + * following bits in the node flags are set: * * - NODE_GOOD_SELFSIG :: User ID or subkey has a self-signature * - NODE_BAD_SELFSIG :: Used ID or subkey has an invalid self-signature @@ -2766,17 +2767,22 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) { - kbnode_t n, knode = NULL; + kbnode_t knode = NULL; /* The node of the current subkey. */ + PKT_public_key *subpk = NULL; /* and its packet. */ + kbnode_t bsnode = NULL; /* Subkey binding signature node. */ + u32 bsdate = 0; /* Timestamp of that node. */ + kbnode_t rsnode = NULL; /* Subkey recocation signature node. */ + u32 rsdate = 0; /* Timestamp of tha node. */ PKT_signature *sig; int rc; - u32 bsdate=0, rsdate=0; - kbnode_t bsnode = NULL, rsnode = NULL; + kbnode_t n; for (n=keyblock; (n = find_next_kbnode (n, 0)); ) { if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) { knode = n; + subpk = knode->pkt->pkt.public_key; bsdate = 0; rsdate = 0; bsnode = NULL; @@ -2865,11 +2871,14 @@ chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) if ( rc ) { if (opt.verbose) - log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %s: unsupported public key" - " algorithm\n"): - _("key %s: invalid subkey binding\n"), - keystr (keyid)); + { + keyid_from_pk (subpk, NULL); + log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key" + " algorithm\n"): + _("key %s: invalid subkey binding\n"), + keystr_with_sub (keyid, subpk->keyid)); + } n->flag |= NODE_DELETION_MARK; } else @@ -2884,8 +2893,12 @@ chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) one is newer */ bsnode->flag |= NODE_DELETION_MARK; if (opt.verbose) - log_info (_("key %s: removed multiple subkey" - " binding\n"),keystr(keyid)); + { + keyid_from_pk (subpk, NULL); + log_info (_("key %s: removed multiple subkey" + " binding\n"), + keystr_with_sub (keyid, subpk->keyid)); + } } bsnode = n; @@ -2964,6 +2977,7 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, { kbnode_t node; int nvalid=0, uid_seen=0, subkey_seen=0; + PKT_public_key *pk; for (node=keyblock->next; node; node = node->next ) { @@ -3001,7 +3015,12 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, || !(node->flag & NODE_GOOD_SELFSIG)) { if (opt.verbose ) - log_info( _("key %s: skipped subkey\n"),keystr(keyid)); + { + pk = node->pkt->pkt.public_key; + keyid_from_pk (pk, NULL); + log_info (_("key %s: skipped subkey\n"), + keystr_with_sub (keyid, pk->keyid)); + } delete_kbnode( node ); /* the subkey */ /* and all following signature packets */ ----------------------------------------------------------------------- Summary of changes: g10/import.c | 45 ++++++++++++++++++++++++++++++++------------- g10/key-check.c | 34 +++++++++++++++++++++++++++++----- g10/packet.h | 1 + 3 files changed, 62 insertions(+), 18 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 18:49:44 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Jun 2018 18:49:44 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-143-g26746fe Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 26746fe65d14a00773473c2d0d271406a5105bca (commit) from 26bce2f01d2029ea2b8a8dbbe36118e3c83c5cba (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 26746fe65d14a00773473c2d0d271406a5105bca Author: Werner Koch Date: Thu Jun 7 18:41:17 2018 +0200 gpg: Improve import's repair-key duplicate signature detection. * g10/key-check.c (key_check_all_keysigs): Factor some code out to ... (remove_duplicate_sigs): new. (key_check_all_keysigs): Call remove_duplicate_sigs again after reordering. -- This is a follupup for commit 26bce2f01d2029ea2b8a8dbbe36118e3c83c5cba to cleanup the code and to add a second de-duplicate step when needed. GnuPG-bug-id: 3994 Signed-off-by: Werner Koch diff --git a/g10/key-check.c b/g10/key-check.c index 17f2dae..c17b12c 100644 --- a/g10/key-check.c +++ b/g10/key-check.c @@ -1,7 +1,7 @@ /* key-check.c - Detect and fix various problems with keys * Copyright (C) 1998-2010 Free Software Foundation, Inc. * Copyright (C) 1998-2017 Werner Koch - * Copyright (C) 2015-2017 g10 Code GmbH + * Copyright (C) 2015-2018 g10 Code GmbH * * This file is part of GnuPG. * @@ -101,6 +101,125 @@ sig_comparison (const void *av, const void *bv) } +static gpg_error_t +remove_duplicate_sigs (kbnode_t kb, int *dups, int *modified) +{ + gpg_error_t err; + kbnode_t n; + int nsigs; + kbnode_t *sigs; /* Allocated array with the signature packet. */ + int i; + int last_i; + int block; + PKT_signature *sig; + + /* Count the sigs. */ + for (nsigs = 0, n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + else if (n->pkt->pkttype == PKT_SIGNATURE) + nsigs ++; + } + + if (!nsigs) + return 0; /* No signatures at all. */ + + /* Add them all to the SIGS array. */ + sigs = xtrycalloc (nsigs, sizeof *sigs); + if (!sigs) + { + err = gpg_error_from_syserror (); + log_error (_("error allocating memory: %s\n"), gpg_strerror (err)); + return err; + } + + block = 0; + i = 0; + for (n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + + if (n->pkt->pkttype != PKT_SIGNATURE) + { + switch (n->pkt->pkttype) + { + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_SUBKEY: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + /* Bump the block number so that we only consider + * signatures below the same object as duplicates. */ + block++; + break; + default: + break; + } + continue; + } + sig = n->pkt->pkt.signature; + sig->help_counter = block; + sigs[i++] = n; + } + log_assert (i == nsigs); + + qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison); + + last_i = 0; + for (i = 1; i < nsigs; i ++) + { + log_assert (sigs[last_i]); + log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE); + log_assert (sigs[i]); + log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE); + + if (sig_comparison (&sigs[last_i], &sigs[i]) == 0) + { + /* They are the same. Kill the latter. */ + if (DBG_PACKET) + { + sig = sigs[i]->pkt->pkt.signature; + + log_debug ("Signature appears multiple times, " + "deleting duplicate:\n"); + log_debug (" sig: class 0x%x, issuer: %s," + " timestamp: %s (%lld), digest: %02x %02x\n", + sig->sig_class, keystr (sig->keyid), + isotimestamp (sig->timestamp), + (long long) sig->timestamp, + sig->digest_start[0], sig->digest_start[1]); + } + + /* Remove sigs[i] from the keyblock. */ + { + kbnode_t z, *prevp; + int to_kill = last_i; + last_i = i; + + for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next) + if (z == sigs[to_kill]) + break; + + *prevp = sigs[to_kill]->next; + + sigs[to_kill]->next = NULL; + release_kbnode (sigs[to_kill]); + sigs[to_kill] = NULL; + + ++*dups; + *modified = 1; + } + } + else + last_i = i; + } + + xfree (sigs); + return 0; +} + + /* Perform a few sanity checks on a keyblock is okay and possibly * repair some damage. Concretely: * @@ -146,121 +265,11 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, pk = kb->pkt->pkt.public_key; /* First we look for duplicates. */ - { - int nsigs; - kbnode_t *sigs; - int i; - int last_i; - int block; - - /* Count the sigs. */ - for (nsigs = 0, n = kb; n; n = n->next) - { - if (is_deleted_kbnode (n)) - continue; - else if (n->pkt->pkttype == PKT_SIGNATURE) - nsigs ++; - } - - if (!nsigs) - return 0; /* No signatures at all. */ - - /* Add them all to the SIGS array. */ - sigs = xtrycalloc (nsigs, sizeof *sigs); - if (!sigs) - { - log_error (_("error allocating memory: %s\n"), - gpg_strerror (gpg_error_from_syserror ())); - return 0; - } - - i = 0; - block = 0; - for (n = kb; n; n = n->next) - { - if (is_deleted_kbnode (n)) - continue; - - if (n->pkt->pkttype != PKT_SIGNATURE) - { - switch (n->pkt->pkttype) - { - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - case PKT_USER_ID: - case PKT_ATTRIBUTE: - /* Bump the block number so that we only consider - * signatures below the same object as duplicates. */ - block++; - break; - default: - break; - } - continue; - } - sig = n->pkt->pkt.signature; - sig->help_counter = block; - sigs[i] = n; - i ++; - } - log_assert (i == nsigs); - - qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison); + if (remove_duplicate_sigs (kb, &dups, &modified)) + goto leave; /* Error */ - last_i = 0; - for (i = 1; i < nsigs; i ++) - { - log_assert (sigs[last_i]); - log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE); - log_assert (sigs[i]); - log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE); - - if (sig_comparison (&sigs[last_i], &sigs[i]) == 0) - /* They are the same. Kill the latter. */ - { - if (DBG_PACKET) - { - sig = sigs[i]->pkt->pkt.signature; - - log_debug ("Signature appears multiple times, " - "deleting duplicate:\n"); - log_debug (" sig: class 0x%x, issuer: %s," - " timestamp: %s (%lld), digest: %02x %02x\n", - sig->sig_class, keystr (sig->keyid), - isotimestamp (sig->timestamp), - (long long) sig->timestamp, - sig->digest_start[0], sig->digest_start[1]); - } - - /* Remove sigs[i] from the keyblock. */ - { - KBNODE z, *prevp; - int to_kill = last_i; - last_i = i; - - for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next) - if (z == sigs[to_kill]) - break; - - *prevp = sigs[to_kill]->next; - - sigs[to_kill]->next = NULL; - release_kbnode (sigs[to_kill]); - sigs[to_kill] = NULL; - - dups ++; - modified = 1; - } - } - else - last_i = i; - } - - xfree (sigs); - } - - /* Make sure the sigs occur after the component (public key, subkey, - user id) that they sign. */ + /* Now make sure the sigs occur after the component (aka block) + * (public key, subkey, user id) that they sign. */ issuer = NULL; last_printed_component = NULL; for (n_prevp = &kb, n = kb; @@ -598,6 +607,14 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, free_public_key (issuer); issuer = NULL; + /* If we reordered signatures we need to de-duplicate again because + * a signature can now be a duplicate in another block. */ + if (reordered) + { + if (remove_duplicate_sigs (kb, &dups, &modified)) + goto leave; + } + /* Identify keys / uids that don't have a self-sig. */ { int has_selfsig = 0; @@ -667,6 +684,8 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, } } + + leave: if (!opt.quiet) { char prefix[100]; ----------------------------------------------------------------------- Summary of changes: g10/key-check.c | 249 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 134 insertions(+), 115 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 18:53:41 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Jun 2018 18:53:41 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-18-g6a87a0b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 6a87a0bd2501d82f4a6263608e4856e841305caf (commit) via cedd754fcb03f6dad6e462efc3d347bcef4ec83a (commit) via 36cc730fa516b3a197f3bb1eb6f3881dd128fbb7 (commit) from c5c8fb1ec7c8690495de6189ec2c3a322db4e881 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6a87a0bd2501d82f4a6263608e4856e841305caf Author: Werner Koch Date: Thu Jun 7 18:41:17 2018 +0200 gpg: Improve import's repair-key duplicate signature detection. * g10/key-check.c (key_check_all_keysigs): Factor some code out to ... (remove_duplicate_sigs): new. (key_check_all_keysigs): Call remove_duplicate_sigs again after reordering. -- This is a follupup for commit 26bce2f01d2029ea2b8a8dbbe36118e3c83c5cba to cleanup the code and to add a second de-duplicate step when needed. GnuPG-bug-id: 3994 Signed-off-by: Werner Koch (cherry picked from commit 26746fe65d14a00773473c2d0d271406a5105bca) diff --git a/g10/key-check.c b/g10/key-check.c index 17f2dae..c17b12c 100644 --- a/g10/key-check.c +++ b/g10/key-check.c @@ -1,7 +1,7 @@ /* key-check.c - Detect and fix various problems with keys * Copyright (C) 1998-2010 Free Software Foundation, Inc. * Copyright (C) 1998-2017 Werner Koch - * Copyright (C) 2015-2017 g10 Code GmbH + * Copyright (C) 2015-2018 g10 Code GmbH * * This file is part of GnuPG. * @@ -101,6 +101,125 @@ sig_comparison (const void *av, const void *bv) } +static gpg_error_t +remove_duplicate_sigs (kbnode_t kb, int *dups, int *modified) +{ + gpg_error_t err; + kbnode_t n; + int nsigs; + kbnode_t *sigs; /* Allocated array with the signature packet. */ + int i; + int last_i; + int block; + PKT_signature *sig; + + /* Count the sigs. */ + for (nsigs = 0, n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + else if (n->pkt->pkttype == PKT_SIGNATURE) + nsigs ++; + } + + if (!nsigs) + return 0; /* No signatures at all. */ + + /* Add them all to the SIGS array. */ + sigs = xtrycalloc (nsigs, sizeof *sigs); + if (!sigs) + { + err = gpg_error_from_syserror (); + log_error (_("error allocating memory: %s\n"), gpg_strerror (err)); + return err; + } + + block = 0; + i = 0; + for (n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + + if (n->pkt->pkttype != PKT_SIGNATURE) + { + switch (n->pkt->pkttype) + { + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_SUBKEY: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + /* Bump the block number so that we only consider + * signatures below the same object as duplicates. */ + block++; + break; + default: + break; + } + continue; + } + sig = n->pkt->pkt.signature; + sig->help_counter = block; + sigs[i++] = n; + } + log_assert (i == nsigs); + + qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison); + + last_i = 0; + for (i = 1; i < nsigs; i ++) + { + log_assert (sigs[last_i]); + log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE); + log_assert (sigs[i]); + log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE); + + if (sig_comparison (&sigs[last_i], &sigs[i]) == 0) + { + /* They are the same. Kill the latter. */ + if (DBG_PACKET) + { + sig = sigs[i]->pkt->pkt.signature; + + log_debug ("Signature appears multiple times, " + "deleting duplicate:\n"); + log_debug (" sig: class 0x%x, issuer: %s," + " timestamp: %s (%lld), digest: %02x %02x\n", + sig->sig_class, keystr (sig->keyid), + isotimestamp (sig->timestamp), + (long long) sig->timestamp, + sig->digest_start[0], sig->digest_start[1]); + } + + /* Remove sigs[i] from the keyblock. */ + { + kbnode_t z, *prevp; + int to_kill = last_i; + last_i = i; + + for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next) + if (z == sigs[to_kill]) + break; + + *prevp = sigs[to_kill]->next; + + sigs[to_kill]->next = NULL; + release_kbnode (sigs[to_kill]); + sigs[to_kill] = NULL; + + ++*dups; + *modified = 1; + } + } + else + last_i = i; + } + + xfree (sigs); + return 0; +} + + /* Perform a few sanity checks on a keyblock is okay and possibly * repair some damage. Concretely: * @@ -146,121 +265,11 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, pk = kb->pkt->pkt.public_key; /* First we look for duplicates. */ - { - int nsigs; - kbnode_t *sigs; - int i; - int last_i; - int block; - - /* Count the sigs. */ - for (nsigs = 0, n = kb; n; n = n->next) - { - if (is_deleted_kbnode (n)) - continue; - else if (n->pkt->pkttype == PKT_SIGNATURE) - nsigs ++; - } - - if (!nsigs) - return 0; /* No signatures at all. */ - - /* Add them all to the SIGS array. */ - sigs = xtrycalloc (nsigs, sizeof *sigs); - if (!sigs) - { - log_error (_("error allocating memory: %s\n"), - gpg_strerror (gpg_error_from_syserror ())); - return 0; - } - - i = 0; - block = 0; - for (n = kb; n; n = n->next) - { - if (is_deleted_kbnode (n)) - continue; - - if (n->pkt->pkttype != PKT_SIGNATURE) - { - switch (n->pkt->pkttype) - { - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - case PKT_USER_ID: - case PKT_ATTRIBUTE: - /* Bump the block number so that we only consider - * signatures below the same object as duplicates. */ - block++; - break; - default: - break; - } - continue; - } - sig = n->pkt->pkt.signature; - sig->help_counter = block; - sigs[i] = n; - i ++; - } - log_assert (i == nsigs); - - qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison); + if (remove_duplicate_sigs (kb, &dups, &modified)) + goto leave; /* Error */ - last_i = 0; - for (i = 1; i < nsigs; i ++) - { - log_assert (sigs[last_i]); - log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE); - log_assert (sigs[i]); - log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE); - - if (sig_comparison (&sigs[last_i], &sigs[i]) == 0) - /* They are the same. Kill the latter. */ - { - if (DBG_PACKET) - { - sig = sigs[i]->pkt->pkt.signature; - - log_debug ("Signature appears multiple times, " - "deleting duplicate:\n"); - log_debug (" sig: class 0x%x, issuer: %s," - " timestamp: %s (%lld), digest: %02x %02x\n", - sig->sig_class, keystr (sig->keyid), - isotimestamp (sig->timestamp), - (long long) sig->timestamp, - sig->digest_start[0], sig->digest_start[1]); - } - - /* Remove sigs[i] from the keyblock. */ - { - KBNODE z, *prevp; - int to_kill = last_i; - last_i = i; - - for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next) - if (z == sigs[to_kill]) - break; - - *prevp = sigs[to_kill]->next; - - sigs[to_kill]->next = NULL; - release_kbnode (sigs[to_kill]); - sigs[to_kill] = NULL; - - dups ++; - modified = 1; - } - } - else - last_i = i; - } - - xfree (sigs); - } - - /* Make sure the sigs occur after the component (public key, subkey, - user id) that they sign. */ + /* Now make sure the sigs occur after the component (aka block) + * (public key, subkey, user id) that they sign. */ issuer = NULL; last_printed_component = NULL; for (n_prevp = &kb, n = kb; @@ -598,6 +607,14 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, free_public_key (issuer); issuer = NULL; + /* If we reordered signatures we need to de-duplicate again because + * a signature can now be a duplicate in another block. */ + if (reordered) + { + if (remove_duplicate_sigs (kb, &dups, &modified)) + goto leave; + } + /* Identify keys / uids that don't have a self-sig. */ { int has_selfsig = 0; @@ -667,6 +684,8 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, } } + + leave: if (!opt.quiet) { char prefix[100]; commit cedd754fcb03f6dad6e462efc3d347bcef4ec83a Author: Werner Koch Date: Thu Jun 7 17:22:58 2018 +0200 gpg: Fix import's repair-key duplicate signature detection. * g10/packet.h (PKG_siganture): Add field 'help_counter'. * g10/key-check.c (sig_comparison): Take care of HELP_COUNTER. (key_check_all_keysigs): De-duplicate on a per-block base. -- The key_check_all_keysigs first does a detection of duplicate signature. This is done over all signatures at once. The problem here is for example: key uid_1 sig_uid_1.1 sig_uid_1.2 subkey_1 sig_sub_1.1 subkey_2 sig_sub_2.1 sig_sub_2.2 (duplicate of sig_sub_1.1) Now the de-duplication deletes the first signature and keeps the second. That works in most cases for foreign signature on userids but in the above constellation the code simply removes sig_sub_1.1 so that subkey_1 has no binding signature anymore. In a later step during import the missing binding is detected and subkey_1 is removed because it is not anymore valid. The sig_sub_2.2 will also be removed later because it does not check out for subkey_2 (that is as expected). The fix is to let the de-duplication work only on blocks (ie. within the signatures of a user id or a subkey). This will not detect all duplicates but that does not harm because later steps will detect and remove them. In the above case (with this patch applied) the second phase of key_check_all_keysigs will reorder key signatures and move the duplicate sig_sub_2.2 directly after sig_sub_1.1. This duplicates the signature and for cleanness we should kick the de-duplication process again. This will be done with a followup patch. GnuPG-bug-id: 3994 Signed-off-by: Werner Koch (cherry picked from commit 26bce2f01d2029ea2b8a8dbbe36118e3c83c5cba) diff --git a/g10/key-check.c b/g10/key-check.c index 86b1e76..17f2dae 100644 --- a/g10/key-check.c +++ b/g10/key-check.c @@ -72,6 +72,13 @@ sig_comparison (const void *av, const void *bv) a = an->pkt->pkt.signature; b = bn->pkt->pkt.signature; + /* Signatures with a different help counter are not identical for + * our purpose. */ + if (a->help_counter < b->help_counter) + return -1; + if (a->help_counter > b->help_counter) + return 1; + if (a->digest_algo < b->digest_algo) return -1; if (a->digest_algo > b->digest_algo) @@ -133,6 +140,7 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, int bad_signature = 0; int missing_selfsig = 0; int modified = 0; + PKT_signature *sig; log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY); pk = kb->pkt->pkt.public_key; @@ -143,6 +151,7 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, kbnode_t *sigs; int i; int last_i; + int block; /* Count the sigs. */ for (nsigs = 0, n = kb; n; n = n->next) @@ -166,14 +175,31 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, } i = 0; + block = 0; for (n = kb; n; n = n->next) { if (is_deleted_kbnode (n)) continue; if (n->pkt->pkttype != PKT_SIGNATURE) - continue; - + { + switch (n->pkt->pkttype) + { + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_SUBKEY: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + /* Bump the block number so that we only consider + * signatures below the same object as duplicates. */ + block++; + break; + default: + break; + } + continue; + } + sig = n->pkt->pkt.signature; + sig->help_counter = block; sigs[i] = n; i ++; } @@ -194,7 +220,7 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, { if (DBG_PACKET) { - PKT_signature *sig = sigs[i]->pkt->pkt.signature; + sig = sigs[i]->pkt->pkt.signature; log_debug ("Signature appears multiple times, " "deleting duplicate:\n"); @@ -244,7 +270,6 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, { PACKET *p; int processed_current_component; - PKT_signature *sig; int rc; int dump_sig_params = 0; @@ -577,7 +602,6 @@ key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, { int has_selfsig = 0; PACKET *p; - PKT_signature *sig; current_component = NULL; for (n = kb; n; n = n->next) diff --git a/g10/packet.h b/g10/packet.h index 43c097e..dc4ce5f 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -230,6 +230,7 @@ typedef struct const byte *trust_regexp; struct revocation_key *revkey; int numrevkeys; + int help_counter; /* Used internally bu some fucntions. */ pka_info_t *pka_info; /* Malloced PKA data or NULL if not available. See also flags.pka_tried. */ char *signers_uid; /* Malloced value of the SIGNERS_UID commit 36cc730fa516b3a197f3bb1eb6f3881dd128fbb7 Author: Werner Koch Date: Thu Jun 7 10:30:07 2018 +0200 gpg: Improve verbose output during import. * g10/import.c (chk_self_sigs): Print the subkeyid in addition to the keyid. (delete_inv_parts): Ditto. Signed-off-by: Werner Koch (cherry picked from commit 1bc6b5174248ba4d83d648ef6d6f4550540d1f20) diff --git a/g10/import.c b/g10/import.c index 10fbd42..6d2beaf 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2731,8 +2731,9 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) } -/* Loop over the keyblock and check all self signatures. On return - * the following bis in the node flags are set: +/* Loop over the KEYBLOCK and check all self signatures. KEYID is the + * keyid of the primary key for reporting purposes. On return the + * following bits in the node flags are set: * * - NODE_GOOD_SELFSIG :: User ID or subkey has a self-signature * - NODE_BAD_SELFSIG :: Used ID or subkey has an invalid self-signature @@ -2747,17 +2748,22 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) { - kbnode_t n, knode = NULL; + kbnode_t knode = NULL; /* The node of the current subkey. */ + PKT_public_key *subpk = NULL; /* and its packet. */ + kbnode_t bsnode = NULL; /* Subkey binding signature node. */ + u32 bsdate = 0; /* Timestamp of that node. */ + kbnode_t rsnode = NULL; /* Subkey recocation signature node. */ + u32 rsdate = 0; /* Timestamp of tha node. */ PKT_signature *sig; int rc; - u32 bsdate=0, rsdate=0; - kbnode_t bsnode = NULL, rsnode = NULL; + kbnode_t n; for (n=keyblock; (n = find_next_kbnode (n, 0)); ) { if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) { knode = n; + subpk = knode->pkt->pkt.public_key; bsdate = 0; rsdate = 0; bsnode = NULL; @@ -2846,11 +2852,14 @@ chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) if ( rc ) { if (opt.verbose) - log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %s: unsupported public key" - " algorithm\n"): - _("key %s: invalid subkey binding\n"), - keystr (keyid)); + { + keyid_from_pk (subpk, NULL); + log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? + _("key %s: unsupported public key" + " algorithm\n"): + _("key %s: invalid subkey binding\n"), + keystr_with_sub (keyid, subpk->keyid)); + } n->flag |= NODE_DELETION_MARK; } else @@ -2865,8 +2874,12 @@ chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) one is newer */ bsnode->flag |= NODE_DELETION_MARK; if (opt.verbose) - log_info (_("key %s: removed multiple subkey" - " binding\n"),keystr(keyid)); + { + keyid_from_pk (subpk, NULL); + log_info (_("key %s: removed multiple subkey" + " binding\n"), + keystr_with_sub (keyid, subpk->keyid)); + } } bsnode = n; @@ -2945,6 +2958,7 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, { kbnode_t node; int nvalid=0, uid_seen=0, subkey_seen=0; + PKT_public_key *pk; for (node=keyblock->next; node; node = node->next ) { @@ -2982,7 +2996,12 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, || !(node->flag & NODE_GOOD_SELFSIG)) { if (opt.verbose ) - log_info( _("key %s: skipped subkey\n"),keystr(keyid)); + { + pk = node->pkt->pkt.public_key; + keyid_from_pk (pk, NULL); + log_info (_("key %s: skipped subkey\n"), + keystr_with_sub (keyid, pk->keyid)); + } delete_kbnode( node ); /* the subkey */ /* and all following signature packets */ ----------------------------------------------------------------------- Summary of changes: g10/import.c | 45 ++++++++--- g10/key-check.c | 241 +++++++++++++++++++++++++++++++++----------------------- g10/packet.h | 1 + 3 files changed, 175 insertions(+), 112 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 21:07:49 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jun 2018 21:07:49 +0200 Subject: [git] gnupg-doc - branch, master, updated. d3752f2f0146923355657e3154e60b1707a1d475 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via d3752f2f0146923355657e3154e60b1707a1d475 (commit) via 85b3f34a7a32da5e7b21e9e1285072eaa026f32f (commit) from 3ce9d4cdbcccddb6d065bd603f4d03921194ba4b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d3752f2f0146923355657e3154e60b1707a1d475 Author: Andre Heinecke Date: Thu Jun 7 21:06:00 2018 +0200 web: Mark emeritus people and sort them down * web/people/index.org: Mark marcus, kai, justus and neal as emeritus. Sort them below the active devs. -- It would probably be better if we had a "kudos" or so section for developers which are no longer active. I've chosen the word emeritus as this was used in the past. diff --git a/web/people/index.org b/web/people/index.org index 7e7b3f8..d54bbf7 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -51,23 +51,6 @@ #+HTML:

-** Marcus Brinkmann - - #+HTML:

- #+HTML:

- #+HTML:
- - /Hacker/ - - Marcus is part of the free software community since 1997, when he - joined the [[http://www.debian.org][Debian]] project. Probably best known for his past work - on GNU/Hurd, he also has a diploma degree in mathematics, and was - part and full time employed by [[https://g10code.com][g10^code]] to work on GnuPG and - related software from 2001 to 2012 and for 7 months in 2017. He was - a founding member of the [[../verein/index.org][GnuPG e.V.]] - - #+HTML:

- ** NIIBE Yutaka #+HTML:

@@ -97,48 +80,6 @@ #+HTML:

-** Neal Walfied - - #+HTML:

- #+HTML:

- #+HTML:
- - /Core components hacker/ - - Neal started to work on GnuPG in 2015 to support maintenance and - development in all areas. We was full time employed by g10^code - from 2015 to 2017. He is a founding member of the [[../verein/index.org][GnuPG e.V.]] - - #+HTML:

- -** Kai Michaelis - - #+HTML:

- #+HTML:

- #+HTML:
- - /Enigmail hacker/ - - Kai is working on the [[https://enigmail.net][Enigmail]] project since 2015. He was part - time employed by g10^code from 2015 to 2017. He is a founding - member of the [[../verein/index.org][GnuPG e.V.]] - - #+HTML:

- -** Justus Winter - - #+HTML:

- #+HTML:

- #+HTML:
- - /Core components hacker/ - - Justus started to work on GnuPG in 2015 to support maintenance and - development in all areas. He was full time employed by g10^code - from 2015 to 2017. He is a founding member of the [[../verein/index.org][GnuPG e.V.]] - - #+HTML:

- ** Ben McGinnes #+HTML:

@@ -187,6 +128,65 @@ #+HTML:

+** Marcus Brinkmann + + #+HTML:

+ #+HTML:

+ #+HTML:
+ + /Hacker emeritus/ + + Marcus is part of the free software community since 1997, when he + joined the [[http://www.debian.org][Debian]] project. Probably best known for his past work + on GNU/Hurd, he also has a diploma degree in mathematics, and was + part and full time employed by [[https://g10code.com][g10^code]] to work on GnuPG and + related software from 2001 to 2012 and for 7 months in 2017. He was + a founding member of the [[../verein/index.org][GnuPG e.V.]] + + #+HTML:

+ +** Neal Walfied + + #+HTML:

+ #+HTML:

+ #+HTML:
+ + /Core components hacker emeritus/ + + Neal started to work on GnuPG in 2015 to support maintenance and + development in all areas. We was full time employed by g10^code + from 2015 to 2017. He is a founding member of the [[../verein/index.org][GnuPG e.V.]] + + #+HTML:

+ +** Kai Michaelis + + #+HTML:

+ #+HTML:

+ #+HTML:
+ + /Enigmail hacker emeritus/ + + Kai is working on the [[https://enigmail.net][Enigmail]] project since 2015. He was part + time employed by g10^code from 2015 to 2017. He is a founding + member of the [[../verein/index.org][GnuPG e.V.]] + + #+HTML:

+ +** Justus Winter + + #+HTML:

+ #+HTML:

+ #+HTML:
+ + /Core components hacker emeritus/ + + Justus started to work on GnuPG in 2015 to support maintenance and + development in all areas. He was full time employed by g10^code + from 2015 to 2017. He is a founding member of the [[../verein/index.org][GnuPG e.V.]] + + #+HTML:

+ * COMMENT # eof commit 85b3f34a7a32da5e7b21e9e1285072eaa026f32f Author: Andre Heinecke Date: Thu Jun 7 21:02:12 2018 +0200 web: Add Andre Heinecke to people * web/people/index.org: Add Andre. * web/people/aheinecke.png: New. diff --git a/web/people/aheinecke.png b/web/people/aheinecke.png new file mode 100644 index 0000000..4569d09 Binary files /dev/null and b/web/people/aheinecke.png differ diff --git a/web/people/index.org b/web/people/index.org index 0438a17..7e7b3f8 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -163,6 +163,30 @@ #+HTML:

+** Andre Heinecke + + #+HTML:

+ #+HTML:

+ #+HTML:
+ + /Windows and UX/ + + Andre is working mainly on GnuPG related projects for his employer + [[https://www.intevation.org][Intevation GmbH]] + He has been an active KDE Developer since 2009, + mostly focused on Windows ports of KDE Software. Since 2013 he took + over several Windows and UX specific parts of GnuPG. + + Andre is the current maintainer of Kleopatra the KDE / Gpg4win GUI + for GnuPG. He also maintains GpgOL since 2013 and wrote the + support for Outlook 2010 and later versions. + Additonally he is the maintainer of Gpg4win in general and GpgEX + as well as the GPGME bindings for C++ and Qt. + + [[https://k.gnupg.net/94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][GPG key 94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1]] + + #+HTML:

+ * COMMENT # eof ----------------------------------------------------------------------- Summary of changes: web/people/aheinecke.png | Bin 0 -> 43719 bytes web/people/index.org | 112 ++++++++++++++++++++++++++++------------------- 2 files changed, 68 insertions(+), 44 deletions(-) create mode 100644 web/people/aheinecke.png hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 21:12:57 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jun 2018 21:12:57 +0200 Subject: [git] gnupg-doc - branch, master, updated. 2c913d974767d4f3f33ffd587abf5d091a9eef9c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 2c913d974767d4f3f33ffd587abf5d091a9eef9c (commit) from d3752f2f0146923355657e3154e60b1707a1d475 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2c913d974767d4f3f33ffd587abf5d091a9eef9c Author: Andre Heinecke Date: Thu Jun 7 21:11:55 2018 +0200 web: Note aheineckes verein status * web/people/index.org: Note aheineckes verein status. diff --git a/web/people/index.org b/web/people/index.org index d54bbf7..28c8f27 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -124,6 +124,9 @@ Additonally he is the maintainer of Gpg4win in general and GpgEX as well as the GPGME bindings for C++ and Qt. + He is a founding member and the current cashier of the + [[../verein/index.org][GnuPG e.V.]] + [[https://k.gnupg.net/94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][GPG key 94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1]] #+HTML:

----------------------------------------------------------------------- Summary of changes: web/people/index.org | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 21:17:06 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jun 2018 21:17:06 +0200 Subject: [git] gnupg-doc - branch, master, updated. e11e8a5b1090d053fb23f5981873f20b9cfe09fc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via e11e8a5b1090d053fb23f5981873f20b9cfe09fc (commit) from 2c913d974767d4f3f33ffd587abf5d091a9eef9c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e11e8a5b1090d053fb23f5981873f20b9cfe09fc Author: Andre Heinecke Date: Thu Jun 7 21:16:07 2018 +0200 web: Try a better split between inactive ppl * web/people/index.org: Try a hr and a note for inactive devs. -- I'm playing with this live as I can't build the website myself. diff --git a/web/people/index.org b/web/people/index.org index 28c8f27..87d20aa 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -131,13 +131,20 @@ #+HTML:

+ + #+HTML:


+** Former developers + + The following developers made large contributions to GnuPG in the past + but are no longer active. + ** Marcus Brinkmann #+HTML:
#+HTML:

#+HTML:
- /Hacker emeritus/ + /Hacker/ Marcus is part of the free software community since 1997, when he joined the [[http://www.debian.org][Debian]] project. Probably best known for his past work @@ -154,7 +161,7 @@ #+HTML:

#+HTML:
- /Core components hacker emeritus/ + /Core components hacker/ Neal started to work on GnuPG in 2015 to support maintenance and development in all areas. We was full time employed by g10^code @@ -168,7 +175,7 @@ #+HTML:

#+HTML:
- /Enigmail hacker emeritus/ + /Enigmail hacker/ Kai is working on the [[https://enigmail.net][Enigmail]] project since 2015. He was part time employed by g10^code from 2015 to 2017. He is a founding @@ -182,7 +189,7 @@ #+HTML:

#+HTML: - /Core components hacker emeritus/ + /Core components hacker/ Justus started to work on GnuPG in 2015 to support maintenance and development in all areas. He was full time employed by g10^code ----------------------------------------------------------------------- Summary of changes: web/people/index.org | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 7 21:30:51 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 07 Jun 2018 21:30:51 +0200 Subject: [git] gnupg-doc - branch, master, updated. dbaa9b76509ebb1f402429c7c52421b319f38482 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via dbaa9b76509ebb1f402429c7c52421b319f38482 (commit) from e11e8a5b1090d053fb23f5981873f20b9cfe09fc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dbaa9b76509ebb1f402429c7c52421b319f38482 Author: Andre Heinecke Date: Thu Jun 7 21:29:59 2018 +0200 web: Improve former developers section * web/people/index.org: Improve the split for former devs and mention their projects. diff --git a/web/people/index.org b/web/people/index.org index 87d20aa..1fd53d1 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -133,10 +133,14 @@ #+HTML:
-** Former developers +* Former developers The following developers made large contributions to GnuPG in the past - but are no longer active. + but are, sadly, no longer active GnuPG developers. + + Most are still working on improving the OpenPGP ecosystem and we wish + them the very best. + #+HTML:
** Marcus Brinkmann @@ -153,6 +157,8 @@ related software from 2001 to 2012 and for 7 months in 2017. He was a founding member of the [[../verein/index.org][GnuPG e.V.]] + Marcus currently works on [[https://neopg.io/][NeoPG]]. + #+HTML:

** Neal Walfied @@ -167,6 +173,7 @@ development in all areas. We was full time employed by g10^code from 2015 to 2017. He is a founding member of the [[../verein/index.org][GnuPG e.V.]] + Neal currently works on [[https://sequoia-pgp.org/][Sequoia-PGP]]. #+HTML:

** Kai Michaelis @@ -195,6 +202,7 @@ development in all areas. He was full time employed by g10^code from 2015 to 2017. He is a founding member of the [[../verein/index.org][GnuPG e.V.]] + Justus currently works on [[https://sequoia-pgp.org/][Sequoia-PGP]]. #+HTML:

* COMMENT ----------------------------------------------------------------------- Summary of changes: web/people/index.org | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 09:28:52 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 08 Jun 2018 09:28:52 +0200 Subject: [git] GnuPG - branch, gniibe/decryption-key, created. gnupg-2.2.7-138-gfed3e10 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, gniibe/decryption-key has been created at fed3e10121a76cf270e72ff0bcf31a4ed40068e8 (commit) - Log ----------------------------------------------------------------- commit fed3e10121a76cf270e72ff0bcf31a4ed40068e8 Author: NIIBE Yutaka Date: Fri Jun 8 16:21:05 2018 +0900 g10: Change the order of handling private key for encryption. * g10/packet.h (struct pubkey_enc_list): New. * g10/gpgv.c (get_session_key): Supply struct pubkey_enc_list. * g10/test-stubs.c (get_session_key): Likewise. * g10/mainproc.c (struct kidlist_item): Remove. (release_list): Use struct pubkey_enc_list. (proc_pubkey_enc, print_pkenc_list): Likewise. (proc_encrypted): Don't loop for pkenc_list, but just supply the list to get_session_key. * g10/pubkey-enc.c (get_session_key): Loop for secret key available, and check pkenc_list for each secret key. -- Signed-off-by: NIIBE Yutaka diff --git a/g10/gpgv.c b/g10/gpgv.c index c43067d..16d9044 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -490,7 +490,7 @@ read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock) * No encryption here but mainproc links to these functions. */ gpg_error_t -get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek) +get_session_key (ctrl_t ctrl, struct pubkey_enc_list *k, DEK *dek) { (void)ctrl; (void)k; diff --git a/g10/mainproc.c b/g10/mainproc.c index d5fee73..835ab6b 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -46,16 +46,6 @@ #define MAX_NESTING_DEPTH 32 -/* An object to build a list of keyid related info. */ -struct kidlist_item -{ - struct kidlist_item *next; - u32 kid[2]; - int pubkey_algo; - gcry_mpi_t data[2]; -}; - - /* * Object to hold the processing context. */ @@ -95,7 +85,7 @@ struct mainproc_context iobuf_t iobuf; /* Used to get the filename etc. */ int trustletter; /* Temporary usage in list_node. */ ulong symkeys; /* Number of symmetrically encrypted session keys. */ - struct kidlist_item *pkenc_list; /* List of encryption packets. */ + struct pubkey_enc_list *pkenc_list; /* List of encryption packets. */ struct { unsigned int sig_seen:1; /* Set to true if a signature packet has been seen. */ @@ -135,7 +125,7 @@ release_list( CTX c ) release_kbnode (c->list); while (c->pkenc_list) { - struct kidlist_item *tmp = c->pkenc_list->next; + struct pubkey_enc_list *tmp = c->pkenc_list->next; mpi_release (c->pkenc_list->data[0]); mpi_release (c->pkenc_list->data[1]); @@ -464,7 +454,7 @@ static void proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) { PKT_pubkey_enc *enc; - struct kidlist_item *x = xmalloc (sizeof *x); + struct pubkey_enc_list *x = xmalloc (sizeof *x); /* Check whether the secret key is available and store in this case. */ c->last_was_session_key = 1; @@ -485,8 +475,8 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) if (!opt.list_only && !opt.override_session_key) { - x->kid[0] = enc->keyid[0]; - x->kid[1] = enc->keyid[1]; + x->keyid[0] = enc->keyid[0]; + x->keyid[1] = enc->keyid[1]; x->pubkey_algo = enc->pubkey_algo; x->data[0] = x->data[1] = NULL; if (enc->data[0]) @@ -507,7 +497,7 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) * not decrypt. */ static void -print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list) +print_pkenc_list (ctrl_t ctrl, struct pubkey_enc_list *list) { for (; list; list = list->next) { @@ -520,19 +510,19 @@ print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list) if (!algstr) algstr = "[?]"; pk->pubkey_algo = list->pubkey_algo; - if (!get_pubkey (ctrl, pk, list->kid)) + if (!get_pubkey (ctrl, pk, list->keyid)) { char *p; log_info (_("encrypted with %u-bit %s key, ID %s, created %s\n"), nbits_from_pk (pk), algstr, keystr_from_pk(pk), strtimestamp (pk->timestamp)); - p = get_user_id_native (ctrl, list->kid); + p = get_user_id_native (ctrl, list->keyid); log_printf (_(" \"%s\"\n"), p); xfree (p); } else log_info (_("encrypted with %s key, ID %s\n"), - algstr, keystr(list->kid)); + algstr, keystr(list->keyid)); free_public_key (pk); } @@ -542,7 +532,6 @@ print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list) static void proc_encrypted (CTX c, PACKET *pkt) { - struct kidlist_item *item; int result = 0; if (!opt.quiet) @@ -555,7 +544,7 @@ proc_encrypted (CTX c, PACKET *pkt) } /* Figure out the session key by looking at all pkenc packets. */ - if (opt.list_only) + if (opt.list_only || c->dek) ; else if (opt.override_session_key) { @@ -572,53 +561,16 @@ proc_encrypted (CTX c, PACKET *pkt) } else { - for (item = c->pkenc_list; item; item = item->next) - if (item->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E - || item->pubkey_algo == PUBKEY_ALGO_ECDH - || item->pubkey_algo == PUBKEY_ALGO_RSA - || item->pubkey_algo == PUBKEY_ALGO_RSA_E - || item->pubkey_algo == PUBKEY_ALGO_ELGAMAL) - { - if (((!item->kid[0] && !item->kid[1]) - || opt.try_all_secrets - || have_secret_key_with_kid (item->kid))) - { - PKT_pubkey_enc enc; - - enc.keyid[0] = item->kid[0]; - enc.keyid[1] = item->kid[1]; - enc.pubkey_algo = item->pubkey_algo; - enc.data[0] = item->data[0]; - enc.data[1] = item->data[1]; - - c->dek = xmalloc_secure_clear (sizeof *c->dek); - if (!(result = get_session_key (c->ctrl, &enc, c->dek))) - break; - - log_info (_("public key decryption failed: %s\n"), - gpg_strerror (result)); - write_status_error ("pkdecrypt_failed", result); - - /* Error: Delete the DEK. */ - xfree (c->dek); - c->dek = NULL; - } - else - { - if (is_status_enabled ()) - { - char buf[20]; - snprintf (buf, sizeof buf, "%08lX%08lX", - (ulong)item->kid[0], (ulong)item->kid[1]); - write_status_text (STATUS_NO_SECKEY, buf); - } - } - } - else + c->dek = xmalloc_secure_clear (sizeof *c->dek); + if ((result = get_session_key (c->ctrl, c->pkenc_list, c->dek))) { log_info (_("public key decryption failed: %s\n"), - gpg_strerror (GPG_ERR_PUBKEY_ALGO)); - write_status_error ("pkdecrypt_failed", GPG_ERR_PUBKEY_ALGO); + gpg_strerror (result)); + write_status_error ("pkdecrypt_failed", result); + + /* Error: Delete the DEK. */ + xfree (c->dek); + c->dek = NULL; } } @@ -698,7 +650,7 @@ proc_encrypted (CTX c, PACKET *pkt) && gnupg_cipher_is_compliant (CO_DE_VS, c->dek->algo, GCRY_CIPHER_MODE_CFB)) { - struct kidlist_item *i; + struct pubkey_enc_list *i; int compliant = 1; PKT_public_key *pk = xmalloc (sizeof *pk); @@ -711,7 +663,7 @@ proc_encrypted (CTX c, PACKET *pkt) { memset (pk, 0, sizeof *pk); pk->pubkey_algo = i->pubkey_algo; - if (get_pubkey (c->ctrl, pk, i->kid) != 0 + if (get_pubkey (c->ctrl, pk, i->keyid) != 0 || ! gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey, nbits_from_pk (pk), NULL)) compliant = 0; diff --git a/g10/packet.h b/g10/packet.h index e8397ea..a4157c5 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -131,6 +131,16 @@ typedef struct { } PKT_pubkey_enc; +/* An object to build a list of public-key encrypted session key. */ +struct pubkey_enc_list +{ + struct pubkey_enc_list *next; + u32 keyid[2]; + int pubkey_algo; + gcry_mpi_t data[PUBKEY_MAX_NENC]; +}; + + /* A one-pass signature packet as defined in RFC 4880, Section 5.4. All fields are serialized. */ typedef struct { @@ -887,7 +897,7 @@ gpg_error_t check_signature2 (ctrl_t ctrl, /*-- pubkey-enc.c --*/ -gpg_error_t get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek); +gpg_error_t get_session_key (ctrl_t ctrl, struct pubkey_enc_list *k, DEK *dek); gpg_error_t get_override_session_key (DEK *dek, const char *string); /*-- compress.c --*/ diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 0185097..8540e03 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -38,7 +38,7 @@ #include "../common/compliance.h" -static gpg_error_t get_it (ctrl_t ctrl, PKT_pubkey_enc *k, +static gpg_error_t get_it (ctrl_t ctrl, struct pubkey_enc_list *k, DEK *dek, PKT_public_key *sk, u32 *keyid); @@ -72,92 +72,92 @@ is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo) * which should have been allocated in secure memory by the caller. */ gpg_error_t -get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek) +get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) { PKT_public_key *sk = NULL; int rc; + void *enum_context = NULL; + u32 keyid[2]; + int search_for_secret_keys = 1; if (DBG_CLOCK) log_clock ("get_session_key enter"); - rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC); - if (rc) - goto leave; - - if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets) + while (search_for_secret_keys) { + struct pubkey_enc_list *k; + + free_public_key (sk); sk = xmalloc_clear (sizeof *sk); - sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */ - if (!(rc = get_seckey (ctrl, sk, k->keyid))) + rc = enum_secret_keys (ctrl, &enum_context, sk); + if (rc) { - /* Check compliance. */ - if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, - sk->pubkey_algo, - sk->pkey, nbits_from_pk (sk), NULL)) - { - log_info (_("key %s is not suitable for decryption" - " in %s mode\n"), - keystr_from_pk (sk), - gnupg_compliance_option_string (opt.compliance)); - rc = gpg_error (GPG_ERR_PUBKEY_ALGO); - } - else - rc = get_it (ctrl, k, dek, sk, k->keyid); + rc = GPG_ERR_NO_SECKEY; + break; } - } - else if (opt.skip_hidden_recipients) - rc = gpg_error (GPG_ERR_NO_SECKEY); - else /* Anonymous receiver: Try all available secret keys. */ - { - void *enum_context = NULL; - u32 keyid[2]; - for (;;) + if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC)) + continue; + + /* Check compliance. */ + if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, + sk->pubkey_algo, + sk->pkey, nbits_from_pk (sk), NULL)) { - free_public_key (sk); - sk = xmalloc_clear (sizeof *sk); - rc = enum_secret_keys (ctrl, &enum_context, sk); - if (rc) - { - rc = GPG_ERR_NO_SECKEY; - break; - } - if (sk->pubkey_algo != k->pubkey_algo) + log_info (_("key %s is not suitable for decryption" + " in %s mode\n"), + keystr_from_pk (sk), + gnupg_compliance_option_string (opt.compliance)); + continue; + } + + for (k = list; k; k = k->next) + { + if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E + || k->pubkey_algo == PUBKEY_ALGO_ECDH + || k->pubkey_algo == PUBKEY_ALGO_RSA + || k->pubkey_algo == PUBKEY_ALGO_RSA_E + || k->pubkey_algo == PUBKEY_ALGO_ELGAMAL)) continue; - if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC)) + + if (openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC)) + continue; + + if (sk->pubkey_algo != k->pubkey_algo) continue; + keyid_from_pk (sk, keyid); - if (!opt.quiet) - log_info (_("anonymous recipient; trying secret key %s ...\n"), - keystr (keyid)); - - /* Check compliance. */ - if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, - sk->pubkey_algo, - sk->pkey, nbits_from_pk (sk), NULL)) + + if (!k->keyid[0] && !k->keyid[1]) { - log_info (_("key %s is not suitable for decryption" - " in %s mode\n"), - keystr_from_pk (sk), - gnupg_compliance_option_string (opt.compliance)); - continue; + if (!opt.quiet) + log_info (_("anonymous recipient; trying secret key %s ...\n"), + keystr (keyid)); } + else if (opt.try_all_secrets + || (k->keyid[0] == keyid[0] && k->keyid[1] == keyid[1])) + ; + else + continue; rc = get_it (ctrl, k, dek, sk, keyid); if (!rc) { - if (!opt.quiet) + if (!opt.quiet && !k->keyid[0] && !k->keyid[1]) log_info (_("okay, we are the anonymous recipient.\n")); + search_for_secret_keys = 0; break; } else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) - break; /* Don't try any more secret keys. */ + { + search_for_secret_keys = 0; + break; /* Don't try any more secret keys. */ + } } - enum_secret_keys (ctrl, &enum_context, NULL); /* free context */ } - - leave: + enum_secret_keys (ctrl, &enum_context, NULL); /* free context */ free_public_key (sk); + if (DBG_CLOCK) log_clock ("get_session_key leave"); return rc; @@ -166,7 +166,7 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek) static gpg_error_t get_it (ctrl_t ctrl, - PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) + struct pubkey_enc_list *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) { gpg_error_t err; byte *frame = NULL; diff --git a/g10/test-stubs.c b/g10/test-stubs.c index e5fd3ae..088aba8 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -253,7 +253,7 @@ read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock) * No encryption here but mainproc links to these functions. */ gpg_error_t -get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek) +get_session_key (ctrl_t ctrl, struct pubkey_enc_list *k, DEK *dek) { (void)ctrl; (void)k; commit 2d6f17c776cd59bc747959711bcc43d61816f3d6 Author: NIIBE Yutaka Date: Thu Jun 7 10:28:00 2018 +0900 g10: Defer selection of decryption key at proc_encrypted. * g10/mainproc.c (struct kidlist_item): Remove REASON. Add DATA. (release_list): Release DATA. (proc_pubkey_enc): Don't get DEK here. (print_pkenc_list): Don't output failure reason here. (proc_encrypted): Get DEK here, and output failure reason. -- Signed-off-by: NIIBE Yutaka diff --git a/g10/mainproc.c b/g10/mainproc.c index 5689d73..d5fee73 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -52,7 +52,7 @@ struct kidlist_item struct kidlist_item *next; u32 kid[2]; int pubkey_algo; - int reason; + gcry_mpi_t data[2]; }; @@ -136,6 +136,9 @@ release_list( CTX c ) while (c->pkenc_list) { struct kidlist_item *tmp = c->pkenc_list->next; + + mpi_release (c->pkenc_list->data[0]); + mpi_release (c->pkenc_list->data[1]); xfree (c->pkenc_list); c->pkenc_list = tmp; } @@ -461,7 +464,7 @@ static void proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) { PKT_pubkey_enc *enc; - int result = 0; + struct kidlist_item *x = xmalloc (sizeof *x); /* Check whether the secret key is available and store in this case. */ c->last_was_session_key = 1; @@ -472,76 +475,27 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) if (opt.verbose) log_info (_("public key is %s\n"), keystr (enc->keyid)); - if (is_status_enabled()) + if (is_status_enabled ()) { char buf[50]; snprintf (buf, sizeof buf, "%08lX%08lX %d 0", - (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo); + (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo); write_status_text (STATUS_ENC_TO, buf); } - if (!opt.list_only && opt.override_session_key) - { - /* It does not make much sense to store the session key in - * secure memory because it has already been passed on the - * command line and the GCHQ knows about it. */ - c->dek = xmalloc_clear (sizeof *c->dek); - result = get_override_session_key (c->dek, opt.override_session_key); - if (result) - { - xfree (c->dek); - c->dek = NULL; - } - } - else if (enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E - || enc->pubkey_algo == PUBKEY_ALGO_ECDH - || enc->pubkey_algo == PUBKEY_ALGO_RSA - || enc->pubkey_algo == PUBKEY_ALGO_RSA_E - || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) - { - /* Note that we also allow type 20 Elgamal keys for decryption. - There are still a couple of those keys in active use as a - subkey. */ - - /* FIXME: Store this all in a list and process it later so that - we can prioritize what key to use. This gives a better user - experience if wildcard keyids are used. */ - if (!c->dek && ((!enc->keyid[0] && !enc->keyid[1]) - || opt.try_all_secrets - || have_secret_key_with_kid (enc->keyid))) - { - if(opt.list_only) - result = GPG_ERR_MISSING_ACTION; /* fixme: Use better error code. */ - else - { - c->dek = xmalloc_secure_clear (sizeof *c->dek); - if ((result = get_session_key (ctrl, enc, c->dek))) - { - /* Error: Delete the DEK. */ - xfree (c->dek); - c->dek = NULL; - } - } - } - else - result = GPG_ERR_NO_SECKEY; - } - else - result = GPG_ERR_PUBKEY_ALGO; - - if (1) + if (!opt.list_only && !opt.override_session_key) { - /* Store it for later display. */ - struct kidlist_item *x = xmalloc (sizeof *x); x->kid[0] = enc->keyid[0]; x->kid[1] = enc->keyid[1]; x->pubkey_algo = enc->pubkey_algo; - x->reason = result; + x->data[0] = x->data[1] = NULL; + if (enc->data[0]) + { + x->data[0] = mpi_copy (enc->data[0]); + x->data[1] = mpi_copy (enc->data[1]); + } x->next = c->pkenc_list; c->pkenc_list = x; - - if (!result && opt.verbose > 1) - log_info (_("public key encrypted data: good DEK\n")); } free_packet(pkt, NULL); @@ -553,18 +507,13 @@ proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) * not decrypt. */ static void -print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list, int failed) +print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list) { for (; list; list = list->next) { PKT_public_key *pk; const char *algstr; - if (failed && !list->reason) - continue; - if (!failed && list->reason) - continue; - algstr = openpgp_pk_algo_name (list->pubkey_algo); pk = xmalloc_clear (sizeof *pk); @@ -586,27 +535,6 @@ print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list, int failed) algstr, keystr(list->kid)); free_public_key (pk); - - if (gpg_err_code (list->reason) == GPG_ERR_NO_SECKEY) - { - if (is_status_enabled()) - { - char buf[20]; - snprintf (buf, sizeof buf, "%08lX%08lX", - (ulong)list->kid[0], (ulong)list->kid[1]); - write_status_text (STATUS_NO_SECKEY, buf); - } - } - else if (gpg_err_code (list->reason) == GPG_ERR_MISSING_ACTION) - { - /* Not tested for secret key due to --list-only mode. */ - } - else if (list->reason) - { - log_info (_("public key decryption failed: %s\n"), - gpg_strerror (list->reason)); - write_status_error ("pkdecrypt_failed", list->reason); - } } } @@ -614,6 +542,7 @@ print_pkenc_list (ctrl_t ctrl, struct kidlist_item *list, int failed) static void proc_encrypted (CTX c, PACKET *pkt) { + struct kidlist_item *item; int result = 0; if (!opt.quiet) @@ -622,11 +551,79 @@ proc_encrypted (CTX c, PACKET *pkt) log_info (_("encrypted with %lu passphrases\n"), c->symkeys); else if (c->symkeys == 1) log_info (_("encrypted with 1 passphrase\n")); - print_pkenc_list (c->ctrl, c->pkenc_list, 1 ); - print_pkenc_list (c->ctrl, c->pkenc_list, 0 ); + print_pkenc_list (c->ctrl, c->pkenc_list); + } + + /* Figure out the session key by looking at all pkenc packets. */ + if (opt.list_only) + ; + else if (opt.override_session_key) + { + c->dek = xmalloc_clear (sizeof *c->dek); + result = get_override_session_key (c->dek, opt.override_session_key); + if (result) + { + xfree (c->dek); + c->dek = NULL; + log_info (_("public key decryption failed: %s\n"), + gpg_strerror (result)); + write_status_error ("pkdecrypt_failed", result); + } + } + else + { + for (item = c->pkenc_list; item; item = item->next) + if (item->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E + || item->pubkey_algo == PUBKEY_ALGO_ECDH + || item->pubkey_algo == PUBKEY_ALGO_RSA + || item->pubkey_algo == PUBKEY_ALGO_RSA_E + || item->pubkey_algo == PUBKEY_ALGO_ELGAMAL) + { + if (((!item->kid[0] && !item->kid[1]) + || opt.try_all_secrets + || have_secret_key_with_kid (item->kid))) + { + PKT_pubkey_enc enc; + + enc.keyid[0] = item->kid[0]; + enc.keyid[1] = item->kid[1]; + enc.pubkey_algo = item->pubkey_algo; + enc.data[0] = item->data[0]; + enc.data[1] = item->data[1]; + + c->dek = xmalloc_secure_clear (sizeof *c->dek); + if (!(result = get_session_key (c->ctrl, &enc, c->dek))) + break; + + log_info (_("public key decryption failed: %s\n"), + gpg_strerror (result)); + write_status_error ("pkdecrypt_failed", result); + + /* Error: Delete the DEK. */ + xfree (c->dek); + c->dek = NULL; + } + else + { + if (is_status_enabled ()) + { + char buf[20]; + snprintf (buf, sizeof buf, "%08lX%08lX", + (ulong)item->kid[0], (ulong)item->kid[1]); + write_status_text (STATUS_NO_SECKEY, buf); + } + } + } + else + { + log_info (_("public key decryption failed: %s\n"), + gpg_strerror (GPG_ERR_PUBKEY_ALGO)); + write_status_error ("pkdecrypt_failed", GPG_ERR_PUBKEY_ALGO); + } } - /* FIXME: Figure out the session key by looking at all pkenc packets. */ + if (c->dek && opt.verbose > 1) + log_info (_("public key encrypted data: good DEK\n")); write_status (STATUS_BEGIN_DECRYPTION); ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 10:30:49 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 08 Jun 2018 10:30:49 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-54-gaf8510f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via af8510fb7f4d5c90cc53f10dcc740f377af73d68 (commit) from e48f4a18f807ee42b31968b84f6ae7811d8d8a45 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit af8510fb7f4d5c90cc53f10dcc740f377af73d68 Author: Andre Heinecke Date: Thu Jun 7 17:48:55 2018 +0200 json: Generalize chunking and getmore * src/gpgme-json.c (MIN_REPLY_CHUNK_SIZE): Lower value to new real minimum. (DEF_REPLY_CHUNK_SIZE): Don't chunk by default. (pending_data): Remove type and base64. (make_data_object): Remove chunksize handling as this is now generic. (encode_and_chunk): Setup the pending_data buffer for chunking if required. (op_getmore): Changed to generically work on a response. (hlp_getmore): Update accordingly. (hlp_help): Document chunksize as generic parameter for all commands. (process_request): Use encode_and_chunk on the response. (hlp_encrypt, op_encrypt, hlp_decrypt, op_decrypt), (hlp_verify, op_verify, hlp_sign, op_sign), (op_keylist, hlp_keylist, hlp_export, op_export): Update accordingly. -- To include handling for json properties e.g. in a keylist in the chunk mechanism the mechanism is now more general. If the chunksize property is provided the response will always look exactly like a "getmore" response. E.g. e.g.: { "op": "keylist", "chunksize": 64 } Results in: { "more": true, "base64": true, "response": "ewoJImtleXMiOglbewoJCQkicmV2b2tlZCI6" } For simplicity this is even true if the chunksize is larger then the response. The client has to combine all "response" chunks and base64 decode them to get valid json. The complete response (including json) is never larger then the chunksize but might be smaller. Except for interactive use due to additional format characters. diff --git a/src/gpgme-json.c b/src/gpgme-json.c index d3309b8..7bb1baf 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -48,14 +48,13 @@ int main (void){fputs ("Build with Libgpg-error >= 1.28!\n", stderr);return 1;} /* We don't allow a request with more than 64 MiB. */ #define MAX_REQUEST_SIZE (64 * 1024 * 1024) -/* Minimal, default and maximum chunk size for returned data. The - * first chunk is returned directly. If the "more" flag is also - * returned, a "getmore" command needs to be used to get the next - * chunk. Right now this value covers just the value of the "data" - * element; so to cover for the other returned objects this values - * needs to be lower than the maximum allowed size of the browser. */ -#define MIN_REPLY_CHUNK_SIZE 512 -#define DEF_REPLY_CHUNK_SIZE (512 * 1024) +/* Minimal chunk size for returned data.*/ +#define MIN_REPLY_CHUNK_SIZE 30 + +/* If no chunksize is provided we print everything. Changing + * this to a positive value will result in all messages beeing + * chunked. */ +#define DEF_REPLY_CHUNK_SIZE 0 #define MAX_REPLY_CHUNK_SIZE (10 * 1024 * 1024) @@ -67,6 +66,7 @@ static cjson_t error_object (cjson_t json, const char *message, ...) GPGRT_ATTR_PRINTF(2,3); static char *error_object_string (const char *message, ...) GPGRT_ATTR_PRINTF(1,2); +static char *process_request (const char *request); /* True if interactive mode is active. */ @@ -80,8 +80,6 @@ static struct char *buffer; /* Malloced data or NULL if not used. */ size_t length; /* Length of that data. */ size_t written; /* # of already written bytes from BUFFER. */ - const char *type;/* The "type" of the data. */ - int base64; /* The "base64" flag of the data. */ } pending_data; @@ -1336,29 +1334,20 @@ get_string_data (cjson_t request, cjson_t result, const char *name, } - -/* - * Implementation of the commands. - */ - - -/* Create a "data" object and the "type", "base64" and "more" flags +/* Create a "data" object and the "type" and "base64" flags * from DATA and append them to RESULT. Ownership of DATA is * transferred to this function. TYPE must be a fixed string. - * CHUNKSIZE is the chunksize requested from the caller. If BASE64 is - * -1 the need for base64 encoding is determined by the content of - * DATA, all other values are taken as true or false. Note that - * op_getmore has similar code but works on PENDING_DATA which is set - * here. */ + * If BASE64 is -1 the need for base64 encoding is determined + * by the content of DATA, all other values are taken as true + * or false. */ static gpg_error_t -make_data_object (cjson_t result, gpgme_data_t data, size_t chunksize, +make_data_object (cjson_t result, gpgme_data_t data, const char *type, int base64) { gpg_error_t err; char *buffer; const char *s; size_t buflen, n; - int c; if (!base64 || base64 == -1) /* Make sure that we really have a string. */ gpgme_data_write (data, "", 1); @@ -1390,49 +1379,98 @@ make_data_object (cjson_t result, gpgme_data_t data, size_t chunksize, } } - /* Adjust the chunksize if we need to do base64 conversion. */ - if (base64) - chunksize = (chunksize / 4) * 3; - xjson_AddStringToObject (result, "type", type); xjson_AddBoolToObject (result, "base64", base64); - if (buflen > chunksize) - { - xjson_AddBoolToObject (result, "more", 1); + if (base64) + err = add_base64_to_object (result, "data", buffer, buflen); + else + err = cjson_AddStringToObject (result, "data", buffer); - c = buffer[chunksize]; - buffer[chunksize] = 0; - if (base64) - err = add_base64_to_object (result, "data", buffer, chunksize); - else - err = cjson_AddStringToObject (result, "data", buffer); - buffer[chunksize] = c; - if (err) - goto leave; + leave: + gpgme_free (buffer); + return err; +} - pending_data.buffer = buffer; - buffer = NULL; - pending_data.length = buflen; - pending_data.written = chunksize; - pending_data.type = type; - pending_data.base64 = base64; - } + +/* Encode and chunk response. + * + * If neccessary this base64 encodes and chunks the repsonse + * for getmore so that we always return valid json independent + * of the chunksize. + * + * A chunked repsonse contains the base64 encoded chunk + * as a string and a boolean if there is still more data + * available for getmore like: + * { + * chunk: "SGVsbG8gV29ybGQK" + * more: true + * } + * + * Chunking is only done if the response is larger then the + * chunksize. + * + * caller has to xfree the return value. + */ +static char * +encode_and_chunk (cjson_t request, cjson_t response) +{ + char *data; + gpg_error_t err = 0; + size_t chunksize; + char *getmore_request = NULL; + + if (opt_interactive) + data = cJSON_Print (response); else + data = cJSON_PrintUnformatted (response); + + if (!data) + goto leave; + + if ((err = get_chunksize (request, &chunksize))) + goto leave; + + if (!chunksize) + goto leave; + + pending_data.buffer = data; + /* Data should already be encoded so that it does not + contain 0.*/ + pending_data.length = strlen (data); + pending_data.written = 0; + + if (gpgrt_asprintf (&getmore_request, + "{ \"op\":\"getmore\", \"chunksize\": %i }", + (int) chunksize) == -1) { - if (base64) - err = add_base64_to_object (result, "data", buffer, buflen); - else - err = cjson_AddStringToObject (result, "data", buffer); + err = gpg_error_from_syserror (); + goto leave; } - leave: - gpgme_free (buffer); - return err; + data = process_request (getmore_request); + +leave: + xfree (getmore_request); + + if (err) + { + cjson_t err_obj = gpg_error_object (NULL, err, + "Encode and chunk failed: %s", + gpgme_strerror (err)); + if (opt_interactive) + return cJSON_Print (err_obj); + return cJSON_PrintUnformatted (err_obj); + } + + return data; } +/* + * Implementation of the commands. + */ static const char hlp_encrypt[] = "op: \"encrypt\"\n" "keys: Array of strings with the fingerprints or user-ids\n" @@ -1442,7 +1480,6 @@ static const char hlp_encrypt[] = "\n" "Optional parameters:\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" - "chunksize: Max number of bytes in the resulting \"data\".\n" "signing_keys: Similar to the keys parameter for added signing.\n" " (openpgp only)" "\n" @@ -1462,8 +1499,7 @@ static const char hlp_encrypt[] = "data: Unless armor mode is used a Base64 encoded binary\n" " ciphertext. In armor mode a string with an armored\n" " OpenPGP or a PEM message.\n" - "base64: Boolean indicating whether data is base64 encoded.\n" - "more: Optional boolean indicating that \"getmore\" is required."; + "base64: Boolean indicating whether data is base64 encoded."; static gpg_error_t op_encrypt (cjson_t request, cjson_t result) { @@ -1471,7 +1507,6 @@ op_encrypt (cjson_t request, cjson_t result) gpgme_ctx_t ctx = NULL; gpgme_protocol_t protocol; char **signing_patterns = NULL; - size_t chunksize; int opt_mime; char *keystring = NULL; gpgme_data_t input = NULL; @@ -1484,8 +1519,6 @@ op_encrypt (cjson_t request, cjson_t result) if ((err = get_protocol (request, &protocol))) goto leave; ctx = get_context (protocol); - if ((err = get_chunksize (request, &chunksize))) - goto leave; if ((err = get_boolean_flag (request, "mime", 0, &opt_mime))) goto leave; @@ -1599,7 +1632,7 @@ op_encrypt (cjson_t request, cjson_t result) input = NULL; /* We need to base64 if armoring has not been requested. */ - err = make_data_object (result, output, chunksize, + err = make_data_object (result, output, "ciphertext", !gpgme_get_armor (ctx)); output = NULL; @@ -1623,7 +1656,6 @@ static const char hlp_decrypt[] = "\n" "Optional parameters:\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" - "chunksize: Max number of bytes in the resulting \"data\".\n" "\n" "Optional boolean flags (default is false):\n" "base64: Input data is base64 encoded.\n" @@ -1678,15 +1710,13 @@ static const char hlp_decrypt[] = " name\n" " value\n" " Number values:\n" - " flags\n" - "more: Optional boolean indicating that \"getmore\" is required."; + " flags\n"; static gpg_error_t op_decrypt (cjson_t request, cjson_t result) { gpg_error_t err; gpgme_ctx_t ctx = NULL; gpgme_protocol_t protocol; - size_t chunksize; gpgme_data_t input = NULL; gpgme_data_t output = NULL; gpgme_decrypt_result_t decrypt_result; @@ -1695,8 +1725,6 @@ op_decrypt (cjson_t request, cjson_t result) if ((err = get_protocol (request, &protocol))) goto leave; ctx = get_context (protocol); - if ((err = get_chunksize (request, &chunksize))) - goto leave; if ((err = get_string_data (request, result, "data", &input))) goto leave; @@ -1734,7 +1762,7 @@ op_decrypt (cjson_t request, cjson_t result) verify_result_to_json (verify_result)); } - err = make_data_object (result, output, chunksize, "plaintext", -1); + err = make_data_object (result, output, "plaintext", -1); output = NULL; if (err) @@ -1761,7 +1789,6 @@ static const char hlp_sign[] = "\n" "Optional parameters:\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" - "chunksize: Max number of bytes in the resulting \"data\".\n" "sender: The mail address of the sender.\n" "mode: A string with the signing mode can be:\n" " detached (default)\n" @@ -1777,15 +1804,13 @@ static const char hlp_sign[] = "data: Unless armor mode is used a Base64 encoded binary\n" " signature. In armor mode a string with an armored\n" " OpenPGP or a PEM message.\n" - "base64: Boolean indicating whether data is base64 encoded.\n" - "more: Optional boolean indicating that \"getmore\" is required."; + "base64: Boolean indicating whether data is base64 encoded.\n"; static gpg_error_t op_sign (cjson_t request, cjson_t result) { gpg_error_t err; gpgme_ctx_t ctx = NULL; gpgme_protocol_t protocol; - size_t chunksize; char **patterns = NULL; gpgme_data_t input = NULL; gpgme_data_t output = NULL; @@ -1798,8 +1823,6 @@ op_sign (cjson_t request, cjson_t result) if ((err = get_protocol (request, &protocol))) goto leave; ctx = get_context (protocol); - if ((err = get_chunksize (request, &chunksize))) - goto leave; if ((err = get_boolean_flag (request, "armor", 0, &abool))) goto leave; @@ -1881,7 +1904,7 @@ op_sign (cjson_t request, cjson_t result) input = NULL; /* We need to base64 if armoring has not been requested. */ - err = make_data_object (result, output, chunksize, + err = make_data_object (result, output, "signature", !gpgme_get_armor (ctx)); output = NULL; @@ -1904,7 +1927,6 @@ static const char hlp_verify[] = "\n" "Optional parameters:\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" - "chunksize: Max number of bytes in the resulting \"data\".\n" "signature: A detached signature. If missing opaque is assumed.\n" "\n" "Optional boolean flags (default is false):\n" @@ -1959,15 +1981,13 @@ static const char hlp_verify[] = " name\n" " value\n" " Number values:\n" - " flags\n" - "more: Optional boolean indicating that \"getmore\" is required."; + " flags\n"; static gpg_error_t op_verify (cjson_t request, cjson_t result) { gpg_error_t err; gpgme_ctx_t ctx = NULL; gpgme_protocol_t protocol; - size_t chunksize; gpgme_data_t input = NULL; gpgme_data_t signature = NULL; gpgme_data_t output = NULL; @@ -1976,8 +1996,6 @@ op_verify (cjson_t request, cjson_t result) if ((err = get_protocol (request, &protocol))) goto leave; ctx = get_context (protocol); - if ((err = get_chunksize (request, &chunksize))) - goto leave; if ((err = get_string_data (request, result, "data", &input))) goto leave; @@ -2022,7 +2040,7 @@ op_verify (cjson_t request, cjson_t result) verify_result_to_json (verify_result)); } - err = make_data_object (result, output, chunksize, "plaintext", -1); + err = make_data_object (result, output, "plaintext", -1); output = NULL; if (err) @@ -2097,7 +2115,6 @@ static const char hlp_keylist[] = " For a single key a String may be used instead of an array.\n" " default lists all keys.\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" - "chunksize: Max number of bytes in the resulting \"data\".\n" "\n" "Optional boolean flags (default is false):\n" "secret: List secret keys.\n" @@ -2215,16 +2232,13 @@ static const char hlp_keylist[] = " signfirst\n" " signlast\n" " encrfirst\n" - " encrlast\n" - "more: Optional boolean indicating that \"getmore\" is required.\n" - " (not implemented)"; + " encrlast\n"; static gpg_error_t op_keylist (cjson_t request, cjson_t result) { gpg_error_t err; gpgme_ctx_t ctx = NULL; gpgme_protocol_t protocol; - size_t chunksize; char **patterns = NULL; int abool; gpgme_keylist_mode_t mode = 0; @@ -2234,8 +2248,6 @@ op_keylist (cjson_t request, cjson_t result) if ((err = get_protocol (request, &protocol))) goto leave; ctx = get_context (protocol); - if ((err = get_chunksize (request, &chunksize))) - goto leave; /* Handle the various keylist mode bools. */ if ((err = get_boolean_flag (request, "secret", 0, &abool))) @@ -2406,7 +2418,6 @@ static const char hlp_export[] = " For a single key a String may be used instead of an array.\n" " default exports all keys.\n" "protocol: Either \"openpgp\" (default) or \"cms\".\n" - "chunksize: Max number of bytes in the resulting \"data\".\n" "\n" "Optional boolean flags (default is false):\n" "armor: Request output in armored format.\n" @@ -2420,15 +2431,13 @@ static const char hlp_export[] = "data: Unless armor mode is used a Base64 encoded binary.\n" " In armor mode a string with an armored\n" " OpenPGP or a PEM / PKCS12 key.\n" - "base64: Boolean indicating whether data is base64 encoded.\n" - "more: Optional boolean indicating that \"getmore\" is required."; + "base64: Boolean indicating whether data is base64 encoded.\n"; static gpg_error_t op_export (cjson_t request, cjson_t result) { gpg_error_t err; gpgme_ctx_t ctx = NULL; gpgme_protocol_t protocol; - size_t chunksize; char **patterns = NULL; int abool; gpgme_export_mode_t mode = 0; @@ -2437,8 +2446,6 @@ op_export (cjson_t request, cjson_t result) if ((err = get_protocol (request, &protocol))) goto leave; ctx = get_context (protocol); - if ((err = get_chunksize (request, &chunksize))) - goto leave; if ((err = get_boolean_flag (request, "armor", 0, &abool))) goto leave; @@ -2495,7 +2502,7 @@ op_export (cjson_t request, cjson_t result) } /* We need to base64 if armoring has not been requested. */ - err = make_data_object (result, output, chunksize, + err = make_data_object (result, output, "keys", !gpgme_get_armor (ctx)); output = NULL; @@ -2765,14 +2772,10 @@ leave: static const char hlp_getmore[] = "op: \"getmore\"\n" "\n" - "Optional parameters:\n" - "chunksize: Max number of bytes in the \"data\" object.\n" - "\n" "Response on success:\n" - "type: Type of the pending data\n" - "data: The next chunk of data\n" - "base64: Boolean indicating whether data is base64 encoded\n" - "more: Optional boolean requesting another \"getmore\"."; + "response: base64 encoded json response.\n" + "more: Another getmore is required.\n" + "base64: boolean if the response is base64 encoded.\n"; static gpg_error_t op_getmore (cjson_t request, cjson_t result) { @@ -2784,9 +2787,12 @@ op_getmore (cjson_t request, cjson_t result) if ((err = get_chunksize (request, &chunksize))) goto leave; - /* Adjust the chunksize if we need to do base64 conversion. */ - if (pending_data.base64) - chunksize = (chunksize / 4) * 3; + /* For the meta data we need 41 bytes: + {"more":true,"base64":true,"response":""} */ + chunksize -= 41; + + /* Adjust the chunksize for the base64 conversion. */ + chunksize = (chunksize / 4) * 3; /* Do we have anything pending? */ if (!pending_data.buffer) @@ -2797,8 +2803,8 @@ op_getmore (cjson_t request, cjson_t result) goto leave; } - xjson_AddStringToObject (result, "type", pending_data.type); - xjson_AddBoolToObject (result, "base64", pending_data.base64); + /* We currently always use base64 encoding for simplicity. */ + xjson_AddBoolToObject (result, "base64", 1); if (pending_data.written >= pending_data.length) { @@ -2807,7 +2813,7 @@ op_getmore (cjson_t request, cjson_t result) gpgme_free (pending_data.buffer); pending_data.buffer = NULL; xjson_AddBoolToObject (result, "more", 0); - err = cjson_AddStringToObject (result, "data", ""); + err = cjson_AddStringToObject (result, "response", ""); } else { @@ -2822,21 +2828,16 @@ op_getmore (cjson_t request, cjson_t result) c = pending_data.buffer[pending_data.written + n]; pending_data.buffer[pending_data.written + n] = 0; - if (pending_data.base64) - err = add_base64_to_object (result, "data", - (pending_data.buffer - + pending_data.written), n); - else - err = cjson_AddStringToObject (result, "data", - (pending_data.buffer - + pending_data.written)); + err = add_base64_to_object (result, "response", + (pending_data.buffer + + pending_data.written), n); pending_data.buffer[pending_data.written + n] = c; if (!err) { pending_data.written += n; if (pending_data.written >= pending_data.length) { - gpgme_free (pending_data.buffer); + xfree (pending_data.buffer); pending_data.buffer = NULL; } } @@ -2866,8 +2867,15 @@ static const char hlp_help[] = " sign Sign data.\n" " verify Verify data.\n" " version Get engine information.\n" - " getmore Retrieve remaining data.\n" - " help Help overview."; + " getmore Retrieve remaining data if chunksize was used.\n" + " help Help overview.\n" + "\n" + "If the data needs to be transferred in smaller chunks the\n" + "property \"chunksize\" with an integer value can be added.\n" + "When \"chunksize\" is set the response (including json) will\n" + "not be larger then \"chunksize\" but might be smaller.\n" + "The chunked result will be transferred in base64 encoded chunks\n" + "using the \"getmore\" operation. See help getmore for more info."; static gpg_error_t op_help (cjson_t request, cjson_t result) { @@ -2924,6 +2932,7 @@ process_request (const char *request) cjson_t j_tmp, j_op; cjson_t response; int helpmode; + int is_getmore = 0; const char *op; char *res; int idx; @@ -2969,7 +2978,7 @@ process_request (const char *request) else { gpg_error_t err; - + is_getmore = optbl[idx].handler == op_getmore; /* If this is not the "getmore" command and we have any * pending data release that data. */ if (pending_data.buffer && optbl[idx].handler != op_getmore) @@ -3001,13 +3010,20 @@ process_request (const char *request) } leave: - cJSON_Delete (json); - if (opt_interactive) - res = cJSON_Print (response); + if (is_getmore) + { + /* For getmore we bypass the encode_and_chunk. */ + if (opt_interactive) + res = cJSON_Print (response); + else + res = cJSON_PrintUnformatted (response); + } else - res = cJSON_PrintUnformatted (response); + res = encode_and_chunk (json, response); if (!res) log_error ("Printing JSON data failed\n"); + + cJSON_Delete (json); cJSON_Delete (response); return res; } ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 266 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 141 insertions(+), 125 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 10:54:31 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 10:54:31 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-144-g13f135c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 13f135c7a252cc46cff96e75968d92b6dc8dce1b (commit) from 26746fe65d14a00773473c2d0d271406a5105bca (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 13f135c7a252cc46cff96e75968d92b6dc8dce1b Author: Werner Koch Date: Fri Jun 8 10:45:21 2018 +0200 gpg: Sanitize diagnostic with the original file name. * g10/mainproc.c (proc_plaintext): Sanitize verbose output. -- This fixes a forgotten sanitation of user supplied data in a verbose mode diagnostic. The mention CVE is about using this to inject status-fd lines into the stderr output. Other harm good as well be done. Note that GPGME based applications are not affected because GPGME does not fold status output into stderr. CVE-id: CVE-2018-12020 GnuPG-bug-id: 4012 diff --git a/g10/mainproc.c b/g10/mainproc.c index d2ceec2..a9da08f 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -851,7 +851,14 @@ proc_plaintext( CTX c, PACKET *pkt ) if (pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8)) log_info (_("Note: sender requested \"for-your-eyes-only\"\n")); else if (opt.verbose) - log_info (_("original file name='%.*s'\n"), pt->namelen, pt->name); + { + /* We don't use print_utf8_buffer because that would require a + * string change which we don't want in 2.2. It is also not + * clear whether the filename is always utf-8 encoded. */ + char *tmp = make_printable_string (pt->name, pt->namelen, 0); + log_info (_("original file name='%.*s'\n"), (int)strlen (tmp), tmp); + xfree (tmp); + } free_md_filter_context (&c->mfx); if (gcry_md_open (&c->mfx.md, 0, 0)) ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 10:54:51 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 10:54:51 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-19-g210e402 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 210e402acd3e284b32db1901e43bf1470e659e49 (commit) from 6a87a0bd2501d82f4a6263608e4856e841305caf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 210e402acd3e284b32db1901e43bf1470e659e49 Author: Werner Koch Date: Fri Jun 8 10:45:21 2018 +0200 gpg: Sanitize diagnostic with the original file name. * g10/mainproc.c (proc_plaintext): Sanitize verbose output. -- This fixes a forgotten sanitation of user supplied data in a verbose mode diagnostic. The mention CVE is about using this to inject status-fd lines into the stderr output. Other harm good as well be done. Note that GPGME based applications are not affected because GPGME does not fold status output into stderr. CVE-id: CVE-2018-12020 GnuPG-bug-id: 4012 (cherry picked from commit 13f135c7a252cc46cff96e75968d92b6dc8dce1b) diff --git a/g10/mainproc.c b/g10/mainproc.c index 116b72a..72b0dd8 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -758,7 +758,14 @@ proc_plaintext( CTX c, PACKET *pkt ) if (pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8)) log_info (_("Note: sender requested \"for-your-eyes-only\"\n")); else if (opt.verbose) - log_info (_("original file name='%.*s'\n"), pt->namelen, pt->name); + { + /* We don't use print_utf8_buffer because that would require a + * string change which we don't want in 2.2. It is also not + * clear whether the filename is always utf-8 encoded. */ + char *tmp = make_printable_string (pt->name, pt->namelen, 0); + log_info (_("original file name='%.*s'\n"), (int)strlen (tmp), tmp); + xfree (tmp); + } free_md_filter_context (&c->mfx); if (gcry_md_open (&c->mfx.md, 0, 0)) ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 11:01:09 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 11:01:09 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.22-15-g2326851 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 2326851c60793653069494379b16d84e4c10a0ac (commit) from 0f8fd95ab32a6d29dac79e19f0850037c7d0c16f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2326851c60793653069494379b16d84e4c10a0ac Author: Werner Koch Date: Fri Jun 8 10:45:21 2018 +0200 gpg: Sanitize diagnostic with the original file name. * g10/mainproc.c (proc_plaintext): Sanitize verbose output. -- This fixes a forgotten sanitation of user supplied data in a verbose mode diagnostic. The mention CVE is about using this to inject status-fd lines into the stderr output. Other harm good as well be done. Note that GPGME based applications are not affected because GPGME does not fold status output into stderr. CVE-id: CVE-2018-12020 GnuPG-bug-id: 4012 (cherry picked from commit 13f135c7a252cc46cff96e75968d92b6dc8dce1b) diff --git a/g10/mainproc.c b/g10/mainproc.c index 33a654b..ffa7ef6 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -638,7 +638,11 @@ proc_plaintext( CTX c, PACKET *pkt ) if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) log_info(_("NOTE: sender requested \"for-your-eyes-only\"\n")); else if( opt.verbose ) - log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name); + { + char *tmp = make_printable_string (pt->name, pt->namelen, 0); + log_info (_("original file name='%.*s'\n"), (int)strlen (tmp), tmp); + xfree (tmp); + } free_md_filter_context( &c->mfx ); c->mfx.md = md_open( 0, 0); /* fixme: we may need to push the textfilter if we have sigclass 1 ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 12:58:23 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 12:58:23 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.7-24-ge9667dd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via e9667dd20a3a71c0a51d20ac4b1aa758e5bb5ada (commit) via cd9aaa7862955846f8adf819cd89d0db33e9c08c (commit) via 8e589300e37172649efe35d1dbfae1069c2ff9fd (commit) via ea36e637224f57cdd4b847484b6b9b790f48ad2d (commit) via 77ab99f80a5b0fbc60e05230185a54cd200d5e65 (commit) from 210e402acd3e284b32db1901e43bf1470e659e49 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e9667dd20a3a71c0a51d20ac4b1aa758e5bb5ada Author: Werner Koch Date: Fri Jun 8 12:47:19 2018 +0200 Post release updates -- diff --git a/NEWS b/NEWS index 41ba31d..7b34436 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.2.9 (unreleased) +------------------------------------------------ + + Noteworthy changes in version 2.2.8 (2018-06-08) ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 59a2e60..f77317f 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ min_automake_version="1.14" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [2]) -m4_define([mym4_micro], [8]) +m4_define([mym4_micro], [9]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release commit cd9aaa7862955846f8adf819cd89d0db33e9c08c Author: Werner Koch Date: Fri Jun 8 11:53:00 2018 +0200 Release 2.2.8 Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index bf1ca41..41ba31d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,30 @@ -Noteworthy changes in version 2.2.8 (unreleased) +Noteworthy changes in version 2.2.8 (2018-06-08) ------------------------------------------------ + * gpg: Decryption of messages not using the MDC mode will now lead + to a hard failure even if a legacy cipher algorithm was used. The + option --ignore-mdc-error can be used to turn this failure into a + warning. Take care: Never use that option unconditionally or + without a prior warning. + + * gpg: The MDC encryption mode is now always used regardless of the + cipher algorithm or any preferences. For testing --rfc2440 can be + used to create a message without an MDC. + + * gpg: Sanitize the diagnostic output of the original file name in + verbose mode. [#4012,CVE-2018-12020] + + * gpg: Detect suspicious multiple plaintext packets in a more + reliable way. [#4000] + + * gpg: Fix the duplicate key signature detection code. [#3994] + + * gpg: The options --no-mdc-warn, --force-mdc, --no-force-mdc, + --disable-mdc and --no-disable-mdc have no more effect. + + * agent: Add DBUS_SESSION_BUS_ADDRESS and a few other envvars to the + list of startup environment variables. [#3947] + Noteworthy changes in version 2.2.7 (2018-05-02) ------------------------------------------------ commit 8e589300e37172649efe35d1dbfae1069c2ff9fd Author: Werner Koch Date: Fri Jun 8 11:24:36 2018 +0200 po: Auto update -- diff --git a/po/ca.po b/po/ca.po index 31c20ad..8f0d762 100644 --- a/po/ca.po +++ b/po/ca.po @@ -4744,6 +4744,9 @@ msgstr "xifrat amb una clau %s, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "ha fallat el desxifratge amb la clau p?blica: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "xifrat amb %lu contrasenyes\n" @@ -4768,6 +4771,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "AV?S: el missatge no tenia protecci? d'integritat\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "ha fallat el desxifratge: %s\n" + msgid "decryption okay\n" msgstr "desxifratge correcte\n" @@ -4787,9 +4805,6 @@ msgstr "NOTA: el remitent ha sol?licitat \"alt secret\"\n" msgid "original file name='%.*s'\n" msgstr "nom del fitxer original='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "revocaci? aut?noma: useu \"gpg --import\" per a aplicar-la\n" diff --git a/po/cs.po b/po/cs.po index 06f91b1..b9edcb2 100644 --- a/po/cs.po +++ b/po/cs.po @@ -4358,6 +4358,9 @@ msgstr "za?ifrov?no %s kl??em, ID %s\n" msgid "public key decryption failed: %s\n" msgstr "de?ifrov?n? ve?ejn?m kl??em selhalo: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "VAROV?N?: zachyceno v?ce prost?ch text?\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "za?ifrov?no s heslem %lu\n" @@ -4378,6 +4381,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "VAROV?N?: zpr?va nebyla chr?n?na proti poru?en? jej? integrity\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "de?ifrov?n? selhalo: %s\n" + msgid "decryption okay\n" msgstr "de?ifrov?n? o.k.\n" @@ -4396,9 +4414,6 @@ msgstr "" msgid "original file name='%.*s'\n" msgstr "p?vodn? jm?no souboru='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "VAROV?N?: zachyceno v?ce prost?ch text?\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "samostatn? revoka?n? certifik?t?? pou?ijte ?gpg --import?, chcete-li jej " diff --git a/po/da.po b/po/da.po index 74951b0..4cb4e44 100644 --- a/po/da.po +++ b/po/da.po @@ -4650,6 +4650,9 @@ msgstr "krypteret med %s n?gle, id %s\n" msgid "public key decryption failed: %s\n" msgstr "afkryptering af offentlig n?gle mislykkedes: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "ADVARSEL: flere klartekster set\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "krypteret med %lu adgangsfraser\n" @@ -4669,6 +4672,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "ADVARSEL: besked var ikke integritetsbeskyttet\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "afkryptering mislykkedes: %s\n" + msgid "decryption okay\n" msgstr "afkryptering okay\n" @@ -4688,9 +4706,6 @@ msgstr "BEM?RK: afsender anmodte om ?for-your-eyes-only?\n" msgid "original file name='%.*s'\n" msgstr "oprindeligt filnavn=?%.*s?\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "ADVARSEL: flere klartekster set\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "uafh?ngig tilbagekald - brug ?gpg --import? for at anvende\n" diff --git a/po/el.po b/po/el.po index 3300d5c..b754131 100644 --- a/po/el.po +++ b/po/el.po @@ -4640,6 +4640,9 @@ msgstr "??????????????? ?? %s key, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "????????????? ?? ??????? ?????? ???????: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "??????????????? ?? %lu ??????? ???????\n" @@ -4660,6 +4663,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "?????????????: ??? ????????????? ? ??????????? ??? ????????\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "???????????????? ???????: %s\n" + msgid "decryption okay\n" msgstr "???????????????? OK\n" @@ -4679,9 +4697,6 @@ msgstr "????????: ? ?????????? ?????? \"???-??-? msgid "original file name='%.*s'\n" msgstr "?????? ????? ???????='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "?????????? ???????? - ??????????????? \"gpg --import\" ??? ????????\n" diff --git a/po/eo.po b/po/eo.po index fb797f0..de229ff 100644 --- a/po/eo.po +++ b/po/eo.po @@ -4615,6 +4615,9 @@ msgstr "?ifrita per %s-?losilo, %08lX\n" msgid "public key decryption failed: %s\n" msgstr "publik?losila mal?ifrado malsukcesis: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, fuzzy, c-format msgid "encrypted with %lu passphrases\n" msgstr "Ripetu pasfrazon\n" @@ -4635,6 +4638,21 @@ msgstr "?ifro IDEA ne disponata, optimisme provas uzi %s anstata?e\n" msgid "WARNING: message was not integrity protected\n" msgstr "AVERTO: nenio estis eksportita\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "mal?ifrado malsukcesis: %s\n" + msgid "decryption okay\n" msgstr "mal?ifrado sukcesis\n" @@ -4654,9 +4672,6 @@ msgstr "NOTO: sendinto petis konfidencon (\"for-your-eyes-only\")\n" msgid "original file name='%.*s'\n" msgstr "originala dosiernomo='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "memstara revoko - uzu \"gpg --import\" por apliki ?in\n" diff --git a/po/es.po b/po/es.po index 4f657af..289e5c4 100644 --- a/po/es.po +++ b/po/es.po @@ -1519,7 +1519,6 @@ msgstr "desbloquear PIN usando C?digo de Reinicio" msgid "destroy all keys and data" msgstr "destruir todas las claves y datos" -#| msgid "|NAME|use user NAME for authentication" msgid "setup KDF for PIN authentication" msgstr "configurar KDF para autentificaci?n de PIN" @@ -4328,6 +4327,9 @@ msgstr "cifrado con clave %s, ID %s\n" msgid "public key decryption failed: %s\n" msgstr "descifrado de la clave p?blica fallido: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "AVISO: se observan varios textos en claro\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "cifrado con %lu frases contrase?a\n" @@ -4347,6 +4349,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "ATENCI?N: la intgridad del mensaje no est? protegida\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "descifrado fallido: %s\n" + msgid "decryption okay\n" msgstr "descifrado correcto\n" @@ -4364,9 +4381,6 @@ msgstr "Atenci?n: el remitente solicit? \"s?lo-para-tus-ojos\"\n" msgid "original file name='%.*s'\n" msgstr "nombre fichero original='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "AVISO: se observan varios textos en claro\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "revocaci?n independiente - use \"gpg --import\" para aplicarla\n" @@ -5214,7 +5228,6 @@ msgid "Note: signature key %s has been revoked\n" msgstr "NOTA: la clave de firmado %s ha sido revocada\n" #, c-format -#| msgid "standalone signature of class 0x%02x\n" msgid "bad key signature from key %s: %s (0x%02x, 0x%x)\n" msgstr "firma incorrecta de la clave %s: %s (0x%02x, 0x%x)\n" diff --git a/po/et.po b/po/et.po index e540035..6db3544 100644 --- a/po/et.po +++ b/po/et.po @@ -4592,6 +4592,9 @@ msgstr "kr?pteeritud %s v?tmega, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "avaliku v?tmega lahtikr?pteerimine eba?nnestus: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "kr?pteeritud kasutades %lu parooli\n" @@ -4610,6 +4613,21 @@ msgstr "IDEA ?iffer pole saadaval, loodan kasutada selle asemel %s\n" msgid "WARNING: message was not integrity protected\n" msgstr "HOIATUS: teate koosk?lalisus ei ole tagatud\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "lahtikr?pteerimine eba?nnestus: %s\n" + msgid "decryption okay\n" msgstr "lahtikr?pteerimine ?nnestus\n" @@ -4629,9 +4647,6 @@ msgstr "M?RKUS: saatja n?udis \"ainult-teie-silmadele\"\n" msgid "original file name='%.*s'\n" msgstr "algne failinimi on='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "eraldiseisev t?histus - realiseerimiseks kasutage \"gpg --import\"\n" diff --git a/po/fi.po b/po/fi.po index 717f85b..a62bdd2 100644 --- a/po/fi.po +++ b/po/fi.po @@ -4622,6 +4622,9 @@ msgstr "salattu %s-avaimella, tunnus %08lX\n" msgid "public key decryption failed: %s\n" msgstr "julkisen avaimen avaus ep?onnistui: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "salattu %lu salasanalla\n" @@ -4642,6 +4645,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "VAROITUS: viestin eheytt? ei oltu suojattu\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "avaus ep?onnistui: %s\n" + msgid "decryption okay\n" msgstr "avaus onnistui\n" @@ -4661,9 +4679,6 @@ msgstr "HUOM: l?hett?j? m??ritt?? \"vain-sinun-silmillesi\"\n" msgid "original file name='%.*s'\n" msgstr "alkuper?isen tiedoston nimi=\"%.*s\"\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "itsen?inen mit?t?inti - k?yt? \"gpg --import\" ottaaksesi k?ytt??n\n" diff --git a/po/fr.po b/po/fr.po index a8a0a4b..b82b59b 100644 --- a/po/fr.po +++ b/po/fr.po @@ -4523,6 +4523,9 @@ msgstr "chiffr? avec une clef %s, identifiant %s\n" msgid "public key decryption failed: %s\n" msgstr "?chec du d?chiffrement par clef publique?: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "Attention?: plusieurs textes en clair ont ?t? vus\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "chiffr? avec %lu?phrases secr?tes\n" @@ -4543,6 +4546,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "Attention?: l'int?grit? du message n'?tait pas prot?g?e\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "?chec du d?chiffrement?: %s\n" + msgid "decryption okay\n" msgstr "le d?chiffrement a r?ussi\n" @@ -4560,9 +4578,6 @@ msgstr "Remarque?: l'exp?diteur a demand? ??? votre seule attention??\n" msgid "original file name='%.*s'\n" msgstr "nom de fichier original?: ??%.*s??\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "Attention?: plusieurs textes en clair ont ?t? vus\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "r?vocation autonome ??utilisez ??gpg --import?? pour l'appliquer\n" diff --git a/po/gl.po b/po/gl.po index 51120cb..ce840ff 100644 --- a/po/gl.po +++ b/po/gl.po @@ -4639,6 +4639,9 @@ msgstr "cifrado cunha chave %s, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "fallou o descifrado de chave p?blica: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "cifrado con %lu contrasinais\n" @@ -4657,6 +4660,21 @@ msgstr "A cifra IDEA non est? dispo?ible, t?ntase empregar %s no seu canto\n" msgid "WARNING: message was not integrity protected\n" msgstr "AVISO: a mensaxe non ti?a protecci?n de integridade\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "o descifrado fallou: %s\n" + msgid "decryption okay\n" msgstr "descifrado correcto\n" @@ -4676,9 +4694,6 @@ msgstr "NOTA: o remitente pediu \"confidencial\"\n" msgid "original file name='%.*s'\n" msgstr "nome do ficheiro orixinal='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "revocaci?n independente - empregue \"gpg --import\" para aplicar\n" diff --git a/po/hu.po b/po/hu.po index 9281c1d..2485e38 100644 --- a/po/hu.po +++ b/po/hu.po @@ -4604,6 +4604,9 @@ msgstr "Titkos?tva %s kulccsal, azonos?t?: %08lX\n" msgid "public key decryption failed: %s\n" msgstr "Nyilv?nos kulcs? visszafejt?s sikertelen: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "%lu jelsz?val rejtjelezve\n" @@ -4624,6 +4627,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "FIGYELEM: Az ?zenetet nem l?tt?k el integrit?sv?delemmel.\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "Visszafejt?s sikertelen: %s.\n" + msgid "decryption okay\n" msgstr "Visszafejt?s rendben.\n" @@ -4643,9 +4661,6 @@ msgstr "MEGJEGYZ?S: A felad? k?r?se: \"csak az ?n szemeinek\".\n" msgid "original file name='%.*s'\n" msgstr "Eredeti f?jln?v: '%.*s'.\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "K?l?n?ll? visszavon?s. Haszn?lja a \"gpg --import\"-ot az alkalmaz?s?hoz!\n" diff --git a/po/id.po b/po/id.po index bc605ff..cc5d4c1 100644 --- a/po/id.po +++ b/po/id.po @@ -4606,6 +4606,9 @@ msgstr "dienkripsi dengan kunci %s, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "gagal dekripsi kunci publik: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "dienkripsi dengan passphrase %lu\n" @@ -4624,6 +4627,21 @@ msgstr "Cipher IDEA tidak tersedia, secara optimis berusaha menggunakan %s\n" msgid "WARNING: message was not integrity protected\n" msgstr "PERINGATAN: integritas pesan tidak terlindungi\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "dekripsi gagal: %s\n" + msgid "decryption okay\n" msgstr "dekripsi lancar\n" @@ -4643,9 +4661,6 @@ msgstr "CATATAN: pengirim meminta \"for-your-eyes-only\"\n" msgid "original file name='%.*s'\n" msgstr "original file name='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "pembatalan mandiri - gunakan \"gpg --import\" untuk mengaplikasikan\n" diff --git a/po/it.po b/po/it.po index 2358ef5..1279200 100644 --- a/po/it.po +++ b/po/it.po @@ -4624,6 +4624,9 @@ msgstr "Cifrato con la chiave %s con ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "decifratura della chiave pubblica fallita: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "cifratto con %lu passphrase\n" @@ -4642,6 +4645,21 @@ msgstr "Cifrario IDEA non disponibile, ottimisticamente cerco di usare %s\n" msgid "WARNING: message was not integrity protected\n" msgstr "ATTENZIONE: l'integrit? del messaggio non era protetta\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "decifratura fallita: %s\n" + msgid "decryption okay\n" msgstr "decifratura corretta\n" @@ -4661,9 +4679,6 @@ msgstr "NOTA: il mittente ha richiesto \"solo-per-i-tuoi-occhi\"\n" msgid "original file name='%.*s'\n" msgstr "nome del file originale='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "revoca solitaria - usa \"gpg --import\" per applicarla\n" diff --git a/po/ja.po b/po/ja.po index d2b4c7e..62afcef 100644 --- a/po/ja.po +++ b/po/ja.po @@ -4229,6 +4229,9 @@ msgstr "%s?, ID %s?????????\n" msgid "public key decryption failed: %s\n" msgstr "?????????????: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "*??*: ?????????????????\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "%lu ????????????\n" @@ -4247,6 +4250,21 @@ msgstr "IDEA???????????????????%s??? msgid "WARNING: message was not integrity protected\n" msgstr "*??*: ???????????????????\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "?????????: %s\n" + msgid "decryption okay\n" msgstr "?????\n" @@ -4264,9 +4282,6 @@ msgstr "??: ????\"?????\"?????????\n" msgid "original file name='%.*s'\n" msgstr "???????='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "*??*: ?????????????????\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "????????? - \"gpg --import\"????????????\n" diff --git a/po/nb.po b/po/nb.po index c6694e7..0d65de9 100644 --- a/po/nb.po +++ b/po/nb.po @@ -4306,6 +4306,9 @@ msgstr "kryptert med %s-n?kkel, ID %s\n" msgid "public key decryption failed: %s\n" msgstr "offentlig n?kkel-dekryptering mislyktes: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "ADVARSEL: fant flere elementer i ren tekst\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "kryptert med %lu passordfraser\n" @@ -4324,6 +4327,21 @@ msgstr "IDEA-kryptering er utilgjengelig. Pr?ver ? bruke %s i stedet\n" msgid "WARNING: message was not integrity protected\n" msgstr "ADVARSEL: meldinga var ikke integritetsbeskyttet\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "dekryptering mislyktes: %s\n" + msgid "decryption okay\n" msgstr "dekryptering ok\n" @@ -4341,9 +4359,6 @@ msgstr "Merk: senderen spesifiserte ?kun for dine ?yne?\n" msgid "original file name='%.*s'\n" msgstr "opprinnelig filnavn=?%.*s?\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "ADVARSEL: fant flere elementer i ren tekst\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "selvstendig opphevelse - bruk ?gpg --import? for ? ta i bruk\n" diff --git a/po/pl.po b/po/pl.po index 801cf2e..8f9183e 100644 --- a/po/pl.po +++ b/po/pl.po @@ -4673,6 +4673,9 @@ msgstr "zaszyfrowano kluczem %s o identyfikatorze %s\n" msgid "public key decryption failed: %s\n" msgstr "b??d odszyfrowywania kluczem publicznym: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "OSTRZE?ENIE: widziano wiele czystych tekst?w\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "zaszyfrowane za pomoc? %lu hase?\n" @@ -4691,6 +4694,21 @@ msgstr "szyfr IDEA nie jest dost?pny, pr?ba u?ycia %s zamiast niego\n" msgid "WARNING: message was not integrity protected\n" msgstr "OSTRZE?ENIE: wiadomo?? nie by?a zabezpieczona przed manipulacj?\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "b??d odszyfrowywania: %s\n" + msgid "decryption okay\n" msgstr "odszyfrowanie poprawne\n" @@ -4710,9 +4728,6 @@ msgstr "UWAGA: nadawca zaznaczy? ?e wiadomo?? nie powinna by? zapisywana\n" msgid "original file name='%.*s'\n" msgstr "pierwotna nazwa pliku='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "OSTRZE?ENIE: widziano wiele czystych tekst?w\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "osobny certyfikat uniewa?nienia - u?yj ,,gpg --import'' aby go wczyta?\n" diff --git a/po/pt.po b/po/pt.po index 91b384f..aec51df 100644 --- a/po/pt.po +++ b/po/pt.po @@ -4612,6 +4612,9 @@ msgstr "cifrado com chave %s, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "decifragem de chave p?blica falhou: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, fuzzy, c-format msgid "encrypted with %lu passphrases\n" msgstr "Repita a frase secreta\n" @@ -4631,6 +4634,21 @@ msgstr "Cifra IDEO n?o dispon?vel, a tentar utilizar %s em substitui??o\n" msgid "WARNING: message was not integrity protected\n" msgstr "AVISO: a mensagem n?o tinha a sua integridade protegida\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "decifragem falhou: %s\n" + msgid "decryption okay\n" msgstr "decifragem correcta\n" @@ -4650,9 +4668,6 @@ msgstr "NOTA: o remetente solicitou \"apenas-para-seus-olhos\"\n" msgid "original file name='%.*s'\n" msgstr "nome do ficheiro original='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "revoca??o solit?ria - utilize \"gpg --import\" para aplicar\n" diff --git a/po/ro.po b/po/ro.po index 66d84e2..49f2132 100644 --- a/po/ro.po +++ b/po/ro.po @@ -4625,6 +4625,9 @@ msgstr "cifrat cu cheia %s, ID %s\n" msgid "public key decryption failed: %s\n" msgstr "decriptarea cu cheie public? a e?uat: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "cifrat? cu %lu fraze-parol?\n" @@ -4643,6 +4646,21 @@ msgstr "cifru IDEA indisponibil, vom ?ncerca s? folosim %s ?n loc\n" msgid "WARNING: message was not integrity protected\n" msgstr "AVERTISMENT: mesajul nu a avut integritatea protejat?\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "decriptarea a e?uat: %s\n" + msgid "decryption okay\n" msgstr "decriptare OK\n" @@ -4662,9 +4680,6 @@ msgstr "NOT?: expeditorul a cerut \"doar-pentru-ochii-d-voastr?\"\n" msgid "original file name='%.*s'\n" msgstr "nume fi?ier original='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "revocare standalone - folosi?i \"gpg --import\" pentru a aplica\n" diff --git a/po/ru.po b/po/ru.po index 19e666c..3db1a88 100644 --- a/po/ru.po +++ b/po/ru.po @@ -4329,6 +4329,9 @@ msgstr "??????????? ?????? %s ? ??????????????? msgid "public key decryption failed: %s\n" msgstr "???? ??????????? ? ???????? ??????: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "????????: ??????????? ????????? ???????\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "??????????? %lu ???????-????????\n" @@ -4347,6 +4350,21 @@ msgstr "???? IDEA ??????????, ???????? ?????? ??? msgid "WARNING: message was not integrity protected\n" msgstr "????????: ??????????? ????????? ?? ????????\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "???? ???????????: %s\n" + msgid "decryption okay\n" msgstr "???????????? ?????????\n" @@ -4364,9 +4382,6 @@ msgstr "?????????: ??????????? ???????? \"????? msgid "original file name='%.*s'\n" msgstr "?????????????? ??? ?????='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "????????: ??????????? ????????? ???????\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "????????? ?????????? ??????: ????????????? ???????? \"gpg --import\"\n" diff --git a/po/sk.po b/po/sk.po index b8a2670..f71a0a8 100644 --- a/po/sk.po +++ b/po/sk.po @@ -4620,6 +4620,9 @@ msgstr "za?ifrovan? %s k???om, ID %08lX\n" msgid "public key decryption failed: %s\n" msgstr "de?ifrovanie verejn?m k???om zlyhalo: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "za?ifrovan? s %lu heslami\n" @@ -4640,6 +4643,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "VAROVANIE: spr?va nem? ochranu integrity\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "de?ifrovanie zlyhalo: %s\n" + msgid "decryption okay\n" msgstr "de?ifrovanie o.k.\n" @@ -4659,9 +4677,6 @@ msgstr "POZN?MKA: odosielate? po?adoval (\"for-your-eyes-only\")\n" msgid "original file name='%.*s'\n" msgstr "p?vodn? meno s?boru='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "samostatn? revoka?n? certifik?t - pou?ite \"gpg --import\", ak ho chcete " diff --git a/po/sv.po b/po/sv.po index 2f85206..1f90746 100644 --- a/po/sv.po +++ b/po/sv.po @@ -4730,6 +4730,9 @@ msgstr "krypterad med %s-nyckel, id %s\n" msgid "public key decryption failed: %s\n" msgstr "dekryptering med publik nyckel misslyckades: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "VARNING: multipla klartexter har p?tr?ffats\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "krypterad med %lu l?senfraser\n" @@ -4751,6 +4754,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "VARNING: detta meddelande var inte integritetsskyddat\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "dekrypteringen misslyckades: %s\n" + msgid "decryption okay\n" msgstr "dekrypteringen lyckades\n" @@ -4771,9 +4789,6 @@ msgstr "OBS: avs?ndaren beg?rde \"endast-f?r-dina-?gon\"\n" msgid "original file name='%.*s'\n" msgstr "ursprungligt filnamn=\"%.*s\"\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "VARNING: multipla klartexter har p?tr?ffats\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "frist?ende sp?rrcertifikat - anv?nd \"gpg --import\" f?r\n" diff --git a/po/tr.po b/po/tr.po index f78c1a4..becd154 100644 --- a/po/tr.po +++ b/po/tr.po @@ -4677,6 +4677,9 @@ msgstr "%s anahtar? ve %s kullan?c? kimli?i ile ?ifrelenmi?\n" msgid "public key decryption failed: %s\n" msgstr "genel anahtar ?ifre ??z?m? ba?ar?s?z: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "UYAR: ?ok say?da salt metin g?r?ld?\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "%lu anahtar parolas? ile ?ifrelenmi?\n" @@ -4696,6 +4699,21 @@ msgstr "" msgid "WARNING: message was not integrity protected\n" msgstr "UYARI: ileti b?t?nl?k korumal? de?ildi\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "?ifre ??zme ba?ar?s?z: %s\n" + msgid "decryption okay\n" msgstr "?ifre ??zme tamam\n" @@ -4715,9 +4733,6 @@ msgstr "B?LG?: g?nderen \"yaln?z-g?zleriniz-i?in\" ricas?nda bulundu\n" msgid "original file name='%.*s'\n" msgstr "?zg?n dosya ad? = '%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "UYAR: ?ok say?da salt metin g?r?ld?\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "tek ba??na y?r?rl?kten kald?rma - uygulamak i?in \"gpg --import\" kullan?n\n" diff --git a/po/uk.po b/po/uk.po index 9fa1410..2a1b9a5 100644 --- a/po/uk.po +++ b/po/uk.po @@ -4418,6 +4418,9 @@ msgstr "??????????? ?????? %s, ????????????? %s\n" msgid "public key decryption failed: %s\n" msgstr "??????? ?????? ??????????????? ????????? ??????: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "?????: ???????? ???????? ?????????? ????????????? ??????\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "??????????? ?? ????????? %lu ???????\n" @@ -4436,6 +4439,21 @@ msgstr "???? IDEA ???????????, ????????? ??????? msgid "WARNING: message was not integrity protected\n" msgstr "?????: ?????????? ???????????? ?? ????????\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "??????? ?????? ?????????????: %s\n" + msgid "decryption okay\n" msgstr "????????????\n" @@ -4453,9 +4471,6 @@ msgstr "??????????: ?????? ???????????: ????? ? msgid "original file name='%.*s'\n" msgstr "????????? ????? ?????=?%.*s?\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "?????: ???????? ???????? ?????????? ????????????? ??????\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "?????? ??????????? ? ????????????? ???????? ?gpg --import? ??? ????????????\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index e425ca8..e0d2413 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -4517,6 +4517,9 @@ msgstr "? %s ????????? %s\n" msgid "public key decryption failed: %s\n" msgstr "???????%s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "? %lu ?????\n" @@ -4535,6 +4538,21 @@ msgstr "IDEA ???????? %s ??\n" msgid "WARNING: message was not integrity protected\n" msgstr "?????????????\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "?????%s\n" + msgid "decryption okay\n" msgstr "????\n" @@ -4554,9 +4572,6 @@ msgstr "?????????????????\n" msgid "original file name='%.*s'\n" msgstr "????? =?%.*s?\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "????????????gpg --import????\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index 6b2c4de..3b5ce07 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -4340,6 +4340,9 @@ msgstr "?? %s ??, ID %s ???\n" msgid "public key decryption failed: %s\n" msgstr "??????: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "??: ???????\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "?? %lu ??????\n" @@ -4358,6 +4361,21 @@ msgstr "IDEA ??????, ????????? %s ??\n" msgid "WARNING: message was not integrity protected\n" msgstr "??: ??????????\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "" + +#, fuzzy +#| msgid "decryption failed: %s\n" +msgid "decryption forced to fail!\n" +msgstr "????: %s\n" + msgid "decryption okay\n" msgstr "????\n" @@ -4375,9 +4393,6 @@ msgstr "???: ?????? \"???????\"\n" msgid "original file name='%.*s'\n" msgstr "????? ='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "??: ???????\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "???? - ?? \"gpg --import\" ???\n" commit ea36e637224f57cdd4b847484b6b9b790f48ad2d Author: Werner Koch Date: Fri Jun 8 11:24:06 2018 +0200 po: Update German translation -- Signed-off-by: Werner Koch diff --git a/po/de.po b/po/de.po index 87c3c15..727b614 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2018-04-09 20:39+0200\n" +"PO-Revision-Date: 2018-06-08 11:22+0200\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "Language: de\n" @@ -4376,6 +4376,9 @@ msgstr "verschl?sselt mit %s Schl?ssel, ID %s\n" msgid "public key decryption failed: %s\n" msgstr "Entschl?sselung mit Public-Key-Verfahren fehlgeschlagen: %s\n" +msgid "WARNING: multiple plaintexts seen\n" +msgstr "WARNUNG: Mehr als ein Klartext erkannt\n" + #, c-format msgid "encrypted with %lu passphrases\n" msgstr "Verschl?sselt mit %lu Passphrases\n" @@ -4395,6 +4398,22 @@ msgid "WARNING: message was not integrity protected\n" msgstr "" "WARNUNG: Botschaft wurde nicht integrit?tsgesch?tzt (integrity protected)\n" +msgid "" +"Hint: If this message was created before the year 2003 it is\n" +"likely that this message is legitimate. This is because back\n" +"then integrity protection was not widely used.\n" +msgstr "" +"Tip: Falls diese Botschaft vor dem Jahr 2003 erzeugt wurde, so wird es\n" +"vermutlich eine legitime Botschaft sein. Die kann vermutet werden, da\n" +"vor diesem Zeitpunkt ein Integrit?tsschutz nur selten verwendet wurde.\n" + +#, c-format +msgid "Use the option '%s' to decrypt anyway.\n" +msgstr "Mit der Option '%s' kann trotzdem entschl?sselt werden.\n" + +msgid "decryption forced to fail!\n" +msgstr "Entschl?sselung als fehlgeschlagen angesehen: %s\n" + msgid "decryption okay\n" msgstr "Entschl?sselung erfolgreich\n" @@ -4413,9 +4432,6 @@ msgstr "" msgid "original file name='%.*s'\n" msgstr "Urspr?nglicher Dateiname='%.*s'\n" -msgid "WARNING: multiple plaintexts seen\n" -msgstr "WARNUNG: Mehr als ein Klartext erkannt\n" - msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "Einzelner Widerruf - verwenden Sie \"gpg --import\", um ihn anzuwenden\n" commit 77ab99f80a5b0fbc60e05230185a54cd200d5e65 Author: Ineiev Date: Sat May 5 19:27:49 2018 +0000 po: Update Russian translation. diff --git a/po/ru.po b/po/ru.po index 654b5a7..19e666c 100644 --- a/po/ru.po +++ b/po/ru.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: GnuPG 2.2.0\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2017-12-13 17:41+0100\n" +"PO-Revision-Date: 2018-05-05 17:41+0100\n" "Last-Translator: Ineiev \n" "Language-Team: Russian \n" "Language: ru\n" @@ -1346,22 +1346,16 @@ msgid "%s keysizes must be in the range %u-%u\n" msgstr "?????? ?????? %s ?????? ???? ? ???????? %u-%u\n" msgid "Changing card key attribute for: " -msgstr "" +msgstr "????????? ????????? ????? ?? ?????:" -#, fuzzy -#| msgid " (1) Signature key\n" msgid "Signature key\n" -msgstr " (1) ???? ???????\n" +msgstr "????? ??? ???????\n" -#, fuzzy -#| msgid " (2) Encryption key\n" msgid "Encryption key\n" -msgstr " (2) ???? ??????????\n" +msgstr "????? ??? ??????????\n" -#, fuzzy -#| msgid " (3) Authentication key\n" msgid "Authentication key\n" -msgstr " (3) ???? ????????????? ????????\n" +msgstr "????? ??? ????????????? ????????\n" msgid "Please select what kind of key you want:\n" msgstr "???????? ??? ?????:\n" @@ -1370,10 +1364,9 @@ msgstr "???????? ??? ?????:\n" msgid " (%d) RSA\n" msgstr " (%d) RSA\n" -#, fuzzy, c-format -#| msgid " (%d) ECC and ECC\n" +#, c-format msgid " (%d) ECC\n" -msgstr " (%d) ECC ? ECC\n" +msgstr " (%d) ECC\n" msgid "Invalid selection.\n" msgstr "???????????? ?????.\n" @@ -1386,15 +1379,13 @@ msgstr "?????? ????? ????? ????????????? ?? ?? msgid "The card will now be re-configured to generate a key of type: %s\n" msgstr "?????? ????? ????? ????????????? ?? ????????? ????? ???? %s\n" -#, fuzzy, c-format -#| msgid "error changing size of key %d to %u bits: %s\n" +#, c-format msgid "error changing key attribute for key %d: %s\n" -msgstr "?????? ????????? ??????? ????? %d ?? %u ???: %s\n" +msgstr "?????? ????????? ???????? ????? %d: %s\n" -#, fuzzy, c-format -#| msgid "error getting current key info: %s\n" +#, c-format msgid "error getting card info: %s\n" -msgstr "?????? ??? ?????????? ?????????? ?????: %s\n" +msgstr "?????? ??? ?????????? ?????????? ?????: %s\n" msgid "This command is not supported by this card\n" msgstr "?????? ??????? ???? ?????? ?? ??????????????\n" @@ -1446,10 +1437,9 @@ msgstr "??????????? (y/N) " msgid "Really do a factory reset? (enter \"yes\") " msgstr "??????????? ????? ? ????????? ?????????? (??????? \"yes\") " -#, fuzzy, c-format -#| msgid "error looking up: %s\n" +#, c-format msgid "error for setup KDF: %s\n" -msgstr "?????? ??????: %s\n" +msgstr "?????? ??? ????????? KDF: %s\n" msgid "quit this menu" msgstr "????? ?? ????? ????" @@ -1502,15 +1492,11 @@ msgstr "?????????????? PIN ? ??????? ???? ?????? msgid "destroy all keys and data" msgstr "?????????? ??? ????? ? ??????" -#, fuzzy -#| msgid "|NAME|use user NAME for authentication" msgid "setup KDF for PIN authentication" -msgstr "|NAME|???????????? ??? ???????????? NAME ??? ????????????? ????????" +msgstr "????????? KDF ??? ???????? ?? PIN" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the key attribute" -msgstr "???????? ??????? ??????? ?????????" +msgstr "???????? ??????? ?????" msgid "gpg/card> " msgstr "gpg/card> " @@ -2151,10 +2137,9 @@ msgstr "\"%s\" ?? ???????? ??????? ??????????? ?? msgid "invalid pinentry mode '%s'\n" msgstr "???????????? ????? ????? ?????? '%s'\n" -#, fuzzy, c-format -#| msgid "invalid value for option '%s'\n" +#, c-format msgid "invalid request origin '%s'\n" -msgstr "???????????? ???????? ????????? \"%s\"\n" +msgstr "???????????? ???????? ??????? '%s'\n" #, c-format msgid "'%s' is not a valid character set\n" @@ -3552,15 +3537,11 @@ msgstr "????? ????? ???????? ?????????? ?????.\ msgid "You can't change the expiration date of a v3 key\n" msgstr "?????? ???????? ???? ???????? ????? v3\n" -#, fuzzy -#| msgid "Changing expiration time for a subkey.\n" msgid "Changing usage of a subkey.\n" -msgstr "????? ????? ???????? ????????.\n" +msgstr "????? ??????? ????????????? ????????.\n" -#, fuzzy -#| msgid "Changing expiration time for the primary key.\n" msgid "Changing usage of the primary key.\n" -msgstr "????? ????? ???????? ?????????? ?????.\n" +msgstr "????? ??????? ????????????? ?????????? ?????.\n" #, c-format msgid "signing subkey %s is already cross-certified\n" @@ -5220,10 +5201,9 @@ msgstr "?????????: ???? ???????? ???????????? msgid "Note: signature key %s has been revoked\n" msgstr "?????????: ???? ??? ???????? %s ???????\n" -#, fuzzy, c-format -#| msgid "standalone signature of class 0x%02x\n" +#, c-format msgid "bad key signature from key %s: %s (0x%02x, 0x%x)\n" -msgstr "????????? ??????? ?????? 0x%02x\n" +msgstr "?????? ??????? ?????? %s: %s (0x%02x 0x%x)\n" #, c-format msgid "assuming bad signature from key %s due to an unknown critical bit\n" ----------------------------------------------------------------------- Summary of changes: NEWS | 30 +++++++++++++++++++++- configure.ac | 2 +- po/ca.po | 21 ++++++++++++--- po/cs.po | 21 ++++++++++++--- po/da.po | 21 ++++++++++++--- po/de.po | 24 +++++++++++++++--- po/el.po | 21 ++++++++++++--- po/eo.po | 21 ++++++++++++--- po/es.po | 23 +++++++++++++---- po/et.po | 21 ++++++++++++--- po/fi.po | 21 ++++++++++++--- po/fr.po | 21 ++++++++++++--- po/gl.po | 21 ++++++++++++--- po/hu.po | 21 ++++++++++++--- po/id.po | 21 ++++++++++++--- po/it.po | 21 ++++++++++++--- po/ja.po | 21 ++++++++++++--- po/nb.po | 21 ++++++++++++--- po/pl.po | 21 ++++++++++++--- po/pt.po | 21 ++++++++++++--- po/ro.po | 21 ++++++++++++--- po/ru.po | 83 ++++++++++++++++++++++++++++-------------------------------- po/sk.po | 21 ++++++++++++--- po/sv.po | 21 ++++++++++++--- po/tr.po | 21 ++++++++++++--- po/uk.po | 21 ++++++++++++--- po/zh_CN.po | 21 ++++++++++++--- po/zh_TW.po | 21 ++++++++++++--- 28 files changed, 521 insertions(+), 124 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 13:05:37 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 13:05:37 +0200 Subject: [git] gnupg-doc - branch, master, updated. 093143fe54d7a51e5c42913b99ac4b1a2c9c2169 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 093143fe54d7a51e5c42913b99ac4b1a2c9c2169 (commit) from dbaa9b76509ebb1f402429c7c52421b319f38482 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 093143fe54d7a51e5c42913b99ac4b1a2c9c2169 Author: Werner Koch Date: Fri Jun 8 12:57:36 2018 +0200 swdb: Release GnuPG 2.2.8 diff --git a/web/swdb.mac b/web/swdb.mac index 9adaf35..ece3aab 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -10,17 +10,17 @@ # # GnuPG-2.2 # -#+macro: gnupg22_ver 2.2.7 -#+macro: gnupg22_date 2018-05-02 -#+macro: gnupg22_size 6475k -#+macro: gnupg22_sha1 e222cda63409a86992369df8976f6c7511e10ea0 -#+macro: gnupg22_sha2 d95b361ee6ef7eff86af40c8c72bf9313736ac9f7010d6604d78bf83818e976e +#+macro: gnupg22_ver 2.2.8 +#+macro: gnupg22_date 2018-06-08 +#+macro: gnupg22_size 6477k +#+macro: gnupg22_sha1 d87553a125832ea90e8aeb3ceeecf24f88de56fb +#+macro: gnupg22_sha2 777b4cb8ced21965a5053d4fa20fe11484f0a478f3d011cef508a1a49db50dcd #+macro: gnupg22_branch STABLE-BRANCH-2-2 -#+macro: gnupg22_w32_ver 2.2.7_20180502 -#+macro: gnupg22_w32_date 2018-05-02 -#+macro: gnupg22_w32_size 3914k -#+macro: gnupg22_w32_sha1 a00f7119c85dd837336f13be3174178d0cf8d85e -#+macro: gnupg22_w32_sha2 2d7ffedb1737e4dbed7f89377c3273b5cc27ee0fd9c70a417bd602203fc419ee +#+macro: gnupg22_w32_ver 2.2.8_20180608 +#+macro: gnupg22_w32_date 2018-06-08 +#+macro: gnupg22_w32_size 3916k +#+macro: gnupg22_w32_sha1 231b29631647328934a35f8c6baa483e7594e26a +#+macro: gnupg22_w32_sha2 21d4123d1455c925f8a570f94bc7e87a205edbff1ad78fabe8b7b5a3614b1aa2 # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 13:55:36 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 08 Jun 2018 13:55:36 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-55-g6c74a59 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 6c74a59e8855d1cac0d8001ad1b7843d2d15be5e (commit) from af8510fb7f4d5c90cc53f10dcc740f377af73d68 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6c74a59e8855d1cac0d8001ad1b7843d2d15be5e Author: Andre Heinecke Date: Fri Jun 8 13:55:21 2018 +0200 json: Add op_createkey * src/gpgme-json.c (hlp_createkey, op_createkey): New. (process_request, hlp_help): Add it. -- This uses an unrestricted context for now until GnuPG-Bug-Id: T4010 is implemented in GnuPG. diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 7bb1baf..598c587 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -2769,6 +2769,89 @@ leave: +static const char hlp_createkey[] = + "op: \"createkey\"\n" + "userid: The user id. E.g. \"Foo Bar \"\n" + "\n" + "Optional parameters:\n" + "algo: Algo of the key as string. See doc for gpg --quick-gen-key.\n" + "expires: Seconds since epoch to expiry as Number. 0 means no expiry.\n" + "\n" + "Response on success:\n" + "success: Boolean true.\n" + "\n" + "Note: This interface does not allow key generation if the userid\n" + "of the new key already exists in the keyring.\n"; +static gpg_error_t +op_createkey (cjson_t request, cjson_t result) +{ + gpg_error_t err; + gpgme_ctx_t ctx = NULL; + unsigned int flags = 0; + unsigned long expires = 0; + cjson_t j_tmp; + const char *algo = "default"; + const char *userid; + +#ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER + /* GnuPG forbids keygen through the browser socket so for + this we create an unrestricted context. + See GnuPG-Bug-Id: T4010 for more info */ + ctx = get_context (GPGME_PROTOCOL_OpenPGP); +#else + err = gpgme_new (&ctx); + if (err) + log_fatal ("error creating GPGME context: %s\n", gpg_strerror (err)); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); +#endif + + j_tmp = cJSON_GetObjectItem (request, "algo"); + if (j_tmp && cjson_is_string (j_tmp)) + { + algo = j_tmp->valuestring; + } + + j_tmp = cJSON_GetObjectItem (request, "userid"); + if (!j_tmp || !cjson_is_string (j_tmp)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + + userid = j_tmp->valuestring; + + j_tmp = cJSON_GetObjectItem (request, "expires"); + if (j_tmp) + { + if (!cjson_is_number (j_tmp)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + expires = j_tmp->valueint; + + if (!expires) + flags |= GPGME_CREATE_NOEXPIRE; + } + + + if ((err = gpgme_op_createkey (ctx, userid, algo, 0, expires, NULL, flags))) + goto leave; + + xjson_AddBoolToObject (result, "success", 1); + +leave: +#ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER + release_context (ctx); +#else + gpgme_release (ctx); +#endif + + return err; +} + + + static const char hlp_getmore[] = "op: \"getmore\"\n" "\n" @@ -2858,10 +2941,12 @@ static const char hlp_help[] = "returned. To list all operations it is allowed to leave out \"op\" in\n" "help mode. Supported values for \"op\" are:\n\n" " config Read configuration values.\n" + " config_opt Read a single configuration value.\n" " decrypt Decrypt data.\n" " delete Delete a key.\n" " encrypt Encrypt data.\n" " export Export keys.\n" + " createkey Generate a keypair (OpenPGP only).\n" " import Import data.\n" " keylist List keys.\n" " sign Sign data.\n" @@ -2918,6 +3003,7 @@ process_request (const char *request) { "export", op_export, hlp_export }, { "decrypt", op_decrypt, hlp_decrypt }, { "delete", op_delete, hlp_delete }, + { "createkey", op_createkey, hlp_createkey }, { "keylist", op_keylist, hlp_keylist }, { "import", op_import, hlp_import }, { "sign", op_sign, hlp_sign }, ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 14:52:48 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 08 Jun 2018 14:52:48 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-56-g54146d9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 54146d90dd5518c24c30e6d2ebeb7f47ed4eb29e (commit) from 6c74a59e8855d1cac0d8001ad1b7843d2d15be5e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 54146d90dd5518c24c30e6d2ebeb7f47ed4eb29e Author: Andre Heinecke Date: Fri Jun 8 14:52:41 2018 +0200 json: Return fingerprint as createkey result * src/gpgme-json.c (op_createkey): Return fingerprint of new key. diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 598c587..ae878bd 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -2778,7 +2778,7 @@ static const char hlp_createkey[] = "expires: Seconds since epoch to expiry as Number. 0 means no expiry.\n" "\n" "Response on success:\n" - "success: Boolean true.\n" + "fingerprint: The fingerprint of the created key.\n" "\n" "Note: This interface does not allow key generation if the userid\n" "of the new key already exists in the keyring.\n"; @@ -2792,6 +2792,7 @@ op_createkey (cjson_t request, cjson_t result) cjson_t j_tmp; const char *algo = "default"; const char *userid; + gpgme_genkey_result_t res; #ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER /* GnuPG forbids keygen through the browser socket so for @@ -2838,7 +2839,14 @@ op_createkey (cjson_t request, cjson_t result) if ((err = gpgme_op_createkey (ctx, userid, algo, 0, expires, NULL, flags))) goto leave; - xjson_AddBoolToObject (result, "success", 1); + res = gpgme_op_genkey_result (ctx); + if (!res) + { + err = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + + xjson_AddStringToObject0 (result, "fingerprint", res->fpr); leave: #ifdef GPG_AGENT_ALLOWS_KEYGEN_TRHOUGH_BROWSER ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 16:07:47 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 16:07:47 +0200 Subject: [git] gnupg-doc - branch, master, updated. d1df251db10b1922c354cb3cd3107ad590d3c341 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via d1df251db10b1922c354cb3cd3107ad590d3c341 (commit) from 093143fe54d7a51e5c42913b99ac4b1a2c9c2169 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d1df251db10b1922c354cb3cd3107ad590d3c341 Author: Werner Koch Date: Fri Jun 8 15:59:10 2018 +0200 web: News about GnuPG 2.2.8 diff --git a/web/index.org b/web/index.org index 8dbc895..526d214 100644 --- a/web/index.org +++ b/web/index.org @@ -65,6 +65,14 @@ The latest release news:\\ # GnuPG's latest news are available as [[http://feedvalidator.org/check.cgi?url%3Dhttps://www.gnupg.org/news.en.rss][RSS 2.0 compliant]] feed. Just # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** GnuPG 2.2.8 released (2018-06-08) :important: + +This version fixes a critical security bug. Either this version or a +vendor provided fix should be installed. There are also a few other +changes; see the [[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000425.html][announcement]] mail. This is [[https://cve.mitre.org/cgi-bin/cvename.cgi?name%3DCVE-2018-12020][CVE-2018-12020]] and our +bug [[https://dev/gnupg.org/T4012][#4012]]. + + ** GnuPG 2.2.7 released (2018-05-02) We are pleased to announce the availability of GnuPG version 2.2.7. ----------------------------------------------------------------------- Summary of changes: web/index.org | 8 ++++++++ 1 file changed, 8 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 16:22:21 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 08 Jun 2018 16:22:21 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-57-g8dff414 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 8dff414e170e4df8ea661028c4ac1588311ca26e (commit) from 54146d90dd5518c24c30e6d2ebeb7f47ed4eb29e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8dff414e170e4df8ea661028c4ac1588311ca26e Author: Andre Heinecke Date: Fri Jun 8 16:19:47 2018 +0200 cpp: Add proper gpgme_op_createkey * lang/cpp/src/context.cpp, lang/cpp/src/context.h (Context::createKeyEx): New. -- The createKeyEx function follows the usual pattern that the synchronous call returns a result directly while for the async an extra call is neccessary. diff --git a/NEWS b/NEWS index e70b9a9..6c33c25 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ Noteworthy changes in version 1.11.2 (unreleased) cpp: Data::rewind NEW. cpp: Context::setFlag NEW. cpp: Context::getFlag NEW. + cpp: Context::createKeyEx NEW. Noteworthy changes in version 1.11.1 (2018-04-20) diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index 8fde84a..aab22cd 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1436,6 +1436,23 @@ Error Context::createKey (const char *userid, flags)); } +KeyGenerationResult Context::createKeyEx (const char *userid, + const char *algo, + unsigned long reserved, + unsigned long expires, + const Key &certkey, + unsigned int flags) +{ + d->lasterr = gpgme_op_createkey(d->ctx, + userid, + algo, + reserved, + expires, + certkey.impl(), + flags); + return KeyGenerationResult(d->ctx, Error(d->lasterr)); +} + Error Context::addUid(const Key &k, const char *userid) { return Error(d->lasterr = gpgme_op_adduid(d->ctx, diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h index 8cccff5..a14625e 100644 --- a/lang/cpp/src/context.h +++ b/lang/cpp/src/context.h @@ -234,6 +234,14 @@ public: const Key &certkey, unsigned int flags); + // Same as create key but returning a result + GpgME::KeyGenerationResult createKeyEx (const char *userid, + const char *algo, + unsigned long reserved, + unsigned long expires, + const Key &certkey, + unsigned int flags); + Error addUid(const Key &key, const char *userid); Error startAddUid(const Key &key, const char *userid); ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + lang/cpp/src/context.cpp | 17 +++++++++++++++++ lang/cpp/src/context.h | 8 ++++++++ 3 files changed, 26 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 16:41:54 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 08 Jun 2018 16:41:54 +0200 Subject: [git] gnupg-doc - branch, master, updated. 8730e196752a3a41c6536cca60ba8e2e442a5b88 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 8730e196752a3a41c6536cca60ba8e2e442a5b88 (commit) from d1df251db10b1922c354cb3cd3107ad590d3c341 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8730e196752a3a41c6536cca60ba8e2e442a5b88 Author: Andre Heinecke Date: Fri Jun 8 16:41:18 2018 +0200 web: Fix sha1 sums for gnupg and gnupg-w32 * web/download/integrity_check.org: It's gnupg22_ver now. diff --git a/web/download/integrity_check.org b/web/download/integrity_check.org index b0f4cb6..f98fbd1 100644 --- a/web/download/integrity_check.org +++ b/web/download/integrity_check.org @@ -106,8 +106,8 @@ that can be downloaded from [[ftp://ftp.gnupg.org/][our site]], have been gathered below. {{{begin_chksum}}} - {{{gnupg22_sha1}}} gnupg-{{{gnupg21_ver}}}.tar.bz2 - {{{gnupg22_w32_sha1}}} gnupg-w32-{{{gnupg21_w32_ver}}}.exe + {{{gnupg22_sha1}}} gnupg-{{{gnupg22_ver}}}.tar.bz2 + {{{gnupg22_w32_sha1}}} gnupg-w32-{{{gnupg22_w32_ver}}}.exe {{{libgpg_error_sha1}}} libgpg-error-{{{libgpg_error_ver}}}.tar.bz2 {{{libgcrypt_sha1}}} libgcrypt-{{{libgcrypt_ver}}}.tar.bz2 {{{libksba_sha1}}} libksba-{{{libksba_ver}}}.tar.bz2 ----------------------------------------------------------------------- Summary of changes: web/download/integrity_check.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 17:58:22 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Fri, 08 Jun 2018 17:58:22 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-56-gc072675 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via c072675f3f2d734297a348c6de810148fb1424a2 (commit) from 7a072270ac031152ee034df0f5b6ef5e8bf7d394 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c072675f3f2d734297a348c6de810148fb1424a2 Author: Maximilian Krambach Date: Fri Jun 8 17:54:58 2018 +0200 js: change chunksize handling and decoding -- * the nativeApp now sends all data in one base64-encoded string, which needs reassembly, but in a much easier way now. * there are some new performance problems now, especially with decrypting data diff --git a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js index a84be27..bd72c1d 100644 --- a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js +++ b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js @@ -152,7 +152,7 @@ describe('Encryption and Decryption', function () { let prm = Gpgmejs.init(); prm.then(function (context) { context.encrypt(b64data, - inputvalues.encrypt.good.fingerprint).then( + inputvalues.encrypt.good.fingerprint, true).then( function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); @@ -185,33 +185,7 @@ describe('Encryption and Decryption', function () { 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); - context.decrypt(answer.data, true).then( - function (result) { - expect(result).to.not.be.empty; - expect(result.data).to.be.a('string'); - expect(result.data).to.equal(b64data); - done(); - }); - }); - }); - }).timeout(3000); - - it('Random data, input and output as base64', function (done) { - let data = bigBoringString(0.0001); - let b64data = btoa(data); - let prm = Gpgmejs.init(); - prm.then(function (context) { - context.encrypt(b64data, - inputvalues.encrypt.good.fingerprint).then( - function (answer) { - expect(answer).to.not.be.empty; - expect(answer.data).to.be.a('string'); - - expect(answer.data).to.include( - 'BEGIN PGP MESSAGE'); - expect(answer.data).to.include( - 'END PGP MESSAGE'); - context.decrypt(answer.data, true).then( + context.decrypt(answer.data).then( function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); @@ -222,5 +196,4 @@ describe('Encryption and Decryption', function () { }); }).timeout(3000); - }); diff --git a/lang/js/BrowserTestExtension/tests/longRunningTests.js b/lang/js/BrowserTestExtension/tests/longRunningTests.js index eefe126..e148d1c 100644 --- a/lang/js/BrowserTestExtension/tests/longRunningTests.js +++ b/lang/js/BrowserTestExtension/tests/longRunningTests.js @@ -24,7 +24,7 @@ /* global bigString, inputvalues */ describe('Long running Encryption/Decryption', function () { - for (let i=0; i < 100; i++) { + for (let i=0; i < 101; i++) { it('Successful encrypt/decrypt completely random data ' + (i+1) + '/100', function (done) { let prm = Gpgmejs.init(); @@ -43,30 +43,32 @@ describe('Long running Encryption/Decryption', function () { function(result){ expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); + /* if (result.data.length !== data.length) { - // console.log('diff: ' + - // (result.data.length - data.length)); + console.log('diff: ' + + (result.data.length - data.length)); for (let i=0; i < result.data.length; i++){ if (result.data[i] !== data[i]){ - // console.log('position: ' + i); - // console.log('result : ' + - // result.data.charCodeAt(i) + - // result.data[i-2] + - // result.data[i-1] + - // result.data[i] + - // result.data[i+1] + - // result.data[i+2]); - // console.log('original: ' + - // data.charCodeAt(i) + - // data[i-2] + - // data[i-1] + - // data[i] + - // data[i+1] + - // data[i+2]); + console.log('position: ' + i); + console.log('result : ' + + result.data.charCodeAt(i) + + result.data[i-2] + + result.data[i-1] + + result.data[i] + + result.data[i+1] + + result.data[i+2]); + console.log('original: ' + + data.charCodeAt(i) + + data[i-2] + + data[i-1] + + data[i] + + data[i+1] + + data[i+2]); break; } } } + */ expect(result.data).to.equal(data); done(); }); diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js index e9c0b21..f399b22 100644 --- a/lang/js/src/Connection.js +++ b/lang/js/src/Connection.js @@ -108,6 +108,7 @@ export class Connection{ return Promise.reject(gpgme_error('MSG_INCOMPLETE')); } let me = this; + let chunksize = message.chunksize; return new Promise(function(resolve, reject){ let answer = new Answer(message); let listener = function(msg) { @@ -115,22 +116,27 @@ export class Connection{ me._connection.onMessage.removeListener(listener); me._connection.disconnect(); reject(gpgme_error('CONN_EMPTY_GPG_ANSWER')); - } else if (msg.type === 'error'){ - me._connection.onMessage.removeListener(listener); - me._connection.disconnect(); - reject(gpgme_error('GNUPG_ERROR', msg.msg)); } else { - let answer_result = answer.add(msg); + let answer_result = answer.collect(msg); if (answer_result !== true){ me._connection.onMessage.removeListener(listener); me._connection.disconnect(); reject(answer_result); - } else if (msg.more === true){ - me._connection.postMessage({'op': 'getmore'}); } else { - me._connection.onMessage.removeListener(listener); - me._connection.disconnect(); - resolve(answer.message); + if (msg.more === true){ + me._connection.postMessage({ + 'op': 'getmore', + 'chunksize': chunksize + }); + } else { + me._connection.onMessage.removeListener(listener); + me._connection.disconnect(); + if (answer.message instanceof Error){ + reject(answer.message); + } else { + resolve(answer.message); + } + } } } }; @@ -170,19 +176,32 @@ class Answer{ constructor(message){ this.operation = message.operation; - this.expected = message.expected; + this.expect = message.expect; } - /** - * Add the information to the answer - * @param {Object} msg The message as received with nativeMessaging - * returns true if successfull, gpgme_error otherwise - */ - add(msg){ - if (this._response === undefined){ - this._response = {}; + collect(msg){ + if (typeof(msg) !== 'object' || !msg.hasOwnProperty('response')) { + return gpgme_error('CONN_UNEXPECTED_ANSWER'); + } + if (this._responseb64 === undefined){ + //this._responseb64 = [msg.response]; + this._responseb64 = msg.response; + return true; + } else { + //this._responseb64.push(msg.response); + this._responseb64 += msg.response; + return true; } - let messageKeys = Object.keys(msg); + } + + get message(){ + if (this._responseb64 === undefined){ + return gpgme_error('CONN_UNEXPECTED_ANSWER'); + } + // let _decodedResponse = JSON.parse(atob(this._responseb64.join(''))); + let _decodedResponse = JSON.parse(atob(this._responseb64)); + let _response = {}; + let messageKeys = Object.keys(_decodedResponse); let poa = permittedOperations[this.operation].answer; if (messageKeys.length === 0){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); @@ -191,80 +210,42 @@ class Answer{ let key = messageKeys[i]; switch (key) { case 'type': - if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){ + if (_decodedResponse.type === 'error'){ + return (gpgme_error('GNUPG_ERROR', _decodedResponse.msg)); + } else if (poa.type.indexOf(_decodedResponse.type) < 0){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } break; - case 'more': + case 'base64': break; - default: - //data should be concatenated - if (poa.data.indexOf(key) >= 0){ - if (!this._response.hasOwnProperty(key)){ - this._response[key] = ''; - } - this._response[key] += msg[key]; - } - //params should not change through the message - else if (poa.params.indexOf(key) >= 0){ - if (!this._response.hasOwnProperty(key)){ - this._response[key] = msg[key]; - } - else if (this._response[key] !== msg[key]){ - return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]); - } + case 'msg': + if (_decodedResponse.type === 'error'){ + return (gpgme_error('GNUPG_ERROR', _decodedResponse.msg)); } - //infos may be json objects etc. Not yet defined. - // Pushing them into arrays for now - else if (poa.infos.indexOf(key) >= 0){ - if (!this._response.hasOwnProperty(key)){ - this._response[key] = []; - } - - if (Array.isArray(msg[key])) { - for (let i=0; i< msg[key].length; i++) { - this._response[key].push(msg[key][i]); - } - } else { - this._response[key].push(msg[key]); - } + break; + default: + if (!poa.data.hasOwnProperty(key)){ + return gpgme_error('CONN_UNEXPECTED_ANSWER'); } - else { + if( typeof(_decodedResponse[key]) !== poa.data[key] ){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } - break; - } - } - return true; - } - - /** - * @returns {Object} the assembled message, original data assumed to be - * (javascript-) strings - */ - get message(){ - let keys = Object.keys(this._response); - let msg = {}; - let poa = permittedOperations[this.operation].answer; - for (let i=0; i < keys.length; i++) { - if (poa.data.indexOf(keys[i]) >= 0 - && this._response.base64 === true - ) { - msg[keys[i]] = atob(this._response[keys[i]]); - if (this.expected === 'base64'){ - msg[keys[i]] = this._response[keys[i]]; - } else { - msg[keys[i]] = decodeURIComponent( - atob(this._response[keys[i]]).split('').map( + if (_decodedResponse.base64 === true + && poa.data[key] === 'string' + && this.expect === undefined + ){ + _response[key] = decodeURIComponent( + atob(_decodedResponse[key]).split('').map( function(c) { return '%' + - ('00' + c.charCodeAt(0).toString(16)).slice(-2); + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); + } else { + _response[key] = _decodedResponse[key]; } - } else { - msg[keys[i]] = this._response[keys[i]]; + break; } } - return msg; + return _response; } } diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js index 0ddda6c..7ccf7ef 100644 --- a/lang/js/src/Message.js +++ b/lang/js/src/Message.js @@ -46,7 +46,6 @@ export class GPGME_Message { constructor(operation){ this.operation = operation; - this._expected = 'string'; } set operation (op){ @@ -59,24 +58,50 @@ export class GPGME_Message { } } } - get operation(){ return this._msg.op; } - set expected(string){ - if (string === 'base64'){ - this._expected = 'base64'; + /** + * Set the maximum size of responses from gpgme in bytes. Values allowed + * range from 10kB to 1MB. The lower limit is arbitrary, the upper limit + * fixed by browsers' nativeMessaging specifications + */ + set chunksize(value){ + if ( + Number.isInteger(value) && + value > 10 * 1024 && + value <= 1024 * 1024 + ){ + this._chunksize = value; + } + } + get chunksize(){ + if (this._chunksize === undefined){ + return 1024 * 1023; + } else { + return this._chunksize; } } - get expected() { - if (this._expected === 'base64'){ - return this._expected; + /** + * If expect is set to 'base64', the response is expected to be base64 + * encoded binary + */ + set expect(value){ + if (value ==='base64'){ + this._expect = value; + } + } + + get expect(){ + if ( this._expect === 'base64'){ + return this._expect; } - return 'string'; + return undefined; } + /** * Sets a parameter for the message. Note that the operation has to be set * first, to be able to check if the parameter is permittted @@ -188,6 +213,7 @@ export class GPGME_Message { */ get message(){ if (this.isComplete === true){ + this._msg.chunksize = this.chunksize; return this._msg; } else { @@ -201,10 +227,13 @@ export class GPGME_Message { return new Promise(function(resolve, reject) { if (me.isComplete === true) { let conn = new Connection; + if (me._msg.chunksize === undefined){ + me._msg.chunksize = 1023*1024; + } conn.post(me).then(function(response) { resolve(response); }, function(reason) { - reject(gpgme_error('GNUPG_ERROR', reason)); + reject(reason); }); } else { diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index cbad902..09bca7f 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -57,8 +57,8 @@ export class GpgME { * Keys used to encrypt the message * @param {GPGME_Key|String|Array|Array} secretKeys * (optional) Keys used to sign the message - * @param {Boolean} base64 (optional) The data is already considered to be - * in base64 encoding + * @param {Boolean} base64 (optional) The data will be interpreted as + * base64 encoded data * @param {Boolean} armor (optional) Request the output as armored block * @param {Boolean} wildcard (optional) If true, recipient information will * not be added to the message @@ -109,24 +109,20 @@ export class GpgME { * Decrypt a Message * @param {String|Object} data text/data to be decrypted. Accepts Strings * and Objects with a getText method - * @param {Boolean} base64 (optional) Response is expected to be base64 - * encoded * @returns {Promise} decrypted message: - data: The decrypted data. This may be base64 encoded. + data: The decrypted data. base64: Boolean indicating whether data is base64 encoded. mime: A Boolean indicating whether the data is a MIME object. signatures: Array of signature Objects TODO not yet implemented. - // should be an object that can tell if all signatures are valid . + // should be an object that can tell if all signatures are valid. * @async */ - decrypt(data, base64=false){ + decrypt(data){ if (data === undefined){ return Promise.reject(gpgme_error('MSG_EMPTY')); } let msg = createMessage('decrypt'); - if (base64 === true){ - msg.expected = 'base64'; - } + if (msg instanceof Error){ return Promise.reject(msg); } @@ -165,10 +161,10 @@ export class GpgME { } msg.setParameter('mode', mode); putData(msg, data); - if (mode === 'detached') { - msg.expected = 'base64'; - } return new Promise(function(resolve,reject) { + if (mode ==='detached'){ + msg.expect= 'base64'; + } msg.post().then( function(message) { if (mode === 'clearsign'){ resolve({ diff --git a/lang/js/src/permittedOperations.js b/lang/js/src/permittedOperations.js index 445a40c..6ac33af 100644 --- a/lang/js/src/permittedOperations.js +++ b/lang/js/src/permittedOperations.js @@ -37,11 +37,8 @@ 5000 ms would be too short answer: type: The payload property of the answer. May be - partial and in need of concatenation - params: Array Information that do not change throughout - the message - infos: Array<*> arbitrary information that may result in a list + data: + the properties expected and their type, eg: {'data':'string'} } } */ @@ -67,9 +64,6 @@ export const permittedOperations = { allowed: ['string'], array_allowed: true }, - 'chunksize': { - allowed: ['number'] - }, 'base64': { allowed: ['boolean'] }, @@ -101,9 +95,10 @@ export const permittedOperations = { }, answer: { type: ['ciphertext'], - data: ['data'], - params: ['base64'], - infos: [] + data: { + 'data': 'string', + 'base64':'boolean' + } } }, @@ -119,18 +114,18 @@ export const permittedOperations = { allowed: ['string'], allowed_data: ['cms', 'openpgp'] }, - 'chunksize': { - allowed: ['number'], - }, 'base64': { allowed: ['boolean'] } }, answer: { type: ['plaintext'], - data: ['data'], - params: ['base64', 'mime'], - infos: ['signatures'] + data: { + 'data': 'string', + 'base64': 'boolean', + 'mime': 'boolean', + 'signatures': 'object' + } } }, @@ -149,9 +144,6 @@ export const permittedOperations = { allowed: ['string'], allowed_data: ['cms', 'openpgp'] }, - 'chunksize': { - allowed: ['number'], - }, 'sender': { allowed: ['string'], }, @@ -169,10 +161,11 @@ export const permittedOperations = { }, answer: { type: ['signature', 'ciphertext'], - data: ['data'], // Unless armor mode is used a Base64 encoded binary - // signature. In armor mode a string with an armored - // OpenPGP or a PEM message. - params: ['base64'] + data: { + 'data': 'string', + 'base64':'boolean' + } + } }, @@ -186,9 +179,6 @@ export const permittedOperations = { allowed: ['string'], allowed_data: ['cms', 'openpgp'] }, - 'chunksize': { - allowed: ['number'], - }, 'secret': { allowed: ['boolean'] }, @@ -220,9 +210,10 @@ export const permittedOperations = { }, answer: { type: ['keys'], - data: [], - params: ['base64'], - infos: ['keys'] + data: { + 'base64': 'boolean', + 'keys': 'object' + } } }, @@ -233,9 +224,6 @@ export const permittedOperations = { allowed: ['string'], allowed_data: ['cms', 'openpgp'] }, - 'chunksize': { - allowed: ['number'], - }, 'keys': { allowed: ['string'], array_allowed: true @@ -259,8 +247,10 @@ export const permittedOperations = { }, answer: { type: ['keys'], - data: ['data'], - params: ['base64'] + data: { + 'data': 'string', + 'base64': 'boolean' + } } }, @@ -280,10 +270,10 @@ export const permittedOperations = { }, }, answer: { - infos: ['result'], type: [], - data: [], - params: [] + data: { + 'result': 'Object' + } } }, @@ -299,15 +289,15 @@ export const permittedOperations = { allowed: ['string'], allowed_data: ['cms', 'openpgp'] }, - // 'secret': { not yet implemented + // 'secret': { not implemented // allowed: ['boolean'] // } }, answer: { - data: [], - params:['success'], - infos: [] + data: { + 'success': 'boolean' + } } }, @@ -316,9 +306,10 @@ export const permittedOperations = { optional: {}, answer: { type: [''], - data: ['gpgme'], - infos: ['info'], - params:[] + data: { + 'gpgme': 'string', + 'info': 'object' + } } } diff --git a/lang/js/unittests.js b/lang/js/unittests.js index ce1dd0c..169e8eb 100644 --- a/lang/js/unittests.js +++ b/lang/js/unittests.js @@ -339,7 +339,8 @@ function unittests (){ test0.setParameter('keys', hp.validFingerprints); expect(test0.message).to.not.be.null; - expect(test0.message).to.have.keys('op', 'data', 'keys'); + expect(test0.message).to.have.keys('op', 'data', 'keys', + 'chunksize'); expect(test0.message.op).to.equal('encrypt'); expect(test0.message.data).to.equal( mp.valid_encrypt_data); ----------------------------------------------------------------------- Summary of changes: .../tests/encryptDecryptTest.js | 31 +---- .../BrowserTestExtension/tests/longRunningTests.js | 38 +++--- lang/js/src/Connection.js | 143 +++++++++------------ lang/js/src/Message.js | 49 +++++-- lang/js/src/gpgmejs.js | 22 ++-- lang/js/src/permittedOperations.js | 81 ++++++------ lang/js/unittests.js | 3 +- 7 files changed, 170 insertions(+), 197 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 8 22:09:33 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Jun 2018 22:09:33 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-2-g18274db Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 18274db32b5dea7fe8db67043a787578c975de4d (commit) from e9667dd20a3a71c0a51d20ac4b1aa758e5bb5ada (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 18274db32b5dea7fe8db67043a787578c975de4d Author: Werner Koch Date: Fri Jun 8 22:01:10 2018 +0200 gpg: Allow building with older libgpg-error. * g10/mainproc.c (proc_encrypted): Use constant from logging.h -- Because the log levels are enums I had to change there names in libgpg-error to avoid clashes. Master uses the new names but 2.2 needs to stick to the old names. Fixes-commit: 825909e9cd5f344ece6c0b0ea3a9475df1d643de Signed-off-by: Werner Koch diff --git a/g10/mainproc.c b/g10/mainproc.c index 72b0dd8..f5cc453 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -683,7 +683,7 @@ proc_encrypted (CTX c, PACKET *pkt) * are rare in practice we print a hint on how to decrypt * such messages. */ log_string - (GPGRT_LOGLVL_INFO, + (GPGRT_LOG_INFO, _("Hint: If this message was created before the year 2003 it is\n" "likely that this message is legitimate. This is because back\n" "then integrity protection was not widely used.\n")); ----------------------------------------------------------------------- Summary of changes: g10/mainproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 9 11:48:39 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 09 Jun 2018 11:48:39 +0200 Subject: [git] gnupg-doc - branch, master, updated. 680e8aa513ce16834888c9ee28fee132149968e4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 680e8aa513ce16834888c9ee28fee132149968e4 (commit) from 8730e196752a3a41c6536cca60ba8e2e442a5b88 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 680e8aa513ce16834888c9ee28fee132149968e4 Author: Werner Koch Date: Sat Jun 9 11:40:18 2018 +0200 web: Fix URL typo and add a missing OID. diff --git a/web/index.org b/web/index.org index 526d214..28f73bd 100644 --- a/web/index.org +++ b/web/index.org @@ -70,7 +70,7 @@ The latest release news:\\ This version fixes a critical security bug. Either this version or a vendor provided fix should be installed. There are also a few other changes; see the [[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000425.html][announcement]] mail. This is [[https://cve.mitre.org/cgi-bin/cvename.cgi?name%3DCVE-2018-12020][CVE-2018-12020]] and our -bug [[https://dev/gnupg.org/T4012][#4012]]. +bug [[https://dev.gnupg.org/T4012][#4012]]. ** GnuPG 2.2.7 released (2018-05-02) diff --git a/web/oids.org b/web/oids.org index 86f77be..5b272cc 100644 --- a/web/oids.org +++ b/web/oids.org @@ -40,4 +40,9 @@ definitive list in the [[http://www.gnu.org/prep/standards/html_node/OID-Allocat - 1.3.6.1.4.1.11591.14.1 :: CRC 32 + - 1.3.6.1.4.1.11591.15 :: ellipticCurves + + - 1.3.6.1.4.1.11591.15.1 :: Ed25519 + + You can search for OIDs at [[http://www.alvestrand.no/objectid/][Alvestrand]] . ----------------------------------------------------------------------- Summary of changes: web/index.org | 2 +- web/oids.org | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 9 12:43:41 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 09 Jun 2018 12:43:41 +0200 Subject: [git] gnupg-doc - branch, master, updated. e709c9306139555af56b15ff202f1f119c4c56ff Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via e709c9306139555af56b15ff202f1f119c4c56ff (commit) from 680e8aa513ce16834888c9ee28fee132149968e4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e709c9306139555af56b15ff202f1f119c4c56ff Author: Werner Koch Date: Sat Jun 9 12:35:38 2018 +0200 web: New macro CVE and fix for latest CVE link. diff --git a/web/index.org b/web/index.org index 28f73bd..449f9a8 100644 --- a/web/index.org +++ b/web/index.org @@ -69,9 +69,8 @@ The latest release news:\\ This version fixes a critical security bug. Either this version or a vendor provided fix should be installed. There are also a few other -changes; see the [[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000425.html][announcement]] mail. This is [[https://cve.mitre.org/cgi-bin/cvename.cgi?name%3DCVE-2018-12020][CVE-2018-12020]] and our -bug [[https://dev.gnupg.org/T4012][#4012]]. - +changes; see the [[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000425.html][announcement]] mail. This is {{{CVE(2018-12020)}}} and +our bug [[https://dev.gnupg.org/T4012][#4012]]. ** GnuPG 2.2.7 released (2018-05-02) diff --git a/web/share/setup.inc b/web/share/setup.inc index c5517df..169acd5 100644 --- a/web/share/setup.inc +++ b/web/share/setup.inc @@ -17,3 +17,9 @@ #+macro: end_chksum @@html:@@ #+macro: twodashes @@html:--@@ + +# Org rendering of links with an included '=' is broken. Thus we use +# a macro here. +#+macro: CVE [[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-$1][CVE-$1]] + +# eof ----------------------------------------------------------------------- Summary of changes: web/index.org | 5 ++--- web/share/setup.inc | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 9 12:56:01 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 09 Jun 2018 12:56:01 +0200 Subject: [git] gnupg-doc - branch, master, updated. c51957c87d6e0724187f1332e39672e97ee6db80 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via c51957c87d6e0724187f1332e39672e97ee6db80 (commit) from e709c9306139555af56b15ff202f1f119c4c56ff (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c51957c87d6e0724187f1332e39672e97ee6db80 Author: Werner Koch Date: Sat Jun 9 12:47:58 2018 +0200 web: Add links to CVE ids. diff --git a/web/index.org b/web/index.org index 449f9a8..acb0c10 100644 --- a/web/index.org +++ b/web/index.org @@ -130,7 +130,7 @@ This is a maintenance release fixing a few minor bugs. {[[https://lists.gnupg.o We are pleased to announce the availability of [[file:software/libgcrypt/index.org][Libgcrypt]] version 1.8.1 and 1.7.9. These releases fix a local side-channel attack on Curve25519 encryption dubbed "May the Fourth be With You" -[CVE-2017-0379]. Read {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000414.html][more]]}... +{{{CVE(2017-0379)}}}. Read {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000414.html][more]]}... ** GnuPG 2.2.0 released (2017-08-28) diff --git a/web/news.org b/web/news.org index b78040c..0d4c9fe 100644 --- a/web/news.org +++ b/web/news.org @@ -27,7 +27,7 @@ section has the links. Although GnuPG 1.4 is of limited use today we did a maintenance release to address the recently published local side channel attack -CVE-2017-7526. See the [[../../download/index.org][download]] section on how to get this version. +{{{CVE(2017-7526)}}}. See the [[../../download/index.org][download]] section on how to get this version. ** Libgcrypt 1.8.0 released (2017-07-18) @@ -48,8 +48,8 @@ Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000409.h ** Libgcrypt 1.7.8 released (2017-06-29) :important: We are pleased to announce the availability of [[file:software/libgcrypt/index.org][Libgcrypt]] version -1.7.8. This release fixes a local side-channel attack -(CVE-2017-7526). See the [[https://lists.gnupg.org/pipermail/gnupg-announce/2017q2/000408.html][announcement mail]] for details. +1.7.8. This release fixes the local side-channel attack +{{{CVE(2017-7526)}}}. See the [[https://lists.gnupg.org/pipermail/gnupg-announce/2017q2/000408.html][announcement mail]] for details. ** GnuPG 2.1.21 released (2017-05-15) :important: @@ -136,7 +136,7 @@ Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000396.h A bug in the random number generator of Libgcrypt and in GnuPG 1.4 has been found. Updating the software is highly suggested. Please read this [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q3/000395.html][mail]] for details. Note that the CVE id in that mail is not -correct, the correct one is CVE-2016-6313. +correct, the correct one is {{{CVE(2016-6313)}}}. ** GnuPG 2.1.14 released (2016-07-14) ----------------------------------------------------------------------- Summary of changes: web/index.org | 2 +- web/news.org | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 9 14:13:04 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 09 Jun 2018 14:13:04 +0200 Subject: [git] gnupg-doc - branch, master, updated. baab91c9491518d3bfe82e70b986c1ae51a4007a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via baab91c9491518d3bfe82e70b986c1ae51a4007a (commit) from c51957c87d6e0724187f1332e39672e97ee6db80 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit baab91c9491518d3bfe82e70b986c1ae51a4007a Author: Werner Koch Date: Sat Jun 9 14:04:59 2018 +0200 web: news was missing the setup file diff --git a/web/news.org b/web/news.org index 0d4c9fe..9888d47 100644 --- a/web/news.org +++ b/web/news.org @@ -1,5 +1,6 @@ #+TITLE: GnuPG - All News #+STARTUP: showall +#+SETUPFILE: "share/setup.inc" * All News ----------------------------------------------------------------------- Summary of changes: web/news.org | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 9 17:13:45 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sat, 09 Jun 2018 17:13:45 +0200 Subject: [git] gnupg-doc - branch, master, updated. 52e91c8bf54485d76b640c2e2cdb380480377525 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 52e91c8bf54485d76b640c2e2cdb380480377525 (commit) from baab91c9491518d3bfe82e70b986c1ae51a4007a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 52e91c8bf54485d76b640c2e2cdb380480377525 Author: Ben McGinnes Date: Sun Jun 10 01:10:01 2018 +1000 bio: Ben * Updated my bio to include more relevant things, both inside and outside the GnuPG project. * Also adjusted the formatting and links for both Andre's keys and mine so that it will word wrap on phones, still be readable and have a little redundancy for retrieval (Andre's now links to gnupg.net and the SKS pool, but mine only has the latter for now). diff --git a/web/people/index.org b/web/people/index.org index 1fd53d1..fcfce89 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -91,16 +91,20 @@ Ben started working on GPGME in 2015 with the initial port of PyME from Python 2 to Python 3. Then returned to take over stewardship of Justus' enhanced version of that port from late 2017 onward. In - conjunction with with continuing work on documentation and - developing XML schemas for the XML format included in GPGME. + conjunction with with continuing work on documentation, developing + the XML definitions of various components of the project and + working on enhancements for whichGnuPG and OpenPGP can provide + other protocols, languages or services. - He is a co-founder of the original CryptoParty movement in - Melbourne, Australia, a founding member of Pirate Party Australia - and actively advocating for civil and human rights since the '90s. - Ben can sometimes be found on freenode IRC using the handle - =Hasimir= and, of course, on the GnuPG mailing lists. + He has been actively advocating for civil and human rights since + the '90s, including as a public [[https://www.securetheinternet.org/][signatory to the open letter]] to + world leaders to not undermine security and freedom. Ben can + sometimes be found on freenode IRC using the handle =Hasimir=, in + the fediverse as [[https://chaos.social/users/adversary][@adversary at chaos.social]], and, of course, on the + GnuPG mailing lists (most often posting from his own domain name, + [[http://www.adversary.org/wp/][adversary.org]]). - [[https://sks-keyservers.net/pks/lookup?op=get&search=0xDB4724E6FA4286C92B4E55C4321E4E2373590E5D][GPG key DB4724E6FA4286C92B4E55C4321E4E2373590E5D]] + GPG Key: [[https://sks-keyservers.net/pks/lookup?op=get&search=0xDB4724E6FA4286C92B4E55C4321E4E2373590E5D][DB47 24E6 FA42 86C9 2B4E]] [[https://sks-keyservers.net/pks/lookup?op=get&search=0xDB4724E6FA4286C92B4E55C4321E4E2373590E5D][55C4 321E 4E23 7359 0E5D]] #+HTML:

@@ -127,7 +131,7 @@ He is a founding member and the current cashier of the [[../verein/index.org][GnuPG e.V.]] - [[https://k.gnupg.net/94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][GPG key 94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1]] + GPG Key: [[https://k.gnupg.net/94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][94A5 C9a0 3C2F E5CA 3B09]] [[https://sks-keyservers.net/pks/lookup?op=get&search=0x94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][5D8E 1FDF 723C F462 B6B1]] #+HTML:

----------------------------------------------------------------------- Summary of changes: web/people/index.org | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jun 9 18:12:17 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sat, 09 Jun 2018 18:12:17 +0200 Subject: [git] gnupg-doc - branch, master, updated. 193c0ca9c47782e674df77eca999accb8de1a354 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 193c0ca9c47782e674df77eca999accb8de1a354 (commit) from 52e91c8bf54485d76b640c2e2cdb380480377525 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 193c0ca9c47782e674df77eca999accb8de1a354 Author: Ben McGinnes Date: Sun Jun 10 02:09:47 2018 +1000 bio typos * Fixed the inevitable typo from the previous update. * Also fixed one in Andre's (unsure if it came from the last edit or had been there longer than that). * Split my key's retrieval points between my site and the SKS keyservers. diff --git a/web/people/index.org b/web/people/index.org index fcfce89..612ecdb 100644 --- a/web/people/index.org +++ b/web/people/index.org @@ -93,18 +93,18 @@ of Justus' enhanced version of that port from late 2017 onward. In conjunction with with continuing work on documentation, developing the XML definitions of various components of the project and - working on enhancements for whichGnuPG and OpenPGP can provide + working on enhancements for which GnuPG and OpenPGP can provide other protocols, languages or services. He has been actively advocating for civil and human rights since the '90s, including as a public [[https://www.securetheinternet.org/][signatory to the open letter]] to world leaders to not undermine security and freedom. Ben can - sometimes be found on freenode IRC using the handle =Hasimir=, in + sometimes be found on [[irc://irc.freenode.net][Freenode IRC]] using the handle =Hasimir=, in the fediverse as [[https://chaos.social/users/adversary][@adversary at chaos.social]], and, of course, on the GnuPG mailing lists (most often posting from his own domain name, [[http://www.adversary.org/wp/][adversary.org]]). - GPG Key: [[https://sks-keyservers.net/pks/lookup?op=get&search=0xDB4724E6FA4286C92B4E55C4321E4E2373590E5D][DB47 24E6 FA42 86C9 2B4E]] [[https://sks-keyservers.net/pks/lookup?op=get&search=0xDB4724E6FA4286C92B4E55C4321E4E2373590E5D][55C4 321E 4E23 7359 0E5D]] + GPG Key: [[http://www.adversary.org/ben-key.asc][DB47 24E6 FA42 86C9 2B4E]] [[https://sks-keyservers.net/pks/lookup?op=get&search=0xDB4724E6FA4286C92B4E55C4321E4E2373590E5D][55C4 321E 4E23 7359 0E5D]] #+HTML:

@@ -117,21 +117,19 @@ /Windows and UX/ Andre is working mainly on GnuPG related projects for his employer - [[https://www.intevation.org][Intevation GmbH]] - He has been an active KDE Developer since 2009, + [[https://www.intevation.org][Intevation GmbH]] He has been an active KDE Developer since 2009, mostly focused on Windows ports of KDE Software. Since 2013 he took over several Windows and UX specific parts of GnuPG. Andre is the current maintainer of Kleopatra the KDE / Gpg4win GUI for GnuPG. He also maintains GpgOL since 2013 and wrote the - support for Outlook 2010 and later versions. - Additonally he is the maintainer of Gpg4win in general and GpgEX - as well as the GPGME bindings for C++ and Qt. + support for Outlook 2010 and later versions. Additonally he is the + maintainer of Gpg4win in general and GpgEX as well as the GPGME + bindings for C++ and Qt. - He is a founding member and the current cashier of the - [[../verein/index.org][GnuPG e.V.]] + He is a founding member and the current cashier of the [[../verein/index.org][GnuPG e.V.]] - GPG Key: [[https://k.gnupg.net/94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][94A5 C9a0 3C2F E5CA 3B09]] [[https://sks-keyservers.net/pks/lookup?op=get&search=0x94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][5D8E 1FDF 723C F462 B6B1]] + GPG Key: [[https://k.gnupg.net/94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][94A5 C9A0 3C2F E5CA 3B09]] [[https://sks-keyservers.net/pks/lookup?op=get&search=0x94A5C9A03C2FE5CA3B095D8E1FDF723CF462B6B1][5D8E 1FDF 723C F462 B6B1]] #+HTML:

----------------------------------------------------------------------- Summary of changes: web/people/index.org | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 17:06:17 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 10 Jun 2018 17:06:17 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-58-g92cd060 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 92cd060f5e2f4fdbfbe4812ebe8ef57e82e1609f (commit) from 8dff414e170e4df8ea661028c4ac1588311ca26e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 92cd060f5e2f4fdbfbe4812ebe8ef57e82e1609f Author: Ben McGinnes Date: Mon Jun 11 01:03:58 2018 +1000 script: groups.py * Added check for if it is run on a Windows system so that the correct binary filename is invoked. diff --git a/lang/python/examples/howto/groups.py b/lang/python/examples/howto/groups.py index fe31d7f..b8317b6 100644 --- a/lang/python/examples/howto/groups.py +++ b/lang/python/examples/howto/groups.py @@ -24,6 +24,7 @@ from __future__ import absolute_import, division, unicode_literals # . import subprocess +import sys """ Intended for use with other scripts. @@ -31,7 +32,12 @@ Intended for use with other scripts. Usage: from groups import group_lists """ -lines = subprocess.getoutput("gpgconf --list-options gpg").splitlines() +if sys.platform == "win32": + gpgconfcmd = "gpgconf.exe --list-options gpg" +else: + gpgconfcmd = "gpgconf --list-options gpg" + +lines = subprocess.getoutput(gpgconfcmd).splitlines() for i in range(len(lines)): if lines[i].startswith("group") is True: ----------------------------------------------------------------------- Summary of changes: lang/python/examples/howto/groups.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 17:09:19 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jun 2018 17:09:19 +0200 Subject: [git] gnupg-doc - branch, master, updated. 591b60c8a8fb18eeebdacc7567461fa0ed4398a2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 591b60c8a8fb18eeebdacc7567461fa0ed4398a2 (commit) from 193c0ca9c47782e674df77eca999accb8de1a354 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 591b60c8a8fb18eeebdacc7567461fa0ed4398a2 Author: Werner Koch Date: Sun Jun 10 17:00:48 2018 +0200 donations: Add monthly statistics diff --git a/web/donate/kudos.org b/web/donate/kudos.org index 03f4810..59123a2 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -6,15 +6,52 @@ * Donation Summary -*** Individual donations this year +*** Monthly donations stats since 2017 + +This is a summary of individual donations since 2017. After the +campaign boost in June and July 2017 we can conclude that a majority +of the received donations are reccurring (either monthly, quarterly or +yearly). The outlier in December 2017 is due to single large donation +of 5000 Euro. + + | Year | Mon | Total | SEPA | Stripe | Paypal | gSEPA | Fee | + |------+-----+-------+------+--------+--------+-------+-----| + | 2017 | 01 | 1771 | 271 | 136 | 1364 | 278 | 7 | + | | 02 | 573 | 15 | 371 | 187 | 20 | 5 | + | | 03 | 339 | 104 | 5 | 230 | 110 | 6 | + | | 04 | 5407 | 4995 | 264 | 148 | 5000 | 5 | + | | 05 | 587 | 5 | 509 | 73 | 10 | 5 | + | | 06 | 29117 | 5291 | 9887 | 13939 | 5351 | 60 | + | | 07 | 14594 | 2356 | 5776 | 6462 | 2410 | 54 | + | | 08 | 6905 | 1466 | 2319 | 3120 | 1509 | 43 | + | | 09 | 7617 | 1214 | 3105 | 3298 | 1257 | 43 | + | | 10 | 6051 | 1182 | 2514 | 2355 | 1227 | 45 | + | | 11 | 5426 | 884 | 2405 | 2137 | 920 | 36 | + | | 12 | 12003 | 1392 | 3047 | 7564 | 1437 | 45 | + | 2018 | 01 | 6538 | 1646 | 2422 | 2470 | 1696 | 50 | + | | 02 | 4505 | 838 | 1705 | 1962 | 875 | 37 | + | | 03 | 7078 | 1058 | 2574 | 3446 | 1101 | 43 | + | | 04 | 5230 | 1093 | 1868 | 2269 | 1137 | 44 | + | | 05 | 5005 | 1008 | 1778 | 2219 | 1047 | 39 | + #+TBLFM: $3=$4+$5+$6::$4=$7-$8 -#+BEGIN_HTML - - -#+END_HTML +#+HTML:

+Legend: ?Total? gives the total net donations in Euro received in that +month. ?SEPA?, ?Stripe? and ?Paypal? are the net donation from the +respective payment provider. The ?gSEPA? column gives the gross +donations for the SEPA account; the ?Fee? column its bank fees. We do +not record the Stripe payment processing costs. The detailed Paypal +amounts can be found at this [[file:paypal-summary.org][page]]. One-time and recurring donations +are not distinguished. +#+HTML:
+ + +*** Yearly donation stats +This is a summary of all donations received by g10 Code GmbH to +support GnuPG development. -*** Previous years +Note: 2017 has not yet been entered. | Year | # | Indi. | Corp. | Total \EUR | | | | | | | @@ -71,9 +108,22 @@ Goteo transferred that money in March 2014 in 6 chunks: 11423, 6000, 5000, 5000, 5218. The total amount is however listed for 2013 along with 148 individual donations of 5041 Euro (4041 net) received before the start of the Goteo campaign. - #+HTML: + + +*** Individual donations this year + +This is the an automatically updated list of donations received via +the online donation system. These are raw numbers and don't include +fees, chargebacks etc. + +#+BEGIN_HTML + + +#+END_HTML + + * List of Donors #+HTML:
    diff --git a/web/donate/paypal-summary.org b/web/donate/paypal-summary.org new file mode 100644 index 0000000..2437003 --- /dev/null +++ b/web/donate/paypal-summary.org @@ -0,0 +1,62 @@ +#+TITLE: GnuPG - Paypal donation summry +#+STARTUP: showall +#+SETUPFILE: "../share/setup.inc" + +#+HTML: + +*** Paypal separated by currency + + | Year | Mon | EUR | fee | GBP | fee | USD | fee | JPY | fee | nEUR | nGBP | nUSD | nJPY | xUSD | xGBP | xJPY | total | + |------+-----+-------+-----+-----+-----+------+-----+-------+------+-------+------+------+------+--------+---------+--------+-------| + | 2017 | 01 | 145 | 12 | | | 1394 | 73 | 500 | 100 | 133 | 0 | 1228 | 3 | 1.0755 | 0.86105 | 121.94 | 1364 | + | | 02 | 85 | 6 | 10 | 1 | 110 | 7 | | | 79 | 11 | 97 | 0 | 1.0597 | 0.85305 | 118.83 | 187 | + | | 03 | 225 | 13 | | | 20 | 1 | | | 212 | 0 | 18 | 0 | 1.0691 | 0.85553 | 119.55 | 230 | + | | 04 | 139 | 5 | 5 | 0 | 10 | 1 | | | 134 | 6 | 8 | 0 | 1.093 | 0.84473 | 121.76 | 148 | + | | 05 | 55 | 3 | | | 26 | 2 | | | 52 | 0 | 21 | 0 | 1.1221 | 0.87365 | 124.4 | 73 | + | | 06 | 11140 | 439 | 158 | 9 | 3148 | 161 | 61500 | 3700 | 10701 | 169 | 2617 | 452 | 1.1412 | 0.87933 | 127.75 | 13939 | + | | 07 | 4003 | 219 | 255 | 13 | 2838 | 143 | 15000 | 900 | 3784 | 271 | 2298 | 109 | 1.1727 | 0.8942 | 129.7 | 6462 | + | | 08 | 1952 | 119 | 120 | 7 | 1413 | 79 | 5000 | 300 | 1833 | 123 | 1128 | 36 | 1.1825 | 0.91973 | 130.81 | 3120 | + | | 09 | 2489 | 145 | 150 | 8 | 995 | 59 | | | 2344 | 161 | 793 | 0 | 1.1806 | 0.88178 | 132.82 | 3298 | + | | 10 | 1699 | 112 | 35 | 3 | 905 | 53 | | | 1587 | 36 | 732 | 0 | 1.1638 | 0.87853 | 132 | 2355 | + | | 11 | 1585 | 102 | 55 | 3 | 750 | 45 | | | 1483 | 59 | 595 | 0 | 1.1849 | 0.87985 | 133.08 | 2137 | + | | 12 | 7078 | 335 | 90 | 5 | 926 | 56 | | | 6743 | 96 | 725 | 0 | 1.1993 | 0.88723 | 135.01 | 7564 | + | 2018 | 01 | 1902 | 116 | 36 | 3 | 855 | 50 | | | 1786 | 38 | 646 | 0 | 1.2457 | 0.8791 | 135.6 | 2470 | + | | 02 | 1493 | 97 | 54 | 3 | 660 | 39 | | | 1396 | 58 | 508 | 0 | 1.2214 | 0.88415 | 130.72 | 1962 | + | | 03 | 1762 | 110 | 50 | 3 | 2267 | 123 | | | 1652 | 54 | 1740 | 0 | 1.2321 | 0.8749 | 131.15 | 3446 | + | | 04 | 1763 | 104 | 35 | 2 | 735 | 44 | | | 1659 | 38 | 572 | 0 | 1.2079 | 0.8796 | 132.12 | 2269 | + | | 05 | 1638 | 98 | 35 | 2 | 797 | 47 | | | 1540 | 38 | 641 | 0 | 1.1699 | 0.8768 | 127.33 | 2219 | + | | | | | | | | | | | 0 | 0 | 0 | 0 | | | | 0 | + #+TBLFM: $11=$3-$4::$12=($5-$6)/$16;%.0f::$13=($7-$8)/$15;%.0f::$14=($9-$10)/$17;%.0f::$18=$11+$12+$13+$14 + +#+HTML:
    +/nEUR/, /nGBP/, /nUSD/ and /nJPY/ are the net donations converted to +Euro using the exchange rate from the last banking day of the month +(/xUSD/,/xGBP/, /xJPL/ columns). Actually received values may differ +because the conversion to Euro is triggered manually as needed. +Values are rounded to a full Euro, USD, Pound or to 100 Yen. +#+HTML:
    + + +*** Exchange rates + +Taken from the ZIP file found at [[https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html][ECB page]]. + +| Date | USD | GBP | JPY | +|-------------+--------+---------+--------| +| 2017-Jan-31 | 1.0755 | 0.86105 | 121.94 | +| 2017-Feb-28 | 1.0597 | 0.85305 | 118.83 | +| 2017-Mar-31 | 1.0691 | 0.85553 | 119.55 | +| 2017-Apr-28 | 1.093 | 0.84473 | 121.76 | +| 2017-May-31 | 1.1221 | 0.87365 | 124.4 | +| 2017-Jun-30 | 1.1412 | 0.87933 | 127.75 | +| 2017-Jul-31 | 1.1727 | 0.8942 | 129.7 | +| 2017-Aug-31 | 1.1825 | 0.91973 | 130.81 | +| 2017-Sep-29 | 1.1806 | 0.88178 | 132.82 | +| 2017-Oct-31 | 1.1638 | 0.87853 | 132 | +| 2017-Nov-30 | 1.1849 | 0.87985 | 133.08 | +| 2017-Dec-29 | 1.1993 | 0.88723 | 135.01 | +| 2018-Jan-31 | 1.2457 | 0.8791 | 135.6 | +| 2018-Feb-28 | 1.2214 | 0.88415 | 130.72 | +| 2018-Mar-29 | 1.2321 | 0.8749 | 131.15 | +| 2018-Apr-30 | 1.2079 | 0.8796 | 132.12 | +| 2018-May-31 | 1.1699 | 0.8768 | 127.33 | ----------------------------------------------------------------------- Summary of changes: web/donate/kudos.org | 64 ++++++++++++++++++++++++++++++++++++++----- web/donate/paypal-summary.org | 62 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 web/donate/paypal-summary.org hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 17:51:36 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jun 2018 17:51:36 +0200 Subject: [git] gnupg-doc - branch, master, updated. 34aadf0da76b43f31c32b08940d7fcc8cbf79590 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 34aadf0da76b43f31c32b08940d7fcc8cbf79590 (commit) from 591b60c8a8fb18eeebdacc7567461fa0ed4398a2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 34aadf0da76b43f31c32b08940d7fcc8cbf79590 Author: Werner Koch Date: Sun Jun 10 17:43:49 2018 +0200 donations: Add stats for 2017 diff --git a/web/donate/kudos-2018.org b/web/donate/kudos-2018.org new file mode 100644 index 0000000..748a5d6 --- /dev/null +++ b/web/donate/kudos-2018.org @@ -0,0 +1,19 @@ +#+TITLE: GnuPG - List of Donors - 2018 +#+STARTUP: showall +#+SETUPFILE: "../share/setup.inc" + +* People who donated money to GnuPG in 2018 + +#+HTML:
      +#+HTML: +#+HTML:
    • [please reload in a few minutes while the list is being updated] +#+HTML: +#+HTML:
    + +#+HTML:
    +(* marks recurring donations) +#+HTML:
    + + + + Thank you. diff --git a/web/donate/kudos.org b/web/donate/kudos.org index 59123a2..cb43443 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -6,56 +6,15 @@ * Donation Summary -*** Monthly donations stats since 2017 - -This is a summary of individual donations since 2017. After the -campaign boost in June and July 2017 we can conclude that a majority -of the received donations are reccurring (either monthly, quarterly or -yearly). The outlier in December 2017 is due to single large donation -of 5000 Euro. - - | Year | Mon | Total | SEPA | Stripe | Paypal | gSEPA | Fee | - |------+-----+-------+------+--------+--------+-------+-----| - | 2017 | 01 | 1771 | 271 | 136 | 1364 | 278 | 7 | - | | 02 | 573 | 15 | 371 | 187 | 20 | 5 | - | | 03 | 339 | 104 | 5 | 230 | 110 | 6 | - | | 04 | 5407 | 4995 | 264 | 148 | 5000 | 5 | - | | 05 | 587 | 5 | 509 | 73 | 10 | 5 | - | | 06 | 29117 | 5291 | 9887 | 13939 | 5351 | 60 | - | | 07 | 14594 | 2356 | 5776 | 6462 | 2410 | 54 | - | | 08 | 6905 | 1466 | 2319 | 3120 | 1509 | 43 | - | | 09 | 7617 | 1214 | 3105 | 3298 | 1257 | 43 | - | | 10 | 6051 | 1182 | 2514 | 2355 | 1227 | 45 | - | | 11 | 5426 | 884 | 2405 | 2137 | 920 | 36 | - | | 12 | 12003 | 1392 | 3047 | 7564 | 1437 | 45 | - | 2018 | 01 | 6538 | 1646 | 2422 | 2470 | 1696 | 50 | - | | 02 | 4505 | 838 | 1705 | 1962 | 875 | 37 | - | | 03 | 7078 | 1058 | 2574 | 3446 | 1101 | 43 | - | | 04 | 5230 | 1093 | 1868 | 2269 | 1137 | 44 | - | | 05 | 5005 | 1008 | 1778 | 2219 | 1047 | 39 | - #+TBLFM: $3=$4+$5+$6::$4=$7-$8 - -#+HTML:
    -Legend: ?Total? gives the total net donations in Euro received in that -month. ?SEPA?, ?Stripe? and ?Paypal? are the net donation from the -respective payment provider. The ?gSEPA? column gives the gross -donations for the SEPA account; the ?Fee? column its bank fees. We do -not record the Stripe payment processing costs. The detailed Paypal -amounts can be found at this [[file:paypal-summary.org][page]]. One-time and recurring donations -are not distinguished. -#+HTML:
    - - *** Yearly donation stats This is a summary of all donations received by g10 Code GmbH to support GnuPG development. -Note: 2017 has not yet been entered. - | Year | # | Indi. | Corp. | Total \EUR | | | | | | | |------+------+--------+--------+------------| +| 2017 | | 90390 | 154104 | 244494 | | 2016 | 271 | 9615 | 146759 | 156374 | | 2015 | 5847 | 205560 | 144262 | 337954 | | 2014 | 801 | 34700 | | 30305 | @@ -63,8 +22,8 @@ Note: 2017 has not yet been entered. | 2012 | 53 | 5991 | | 4963 | | 2011 | 21 | 553 | | 465 | |------+------+--------+--------+------------| -| | | 294101 | 291021 | 561531 | -#+TBLFM: $LR3=vsum(@I.. at II)::$LR4=vsum(@I.. at II)::$LR5=vsum(@I.. at II) +| | | 384491 | 445125 | 561531 | +#+TBLFM: $5=$3+$4::$LR3=vsum(@I.. at II)::$LR4=vsum(@I.. at II)::$LR5=vsum(@I.. at II) #+HTML:
    Legend: ?Indi.? indicates individual donations, ?Corp.? lists large @@ -73,6 +32,24 @@ without taxes and banking fees. Note that this list has been updated on 2017-05-02 to include the Linux Foundation grant. Note further that the ?Total? for 2016 is preliminary. +# About 2017:\\ +# | Individual Donations | 90390 | bank fees already deducted +# |----------------------+--------| +# | Company | amount | Remarks | +# |------------------+--------+------------------------| +# | Facebook | 42038 | bank fees = 42 Euro | +# | Stripe | 42441 | no bank fess | +# | Linux Foundation | 47369 | bank fees = 11*15 Euro | +# | First Look Media | 22256 | bank fess = 22 Euro | +# |------------------+--------+------------------------| +# | | 154104 | | +In 2017 we launched a campaign and started the recurring donation +programm. All individual donations summed up to a net ammount of +90390 Euro. We received 50000 USD each from Stripe and Facebook +(42038 + 42441 Euro net). The Linux Foundation granted 55000 USD +(47369 Euro net). To support the recurring donation campaign we also +received 25000 USD (22256 Euro net) from First Look Media. + # About 2016:\\ # | Individual Donations | 268 | 9615 | | # | Facebook | 1 | 44715 | 44715 | @@ -110,7 +87,44 @@ with 148 individual donations of 5041 Euro (4041 net) received before the start of the Goteo campaign. #+HTML:
    +*** Monthly donations stats since 2017 + +This is a summary of individual donations since 2017. After the +campaign boost in June and July 2017 we can conclude that a majority +of the received donations are now reccurring (either monthly, +quarterly or yearly). The outlier in December 2017 is a single large +donation of 5000 Euro. + + | Year | Mon | Total | SEPA | Stripe | Paypal | gSEPA | Fee | + |------+-----+-------+------+--------+--------+-------+-----| + | 2017 | 01 | 1771 | 271 | 136 | 1364 | 278 | 7 | + | | 02 | 573 | 15 | 371 | 187 | 20 | 5 | + | | 03 | 339 | 104 | 5 | 230 | 110 | 6 | + | | 04 | 5407 | 4995 | 264 | 148 | 5000 | 5 | + | | 05 | 587 | 5 | 509 | 73 | 10 | 5 | + | | 06 | 29117 | 5291 | 9887 | 13939 | 5351 | 60 | + | | 07 | 14594 | 2356 | 5776 | 6462 | 2410 | 54 | + | | 08 | 6905 | 1466 | 2319 | 3120 | 1509 | 43 | + | | 09 | 7617 | 1214 | 3105 | 3298 | 1257 | 43 | + | | 10 | 6051 | 1182 | 2514 | 2355 | 1227 | 45 | + | | 11 | 5426 | 884 | 2405 | 2137 | 920 | 36 | + | | 12 | 12003 | 1392 | 3047 | 7564 | 1437 | 45 | + | 2018 | 01 | 6538 | 1646 | 2422 | 2470 | 1696 | 50 | + | | 02 | 4505 | 838 | 1705 | 1962 | 875 | 37 | + | | 03 | 7078 | 1058 | 2574 | 3446 | 1101 | 43 | + | | 04 | 5230 | 1093 | 1868 | 2269 | 1137 | 44 | + | | 05 | 5005 | 1008 | 1778 | 2219 | 1047 | 39 | + #+TBLFM: $3=$4+$5+$6::$4=$7-$8 +#+HTML:
    +Legend: ?Total? gives the total net donations in Euro received in that +month. ?SEPA?, ?Stripe? and ?Paypal? are the net donation from the +respective payment provider. The ?gSEPA? column gives the gross +donations for the SEPA account; the ?Fee? column its bank fees. We do +not record the Stripe payment processing costs. The detailed Paypal +amounts can be found at this [[file:paypal-summary.org][page]]. One-time and recurring donations +are not distinguished. +#+HTML:
    *** Individual donations this year @@ -139,6 +153,7 @@ fees, chargebacks etc. Thank you. + - All donors to GnuPG in [[file:kudos-2017.org][2018]] - All donors to GnuPG in [[file:kudos-2017.org][2017]] - All donors to GnuPG in [[file:kudos-2016.org][2016]] - All donors to GnuPG in [[file:kudos-2015.org][2015]] ----------------------------------------------------------------------- Summary of changes: web/donate/{kudos-2017.org => kudos-2018.org} | 4 +- web/donate/kudos.org | 103 +++++++++++++++----------- 2 files changed, 61 insertions(+), 46 deletions(-) copy web/donate/{kudos-2017.org => kudos-2018.org} (78%) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 17:55:24 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jun 2018 17:55:24 +0200 Subject: [git] gnupg-doc - branch, master, updated. e0195fc71ef51b05c3418f3af4bbe975c5c3d787 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via e0195fc71ef51b05c3418f3af4bbe975c5c3d787 (commit) from 34aadf0da76b43f31c32b08940d7fcc8cbf79590 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e0195fc71ef51b05c3418f3af4bbe975c5c3d787 Author: Werner Koch Date: Sun Jun 10 17:47:23 2018 +0200 donations: Add a remark to the auto created list diff --git a/web/donate/kudos.org b/web/donate/kudos.org index cb43443..018aba6 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -118,7 +118,7 @@ donation of 5000 Euro. #+HTML:
    Legend: ?Total? gives the total net donations in Euro received in that -month. ?SEPA?, ?Stripe? and ?Paypal? are the net donation from the +month. ?SEPA?, ?Stripe? and ?Paypal? are the net donations from the respective payment provider. The ?gSEPA? column gives the gross donations for the SEPA account; the ?Fee? column its bank fees. We do not record the Stripe payment processing costs. The detailed Paypal @@ -130,7 +130,7 @@ are not distinguished. This is the an automatically updated list of donations received via the online donation system. These are raw numbers and don't include -fees, chargebacks etc. +recurred or SEPA donations, fees, chargebacks etc. #+BEGIN_HTML ----------------------------------------------------------------------- Summary of changes: web/donate/kudos.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 18:00:21 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jun 2018 18:00:21 +0200 Subject: [git] gnupg-doc - branch, master, updated. d4b98f9c0c55dab1d2a47a76c88851762bc0ab21 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via d4b98f9c0c55dab1d2a47a76c88851762bc0ab21 (commit) from e0195fc71ef51b05c3418f3af4bbe975c5c3d787 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d4b98f9c0c55dab1d2a47a76c88851762bc0ab21 Author: Werner Koch Date: Sun Jun 10 17:52:19 2018 +0200 donations: Try a tag cloud list for the 2018 donors. diff --git a/web/donate/kudos-2018.org b/web/donate/kudos-2018.org index 748a5d6..d72a850 100644 --- a/web/donate/kudos-2018.org +++ b/web/donate/kudos-2018.org @@ -4,11 +4,11 @@ * People who donated money to GnuPG in 2018 -#+HTML:
      +#+HTML:
        #+HTML: #+HTML:
      • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
      +#+HTML:

    #+HTML:
    (* marks recurring donations) ----------------------------------------------------------------------- Summary of changes: web/donate/kudos-2018.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 18:00:51 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jun 2018 18:00:51 +0200 Subject: [git] gnupg-doc - branch, master, updated. 1cbec4b8d0cb0a7b1c35b52191dd0df19f4d4fae Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 1cbec4b8d0cb0a7b1c35b52191dd0df19f4d4fae (commit) from d4b98f9c0c55dab1d2a47a76c88851762bc0ab21 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1cbec4b8d0cb0a7b1c35b52191dd0df19f4d4fae Author: Werner Koch Date: Sun Jun 10 17:53:04 2018 +0200 donations: Fix a link diff --git a/web/donate/kudos.org b/web/donate/kudos.org index 018aba6..71a7ce4 100644 --- a/web/donate/kudos.org +++ b/web/donate/kudos.org @@ -153,7 +153,7 @@ recurred or SEPA donations, fees, chargebacks etc. Thank you. - - All donors to GnuPG in [[file:kudos-2017.org][2018]] + - All donors to GnuPG in [[file:kudos-2018.org][2018]] - All donors to GnuPG in [[file:kudos-2017.org][2017]] - All donors to GnuPG in [[file:kudos-2016.org][2016]] - All donors to GnuPG in [[file:kudos-2015.org][2015]] ----------------------------------------------------------------------- Summary of changes: web/donate/kudos.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 10 19:31:09 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 10 Jun 2018 19:31:09 +0200 Subject: [git] gnupg-doc - branch, master, updated. 031285b8ea7debdb90c497b29a0e25894c6a76a5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 031285b8ea7debdb90c497b29a0e25894c6a76a5 (commit) from 1cbec4b8d0cb0a7b1c35b52191dd0df19f4d4fae (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 031285b8ea7debdb90c497b29a0e25894c6a76a5 Author: Werner Koch Date: Sun Jun 10 19:23:15 2018 +0200 donations: Use a tag cloud for all years diff --git a/web/donate/kudos-2011.org b/web/donate/kudos-2011.org index 6c9c1ab..f5577fe 100644 --- a/web/donate/kudos-2011.org +++ b/web/donate/kudos-2011.org @@ -4,10 +4,11 @@ * People who donated money to GnuPG in 2011 -#+HTML:
      +#+HTML:
        #+HTML: #+HTML:
      • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
      +#+HTML:

    + Thank you. diff --git a/web/donate/kudos-2012.org b/web/donate/kudos-2012.org index d2bf44c..719cb6a 100644 --- a/web/donate/kudos-2012.org +++ b/web/donate/kudos-2012.org @@ -4,11 +4,12 @@ * People who donated money to GnuPG in 2012 -#+HTML:
      +#+HTML:
        #+HTML: #+HTML:
      • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
      +#+HTML:

+ Thank you. diff --git a/web/donate/kudos-2013.org b/web/donate/kudos-2013.org index 0d8802d..a33f73c 100644 --- a/web/donate/kudos-2013.org +++ b/web/donate/kudos-2013.org @@ -4,11 +4,11 @@ * People who donated money to GnuPG in 2013 -#+HTML:
    +#+HTML:
      #+HTML: #+HTML:
    • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
    +#+HTML:

Thank you. diff --git a/web/donate/kudos-2014.org b/web/donate/kudos-2014.org index ecf4ac9..d94c183 100644 --- a/web/donate/kudos-2014.org +++ b/web/donate/kudos-2014.org @@ -4,11 +4,11 @@ * People who donated money to GnuPG in 2014 -#+HTML:
    +#+HTML:
      #+HTML: #+HTML:
    • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
    +#+HTML:

Thank you. diff --git a/web/donate/kudos-2015.org b/web/donate/kudos-2015.org index 2f50c45..5d504e8 100644 --- a/web/donate/kudos-2015.org +++ b/web/donate/kudos-2015.org @@ -4,10 +4,10 @@ * People who donated money to GnuPG in 2015 -#+HTML:
    +#+HTML:
      #+HTML: #+HTML:
    • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
    +#+HTML:

Thank you. diff --git a/web/donate/kudos-2016.org b/web/donate/kudos-2016.org index 81ec977..9a7a9a0 100644 --- a/web/donate/kudos-2016.org +++ b/web/donate/kudos-2016.org @@ -4,10 +4,11 @@ * People who donated money to GnuPG in 2016 -#+HTML:
    +#+HTML:
      #+HTML: #+HTML:
    • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
    +#+HTML:

+ Thank you. diff --git a/web/donate/kudos-2017.org b/web/donate/kudos-2017.org index fd6bce5..169db9a 100644 --- a/web/donate/kudos-2017.org +++ b/web/donate/kudos-2017.org @@ -4,11 +4,11 @@ * People who donated money to GnuPG in 2017 -#+HTML:
    +#+HTML:
      #+HTML: #+HTML:
    • [please reload in a few minutes while the list is being updated] #+HTML: -#+HTML:
    +#+HTML:

#+HTML:
(* marks recurring donations) ----------------------------------------------------------------------- Summary of changes: web/donate/kudos-2011.org | 5 +++-- web/donate/kudos-2012.org | 5 +++-- web/donate/kudos-2013.org | 4 ++-- web/donate/kudos-2014.org | 4 ++-- web/donate/kudos-2015.org | 4 ++-- web/donate/kudos-2016.org | 5 +++-- web/donate/kudos-2017.org | 4 ++-- 7 files changed, 17 insertions(+), 14 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 07:55:38 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 11 Jun 2018 07:55:38 +0200 Subject: [git] GnuPG - branch, gniibe/decryption-key, updated. gnupg-2.2.7-139-gc03a3eb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, gniibe/decryption-key has been updated via c03a3eb01d2d26bd69e6d7c7d2a5f72229e189e0 (commit) from fed3e10121a76cf270e72ff0bcf31a4ed40068e8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c03a3eb01d2d26bd69e6d7c7d2a5f72229e189e0 Author: NIIBE Yutaka Date: Mon Jun 11 11:48:14 2018 +0900 g10: Enumerated keys for decryption should be unique. * g10/getkey.c (enum_secret_keys): Collecting keys in the context, check duplicate to make sure returning only unique keys. * g10/pubkey-enc.c (get_session_key): Now, it's the responsibility of enum_secret_keys to free keys. -- Signed-off-by: NIIBE Yutaka diff --git a/g10/getkey.c b/g10/getkey.c index b111376..670dc1d 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3950,6 +3950,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) kbnode_t keyblock; kbnode_t node; getkey_ctx_t ctx; + pubkey_t results; } *c = *context; if (!c) @@ -3964,6 +3965,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) if (!sk) { /* Free the context. */ + pubkeys_free (c->results); release_kbnode (c->keyblock); getkey_end (ctrl, c->ctx); xfree (c); @@ -4066,8 +4068,31 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) if (c->node->pkt->pkttype == PKT_PUBLIC_KEY || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY) { + pubkey_t r; + + /* Skip this candidate if it's already enumerated. */ + for (r = c->results; r; r = r->next) + if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key)) + break; + if (r) + continue; + copy_public_key (sk, c->node->pkt->pkt.public_key); c->node = c->node->next; + + r = xtrycalloc (1, sizeof (*r)); + if (!r) + { + err = gpg_error_from_syserror (); + free_public_key (sk); + return err; + } + + r->pk = sk; + r->keyblock = NULL; + r->next = c->results; + c->results = r; + return 0; /* Found. */ } } diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 8540e03..32b1ed0 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -87,7 +87,6 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) { struct pubkey_enc_list *k; - free_public_key (sk); sk = xmalloc_clear (sizeof *sk); rc = enum_secret_keys (ctrl, &enum_context, sk); if (rc) @@ -156,7 +155,6 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) } } enum_secret_keys (ctrl, &enum_context, NULL); /* free context */ - free_public_key (sk); if (DBG_CLOCK) log_clock ("get_session_key leave"); ----------------------------------------------------------------------- Summary of changes: g10/getkey.c | 25 +++++++++++++++++++++++++ g10/pubkey-enc.c | 2 -- 2 files changed, 25 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 08:56:55 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 08:56:55 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-145-gd2bc66f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via d2bc66f241a66cc95140cbb3a07555f6301290ed (commit) from 13f135c7a252cc46cff96e75968d92b6dc8dce1b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d2bc66f241a66cc95140cbb3a07555f6301290ed Author: Werner Koch Date: Mon Jun 11 08:46:37 2018 +0200 gpg: Set some list options with --show-keys * g10/gpg.c (main): Set some list options. -- The new command --show-keys is commonly used to check the content of a file with keys. In this case it can be expected that all included subkeys and uids are of interested, even when they are already expired or have been revoked. Signed-off-by: Werner Koch diff --git a/doc/gpg.texi b/doc/gpg.texi index 9db2365..5f114c5 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -356,9 +356,11 @@ be used to locate a key. Only public keys are listed. @item --show-keys @opindex show-keys This commands takes OpenPGP keys as input and prints information about -them in the same way the command @option{--list-keys} does for -imported key. No internal state is changed. For automated processing -this command should be combined with the option +them in the same way the command @option{--list-keys} does for locally +stored key. In addition the list options @code{show-unusable-uids}, + at code{show-unusable-subkeys}, @code{show-notations} and + at code{show-policy-urls} are also enabled. As usual for automated +processing, this command should be combined with the option @option{--with-colons}. @item --fingerprint diff --git a/g10/gpg.c b/g10/gpg.c index 499c005..8effc53 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2650,6 +2650,10 @@ main (int argc, char **argv) opt.import_options |= IMPORT_SHOW; opt.import_options |= IMPORT_DRY_RUN; opt.import_options &= ~IMPORT_REPAIR_KEYS; + opt.list_options |= LIST_SHOW_UNUSABLE_UIDS; + opt.list_options |= LIST_SHOW_UNUSABLE_SUBKEYS; + opt.list_options |= LIST_SHOW_NOTATIONS; + opt.list_options |= LIST_SHOW_POLICY_URLS; break; case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 8 +++++--- g10/gpg.c | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 08:58:31 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 08:58:31 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-3-gcbb84b3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via cbb84b3361263504dcb958208bc20177cb97cebd (commit) from 18274db32b5dea7fe8db67043a787578c975de4d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cbb84b3361263504dcb958208bc20177cb97cebd Author: Werner Koch Date: Mon Jun 11 08:46:37 2018 +0200 gpg: Set some list options with --show-keys * g10/gpg.c (main): Set some list options. -- The new command --show-keys is commonly used to check the content of a file with keys. In this case it can be expected that all included subkeys and uids are of interested, even when they are already expired or have been revoked. Signed-off-by: Werner Koch (cherry picked from commit d2bc66f241a66cc95140cbb3a07555f6301290ed) diff --git a/doc/gpg.texi b/doc/gpg.texi index ca13047..2915d25 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -356,9 +356,11 @@ be used to locate a key. Only public keys are listed. @item --show-keys @opindex show-keys This commands takes OpenPGP keys as input and prints information about -them in the same way the command @option{--list-keys} does for -imported key. No internal state is changed. For automated processing -this command should be combined with the option +them in the same way the command @option{--list-keys} does for locally +stored key. In addition the list options @code{show-unusable-uids}, + at code{show-unusable-subkeys}, @code{show-notations} and + at code{show-policy-urls} are also enabled. As usual for automated +processing, this command should be combined with the option @option{--with-colons}. @item --fingerprint diff --git a/g10/gpg.c b/g10/gpg.c index b76a039..c117de3 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2610,6 +2610,10 @@ main (int argc, char **argv) opt.import_options |= IMPORT_SHOW; opt.import_options |= IMPORT_DRY_RUN; opt.import_options &= ~IMPORT_REPAIR_KEYS; + opt.list_options |= LIST_SHOW_UNUSABLE_UIDS; + opt.list_options |= LIST_SHOW_UNUSABLE_SUBKEYS; + opt.list_options |= LIST_SHOW_NOTATIONS; + opt.list_options |= LIST_SHOW_POLICY_URLS; break; case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 8 +++++--- g10/gpg.c | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 09:03:53 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 09:03:53 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-4-gdc96fd8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via dc96fd883571a975cfea0882fd38d7b0dd78775b (commit) from cbb84b3361263504dcb958208bc20177cb97cebd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dc96fd883571a975cfea0882fd38d7b0dd78775b Author: Werner Koch Date: Mon Jun 11 08:56:04 2018 +0200 doc: Mention new command --show-keys in the 2.2.7 NEWS. -- diff --git a/NEWS b/NEWS index 7b34436..03ea514 100644 --- a/NEWS +++ b/NEWS @@ -26,9 +26,13 @@ Noteworthy changes in version 2.2.8 (2018-06-08) * gpg: The options --no-mdc-warn, --force-mdc, --no-force-mdc, --disable-mdc and --no-disable-mdc have no more effect. + * gpg: New command --show-keys. + * agent: Add DBUS_SESSION_BUS_ADDRESS and a few other envvars to the list of startup environment variables. [#3947] + See-also: gnupg-announce/2018q2/000425.html + Noteworthy changes in version 2.2.7 (2018-05-02) ------------------------------------------------ ----------------------------------------------------------------------- Summary of changes: NEWS | 4 ++++ 1 file changed, 4 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 09:03:57 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 09:03:57 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-146-g615b9d1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 615b9d1fb779f3d5593484aa1e023b0ddff459f0 (commit) from d2bc66f241a66cc95140cbb3a07555f6301290ed (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 615b9d1fb779f3d5593484aa1e023b0ddff459f0 Author: Werner Koch Date: Mon Jun 11 08:55:20 2018 +0200 doc: Include release info from 2.2.8 -- diff --git a/NEWS b/NEWS index 48f4fdb..232d8be 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,36 @@ Noteworthy changes in version 2.3.0 (unreleased) ------------------------------------------------ + Changes also found in 2.2.8: + + * gpg: Decryption of messages not using the MDC mode will now lead + to a hard failure even if a legacy cipher algorithm was used. The + option --ignore-mdc-error can be used to turn this failure into a + warning. Take care: Never use that option unconditionally or + without a prior warning. + + * gpg: The MDC encryption mode is now always used regardless of the + cipher algorithm or any preferences. For testing --rfc2440 can be + used to create a message without an MDC. + + * gpg: Sanitize the diagnostic output of the original file name in + verbose mode. [#4012,CVE-2018-12020] + + * gpg: Detect suspicious multiple plaintext packets in a more + reliable way. [#4000] + + * gpg: Fix the duplicate key signature detection code. [#3994] + + * gpg: The options --no-mdc-warn, --force-mdc, --no-force-mdc, + --disable-mdc and --no-disable-mdc have no more effect. + + * gpg: New command --show-keys. + + * agent: Add DBUS_SESSION_BUS_ADDRESS and a few other envvars to the + list of startup environment variables. [#3947] + + See-also: gnupg-announce/2018q2/000425.html + Changes also found in 2.2.7: * gpg: New option --no-symkey-cache to disable the passphrase cache @@ -36,6 +66,8 @@ Noteworthy changes in version 2.3.0 (unreleased) * agent,dirmngr: New sub-command "getenv" for "getinfo" to ease debugging. + See-also: gnupg-announce/2018q2/000424.html + Changes also found in 2.2.6: * gpg,gpgsm: New option --request-origin to pretend requests coming @@ -81,6 +113,8 @@ Noteworthy changes in version 2.3.0 (unreleased) * Allow the use of UNC directory names as homedir. [#3818] + See-also: gnupg-announce/2018q2/000421.html + Changes also found in 2.2.5: * gpg: Allow the use of the "cv25519" and "ed25519" short names in @@ -124,6 +158,8 @@ Noteworthy changes in version 2.3.0 (unreleased) with statically linked versions of the core GnuPG libraries. Also use --enable-wks-tools by default by Speedo builds for Unix. + See-also: gnupg-announce/2018q1/000420.html + Changes also found in 2.2.4: * gpg: Change default preferences to prefer SHA512. @@ -153,6 +189,8 @@ Noteworthy changes in version 2.3.0 (unreleased) * New configure option --enable-run-gnupg-user-socket to first try a socket directory which is not removed by systemd at session end. + See-also: gnupg-announce/2017q4/000419.html + Changes also found in 2.2.3: * gpgsm: Fix initial keybox creation on Windows. [#3507] @@ -172,7 +210,6 @@ Noteworthy changes in version 2.3.0 (unreleased) See-also: gnupg-announce/2017q4/000417.html - Changes also found in 2.2.2: * gpg: Avoid duplicate key imports by concurrently running gpg @@ -236,6 +273,8 @@ Noteworthy changes in version 2.3.0 (unreleased) certificates are configured. If build with GNUTLS, this was already the case. + See-also: gnupg-announce/2017q3/000415.html + Release dates of 2.2.x versions: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Version 2.2.1 (2017-09-19) @@ -245,6 +284,7 @@ Noteworthy changes in version 2.3.0 (unreleased) Version 2.2.5 (2018-02-22) Version 2.2.6 (2018-04-09) Version 2.2.7 (2018-05-02) + Version 2.2.8 (2018-06-08) Noteworthy changes in version 2.2.0 (2017-08-28) ----------------------------------------------------------------------- Summary of changes: NEWS | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 11:16:30 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 11:16:30 +0200 Subject: [git] gnupg-doc - branch, master, updated. 71724d3c3bafc1b8534ceb150d264db9ccf6f39a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 71724d3c3bafc1b8534ceb150d264db9ccf6f39a (commit) from 031285b8ea7debdb90c497b29a0e25894c6a76a5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 71724d3c3bafc1b8534ceb150d264db9ccf6f39a Author: Werner Koch Date: Mon Jun 11 11:08:28 2018 +0200 swdb: Release of Gnupg 1.4.23 diff --git a/web/swdb.mac b/web/swdb.mac index ece3aab..09a3730 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -37,15 +37,15 @@ # # GnuPG-1 # -#+macro: gnupg1_ver 1.4.22 -#+macro: gnupg1_date 2017-07-19 -#+macro: gnupg1_size 3658k -#+macro: gnupg1_sha1 4bad84fba712626cbbd5adf20988788028c5a5a6 -#+macro: gnupg1_sha2 9594a24bec63a21568424242e3f198b9d9828dea5ff0c335e47b06f835f930b4 -# -#+macro: gnupg1_w32cli_ver 1.4.22 -#+macro: gnupg1_w32cli_size 2372k -#+macro: gnupg1_w32cli_sha1 27b8069872d6d2b271222ffb9322dbd6197b0b89 +#+macro: gnupg1_ver 1.4.23 +#+macro: gnupg1_date 2018-06-11 +#+macro: gnupg1_size 3661k +#+macro: gnupg1_sha1 13747486ed5ff707f796f34f50f4c3085c3a6875 +#+macro: gnupg1_sha2 c9462f17e651b6507848c08c430c791287cd75491f8b5a8b50c6ed46b12678ba +# +#+macro: gnupg1_w32cli_ver 1.4.23 +#+macro: gnupg1_w32cli_size 2376k +#+macro: gnupg1_w32cli_sha1 d4c9962179d36a140be72c34f34e557b56c975b5 # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 12:14:11 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Mon, 11 Jun 2018 12:14:11 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-57-ge97e6c0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via e97e6c06e950cfad424e120f4f3752b594214c94 (commit) from c072675f3f2d734297a348c6de810148fb1424a2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e97e6c06e950cfad424e120f4f3752b594214c94 Author: Maximilian Krambach Date: Mon Jun 11 12:08:50 2018 +0200 js: Add key creation to Keyring -- * src/Keyring.js: Added method generateKey for new Keys Still TODO: Key length and some further testing. Automated testing does not work in this case, and gpgmejs will not be able to delete test keys again. * src/permittedOperations.js Added new method's definitions according to gpgme-json diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index 7158587..0d4e3c5 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -197,5 +197,63 @@ export class GPGME_Keyring { } } - // generateKey + /** + * Generates a new Key pair directly in gpg, and returns a GPGME_Key + * representing that Key. Please note that due to security concerns, secret + * Keys can not be _deleted_ from inside gpgmejs. + * + * @param {String} userId The user Id, e.g. "Foo Bar " + * @param {*} algo (optional) algorithm to be used. See + * {@link supportedKeyAlgos } below for supported values. + * @param {Number} keyLength (optional) TODO + * @param {Date} expires (optional) Expiration date. If not set, expiration + * will be set to 'never' + * + * @returns{Promise} + */ + generateKey(userId, algo = 'default', keyLength, expires){ + if ( + typeof(userId) !== 'string' || + supportedKeyAlgos.indexOf(algo) < 0 || + (expires && !(expires instanceof Date)) + // TODO keylength + // TODO check for completeness of algos + ){ + return Promise.reject(gpgme_error('PARAM_WRONG')); + } + let me = this; + return new Promise(function(resolve, reject){ + let msg = createMessage('createkey'); + msg.setParameter('userid', userId); + msg.setParameter('algo', algo); + if (expires){ + msg.setParameter('expires', + Math.floor(expires.valueOf()/1000)); + } + // TODO append keylength to algo + msg.post().then(function(response){ + me.getKeys(response.fingerprint, true).then( + // TODO make prepare_sync (second parameter) optional here. + function(result){ + resolve(result); + }, function(error){ + reject(error); + }); + }, function(error) { + reject(error); + }); + }); + } } + +/** + * A list of algorithms supported for key generation. + */ +const supportedKeyAlgos = [ + 'default', + 'rsa', + 'dsa', + 'elg', + 'ed25519', + 'cv25519' +]; \ No newline at end of file diff --git a/lang/js/src/permittedOperations.js b/lang/js/src/permittedOperations.js index 6ac33af..91612ad 100644 --- a/lang/js/src/permittedOperations.js +++ b/lang/js/src/permittedOperations.js @@ -311,12 +311,31 @@ export const permittedOperations = { 'info': 'object' } } - } + }, + createkey: { + pinentry: true, + required: { + userid: { + allowed: ['string'] + } + }, + optional: { + algo: { + allowed: ['string'] + }, + expires: { + allowed: ['number'], + } + }, + answer: { + type: [''], + data: {'fingerprint': 'string'} + } + } /** * TBD handling of secrets * TBD key modification? - * TBD: key generation */ }; ----------------------------------------------------------------------- Summary of changes: lang/js/src/Keyring.js | 60 +++++++++++++++++++++++++++++++++++++- lang/js/src/permittedOperations.js | 23 +++++++++++++-- 2 files changed, 80 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 13:31:43 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 13:31:43 +0200 Subject: [git] gnupg-doc - branch, master, updated. 51549ca5dbdc01c920fcbd5956f17de439e91d86 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 51549ca5dbdc01c920fcbd5956f17de439e91d86 (commit) from 71724d3c3bafc1b8534ceb150d264db9ccf6f39a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 51549ca5dbdc01c920fcbd5956f17de439e91d86 Author: Werner Koch Date: Mon Jun 11 13:23:54 2018 +0200 web: Announce 1.4.23 diff --git a/web/index.org b/web/index.org index acb0c10..53df6f1 100644 --- a/web/index.org +++ b/web/index.org @@ -65,6 +65,12 @@ The latest release news:\\ # GnuPG's latest news are available as [[http://feedvalidator.org/check.cgi?url%3Dhttps://www.gnupg.org/news.en.rss][RSS 2.0 compliant]] feed. Just # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** GnuPG 1.4.23 released (2018-06-11) :important: + +Although GnuPG 1.4 is of very limited use today we did a maintenance +release to address the critical security bug {{{CVE(2017-7526)}}}. +See the [[../../download/index.org][download]] section on how to get this version. + ** GnuPG 2.2.8 released (2018-06-08) :important: This version fixes a critical security bug. Either this version or a ----------------------------------------------------------------------- Summary of changes: web/index.org | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 15:12:37 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Mon, 11 Jun 2018 15:12:37 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-58-ge154554 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via e154554e9a48a08219649a58be0b641c561e1748 (commit) from e97e6c06e950cfad424e120f4f3752b594214c94 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e154554e9a48a08219649a58be0b641c561e1748 Author: Maximilian Krambach Date: Mon Jun 11 15:10:43 2018 +0200 js: removed config -- * There is no use for a configuration at the moment, and it seems improbable that this use will arise. diff --git a/lang/js/BrowserTestExtension/tests/inputvalues.js b/lang/js/BrowserTestExtension/tests/inputvalues.js index 024aad2..1c70190 100644 --- a/lang/js/BrowserTestExtension/tests/inputvalues.js +++ b/lang/js/BrowserTestExtension/tests/inputvalues.js @@ -53,14 +53,6 @@ const inputvalues = {// eslint-disable-line no-unused-vars // bogus fingerprint) fingerprint: 'CDC3A2B2860625CCBFC5AAAAAC6D1B604967FC4A' } - }, - init: { - // some parameters - invalid_startups: [ - {all_passwords: true}, - 'openpgpmode', - {api_style:'frankenstein'} - ] } }; diff --git a/lang/js/BrowserTestExtension/tests/startup.js b/lang/js/BrowserTestExtension/tests/startup.js index d434b6d..dae9402 100644 --- a/lang/js/BrowserTestExtension/tests/startup.js +++ b/lang/js/BrowserTestExtension/tests/startup.js @@ -22,7 +22,6 @@ */ /* global describe, it, expect, Gpgmejs */ -/* global inputvalues */ describe('GPGME context', function(){ it('Starting a GpgME instance', function(done){ @@ -36,19 +35,3 @@ describe('GPGME context', function(){ }); }); }); - -describe('GPGME does not start with invalid parameters', function(){ - for (let i=0; i < inputvalues.init.invalid_startups.length; i++){ - it('Parameter '+ i, function(done){ - let prm = Gpgmejs.init(inputvalues.init.invalid_startups[i]); - prm.then(function(context){ - expect(context).to.be.undefined; - done(); - }, function(error){ - expect(error).to.be.an.instanceof(Error); - expect(error.code).to.equal('PARAM_WRONG'); - done(); - }); - }); - } -}); \ No newline at end of file diff --git a/lang/js/src/Config.js b/lang/js/src/Config.js deleted file mode 100644 index 8a3ef49..0000000 --- a/lang/js/src/Config.js +++ /dev/null @@ -1,34 +0,0 @@ -/* gpgme.js - Javascript integration for gpgme - * Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik - * - * This file is part of GPGME. - * - * GPGME is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * GPGME is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . - * SPDX-License-Identifier: LGPL-2.1+ - * - * Author(s): - * Maximilian Krambach - */ - -export const availableConf = { - null_expire_is_never: [true, false], - // cachedKeys: Some Key info will not be queried on each invocation, - // manual refresh by Key.refresh() - cachedKeys: [true, false] -}; - -export const defaultConf = { - null_expire_is_never: false, - cachedKeys: false -}; \ No newline at end of file diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index 09bca7f..7fa7643 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -30,10 +30,8 @@ import { GPGME_Keyring } from './Keyring'; export class GpgME { /** * initializes GpgME by opening a nativeMessaging port - * TODO: add configuration */ - constructor(config){ //TODO config not parsed - this._config = config; + constructor(){ } set Keyring(keyring){ diff --git a/lang/js/src/index.js b/lang/js/src/index.js index 1b13ec4..6db2873 100644 --- a/lang/js/src/index.js +++ b/lang/js/src/index.js @@ -25,24 +25,20 @@ import { GpgME } from './gpgmejs'; import { gpgme_error } from './Errors'; import { Connection } from './Connection'; -import { defaultConf, availableConf } from './Config'; /** - * Initializes a nativeMessaging Connection and returns a GPGMEjs object - * @param {Object} config Configuration. See Config.js for available parameters. - * Still TODO + * Tests nativeMessaging once and returns a GpgME object if successful. + * @returns {GpgME | Error} + * + * @async */ -function init(config){ - let _conf = parseconfiguration(config); - if (_conf instanceof Error){ - return Promise.reject(_conf); - } +function init(){ return new Promise(function(resolve, reject){ let connection = new Connection; connection.checkConnection(false).then( function(result){ if (result === true) { - resolve(new GpgME(_conf)); + resolve(new GpgME()); } else { reject(gpgme_error('CONN_NO_CONNECT')); } @@ -52,36 +48,6 @@ function init(config){ }); } -function parseconfiguration(rawconfig = {}){ - if ( typeof(rawconfig) !== 'object'){ - return gpgme_error('PARAM_WRONG'); - } - let result_config = {}; - let conf_keys = Object.keys(rawconfig); - - for (let i=0; i < conf_keys.length; i++){ - - if (availableConf.hasOwnProperty(conf_keys[i])){ - let value = rawconfig[conf_keys[i]]; - if (availableConf[conf_keys[i]].indexOf(value) < 0){ - return gpgme_error('PARAM_WRONG'); - } else { - result_config[conf_keys[i]] = value; - } - } - else { - return gpgme_error('PARAM_WRONG'); - } - } - let default_keys = Object.keys(defaultConf); - for (let j=0; j < default_keys.length; j++){ - if (!result_config.hasOwnProperty(default_keys[j])){ - result_config[default_keys[j]] = defaultConf[default_keys[j]]; - } - } - return result_config; -} - export default { init: init }; \ No newline at end of file ----------------------------------------------------------------------- Summary of changes: lang/js/BrowserTestExtension/tests/inputvalues.js | 8 ---- lang/js/BrowserTestExtension/tests/startup.js | 17 --------- lang/js/src/Config.js | 34 ----------------- lang/js/src/gpgmejs.js | 4 +- lang/js/src/index.js | 46 +++-------------------- 5 files changed, 7 insertions(+), 102 deletions(-) delete mode 100644 lang/js/src/Config.js hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 18:24:12 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 11 Jun 2018 18:24:12 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-18-gc9a1737 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via c9a173782e33b9709aae8f57c52db32538e1f852 (commit) via a1a0f0aa53b0be2da786c8cfbdf10d03d1d4b1bf (commit) via 49cc27fd092d8a7cb83a78c715a52764a1605652 (commit) via 5a2f1ac5880d0ce481026034c02e851fab67d48a (commit) from 75e02a5985d3a57668ce7ea8b0057ca919850b1a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c9a173782e33b9709aae8f57c52db32538e1f852 Author: Andre Heinecke Date: Mon Jun 11 18:19:48 2018 +0200 Clean reply / forwards of unsigned S/MIME Mails * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Improve reply / forward handling and check for HTML Blocked Mails to clean them. * src/windowmessages.cpp, src/windowmessages.h (do_in_ui_thread_async): Extend to take delay as opt. param. (CLEAR_REPLY_FORWARD): New message. (gpgol_window_proc): Handle it. -- This is ugly ugly ugly. As we don't have a reliable way to detect when a reply / forward is filled with data we just wait a second before wiping the reply if necessary. The change in the write event to not invalidate the last mail also poses a regression risk. GnuPG-Bug-Id: T3986 diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index e4dd961..9effeb1 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -135,6 +135,8 @@ EVENT_SINK_INVOKE(MailItemEvents) return S_OK; } } + + bool is_reply = false; switch(dispid) { case Open: @@ -592,7 +594,10 @@ EVENT_SINK_INVOKE(MailItemEvents) " Pass but schedule revert.", SRCNAME, __func__); - Mail::invalidate_last_mail (); + /* This might be a forward. So don't invalidate yet. */ + + // Mail::invalidate_last_mail (); + do_in_ui_thread_async (REVERT_MAIL, m_mail); return S_OK; } @@ -719,10 +724,16 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__); return S_OK; } + /* Fallthrough */ + case ReplyAll: + case Reply: + { + is_reply = true; + } case Forward: { - log_oom_extra ("%s:%s: Forward: %p", - SRCNAME, __func__, m_mail); + log_oom_extra ("%s:%s: %s : %p", + SRCNAME, __func__, is_reply ? "reply" : "forward", m_mail); if (!m_mail->is_crypto_mail ()) { /* Non crypto mails do not interest us.*/ @@ -746,18 +757,52 @@ EVENT_SINK_INVOKE(MailItemEvents) if (!lastSize && !lastEntryStr.size ()) { - log_debug ("%s:%s: Forward in the same loop as empty load." - " Marking %p (item %p) as forwarded.", - SRCNAME, __func__, last_mail, last_mail->item ()); + if (!is_reply) + { + log_debug ("%s:%s: Forward in the same loop as empty " + "load Marking %p (item %p) as forwarded.", + SRCNAME, __func__, last_mail, + last_mail->item ()); - last_mail->set_is_forwarded_crypto_mail (true); + last_mail->set_is_forwarded_crypto_mail (true); + } + else + { + log_debug ("%s:%s: Reply in the same loop as empty " + "load Marking %p (item %p) as reply.", + SRCNAME, __func__, last_mail, + last_mail->item ()); + } + if (m_mail->is_block_html()) + { + std::string caption = _("GpgOL") + std::string (": "); + caption += is_reply ? _("Dangerous reply") : + _("Dangerous forward"); + std::string buf = _("Unsigned S/MIME mails are not integrity " + "protected."); + buf += "\n\n"; + + if (is_reply) + { + buf += _("For security reasons no decrypted contents" + " are included in this reply."); + } + else + { + buf += _("For security reasons no decrypted contents" + " are included in the forwarded mail."); + } + + gpgol_message_box (get_active_hwnd (), buf.c_str(), + _("GpgOL"), MB_OK); + + do_in_ui_thread_async (CLEAR_REPLY_FORWARD, last_mail, 1000); + } } + // We can now invalidate the last mail + Mail::invalidate_last_mail (); } - } - /* Fallthrough */ - case Reply: - case ReplyAll: - { + log_oom_extra ("%s:%s: Reply Forward ReplyAll: %p", SRCNAME, __func__, m_mail); if (!opt.reply_crypt) diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 73292d1..36c0631 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -182,6 +182,19 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) xfree (ctx->data); break; } + case (CLEAR_REPLY_FORWARD): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: Clear reply forward for mail which is gone.", + SRCNAME, __func__); + break; + } + mail->wipe (true); + mail->remove_all_attachments (); + break; + } default: log_debug ("%s:%s: Unknown msg %x", SRCNAME, __func__, ctx->wmsg_type); @@ -242,7 +255,7 @@ send_msg_to_ui_thread (wm_ctx_t *ctx) int do_in_ui_thread (gpgol_wmsg_type type, void *data) { - wm_ctx_t ctx = {NULL, UNKNOWN, 0}; + wm_ctx_t ctx = {NULL, UNKNOWN, 0, 0}; ctx.wmsg_type = type; ctx.data = data; if (send_msg_to_ui_thread (&ctx)) @@ -256,19 +269,25 @@ static DWORD WINAPI do_async (LPVOID arg) { wm_ctx_t *ctx = (wm_ctx_t*) arg; - log_debug ("%s:%s: Do async with type %i", - SRCNAME, __func__, ctx ? ctx->wmsg_type : -1); + log_debug ("%s:%s: Do async with type %i after %i ms", + SRCNAME, __func__, ctx ? ctx->wmsg_type : -1, + ctx->delay); + if (ctx->delay) + { + Sleep (ctx->delay); + } send_msg_to_ui_thread (ctx); xfree (ctx); return 0; } void -do_in_ui_thread_async (gpgol_wmsg_type type, void *data) +do_in_ui_thread_async (gpgol_wmsg_type type, void *data, int delay) { wm_ctx_t *ctx = (wm_ctx_t *) calloc (1, sizeof (wm_ctx_t)); ctx->wmsg_type = type; ctx->data = data; + ctx->delay = delay; CloseHandle (CreateThread (NULL, 0, do_async, (LPVOID) ctx, 0, NULL)); } diff --git a/src/windowmessages.h b/src/windowmessages.h index 56d9db8..dcc372c 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -52,6 +52,7 @@ typedef enum _gpgol_wmsg_type BRING_TO_FRONT, /* Bring the active Outlook window to the front. */ INVALIDATE_LAST_MAIL, REVERT_MAIL, + CLEAR_REPLY_FORWARD, } gpgol_wmsg_type; typedef struct @@ -59,6 +60,7 @@ typedef struct void *data; /* Pointer to arbitrary data depending on msg type */ gpgol_wmsg_type wmsg_type; /* Type of the msg. */ int err; /* Set to true on error */ + int delay; } wm_ctx_t; /** Create and register the responder window. @@ -77,9 +79,12 @@ int do_in_ui_thread (gpgol_wmsg_type type, void *data); /** Send a message to the UI thread but returns - immediately without waiting for the execution. */ + immediately without waiting for the execution. + + The delay is used in the detached thread to delay + the sending of the actual message. */ void -do_in_ui_thread_async (gpgol_wmsg_type type, void *data); +do_in_ui_thread_async (gpgol_wmsg_type type, void *data, int delay = 0); /** Create our filter before outlook Window Messages. */ HHOOK commit a1a0f0aa53b0be2da786c8cfbdf10d03d1d4b1bf Author: Andre Heinecke Date: Mon Jun 11 18:17:03 2018 +0200 Extend mail class for better reply/forward handling * src/mail.cpp, src/mail.h (Mail::set_is_reply_crypto_mail), (Maill::is_reply_crypto_mail, m_is_reply_crypto_mail): New flag for replies. (Mail::remove_all_attachements): New helper. (Mail::is_block_html): Expose the flag. -- This helps with: GnuPG-Bug-Id: T3986 diff --git a/src/mail.cpp b/src/mail.cpp index e5c2b3a..47d7367 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -92,6 +92,7 @@ Mail::Mail (LPDISPATCH mailitem) : m_window(nullptr), m_async_crypt_disabled(false), m_is_forwarded_crypto_mail(false), + m_is_reply_crypto_mail(false), m_is_send_again(false), m_disable_att_remove_warning(false) { @@ -2976,6 +2977,51 @@ Mail::locate_all_crypto_recipients() } int +Mail::remove_all_attachments () +{ + int ret = 0; + LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments"); + if (!attachments) + { + TRACEPOINT; + return 0; + } + int count = get_oom_int (attachments, "Count"); + LPDISPATCH to_delete[count]; + + /* Populate the array so that we don't get in an index mess */ + for (int i = 1; i <= count; i++) + { + auto item_str = std::string("Item(") + std::to_string (i) + ")"; + to_delete[i-1] = get_oom_object (attachments, item_str.c_str()); + } + gpgol_release (attachments); + + /* Now delete all attachments */ + for (int i = 0; i < count; i++) + { + LPDISPATCH attachment = to_delete[i]; + + if (!attachment) + { + log_error ("%s:%s: No such attachment %i", + SRCNAME, __func__, i); + ret = -1; + } + + /* Delete the attachments that are marked to delete */ + if (invoke_oom_method (attachment, "Delete", NULL)) + { + log_error ("%s:%s: Deleting attachment %i", + SRCNAME, __func__, i); + ret = -1; + } + gpgol_release (attachment); + } + return ret; +} + +int Mail::remove_our_attachments () { LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments"); diff --git a/src/mail.h b/src/mail.h index 20e737a..7f4ed7b 100644 --- a/src/mail.h +++ b/src/mail.h @@ -455,11 +455,20 @@ public: void set_is_forwarded_crypto_mail (bool value) { m_is_forwarded_crypto_mail = value; } bool is_forwarded_crypto_mail () { return m_is_forwarded_crypto_mail; } + /** Set if this is a reply of a crypto mail. */ + void set_is_reply_crypto_mail (bool value) { m_is_reply_crypto_mail = value; } + bool is_reply_crypto_mail () { return m_is_reply_crypto_mail; } + /** Remove the hidden GpgOL attachments. This is needed when forwarding without encryption so that our attachments are not included in the forward. Returns 0 on success. Works in OOM. */ int remove_our_attachments (); + /** Remove all attachments. Including our own. This is needed for + forwarding of unsigned S/MIME mails (Efail). + Returns 0 on success. Works in OOM. */ + int remove_all_attachments (); + /** Check both OOM and MAPI if the body is either empty or encrypted. Won't abort on OOM or MAPI errors, so it can be used in both states. But will return false if a body @@ -490,6 +499,7 @@ public: /* Block loading HTML content */ void set_block_html (bool value); + bool is_block_html () const { return m_block_html; } /* Remove automatic loading of HTML references setting. */ void set_block_status (); @@ -534,6 +544,7 @@ private: bool m_async_crypt_disabled; std::string m_mime_data; bool m_is_forwarded_crypto_mail; /* Is this a forward of a crypto mail */ + bool m_is_reply_crypto_mail; /* Is this a reply to a crypto mail */ bool m_is_send_again; /* Is this a send again of a crypto mail */ bool m_disable_att_remove_warning; /* Should not warn about attachment removal. */ bool m_block_html; /* Force blocking of html content. e.g for unsigned S/MIME mails. */ commit 49cc27fd092d8a7cb83a78c715a52764a1605652 Author: Andre Heinecke Date: Mon Jun 11 18:15:14 2018 +0200 Improve unsigned S/MIME HTML handling * src/mail.cpp (update_body): Improve handling and messages. -- GnuPG-Bug-Id: T3986 diff --git a/src/mail.cpp b/src/mail.cpp index b2d0fbe..e5c2b3a 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1082,35 +1082,63 @@ Mail::update_body() // No need to carry body anymore m_orig_body = std::string(); auto html = m_parser->get_html_body (); + auto body = m_parser->get_body (); /** Outlook does not show newlines if \r\r\n is a newline. We replace these as apparently some other buggy MUA sends this. */ find_and_replace (html, "\r\r\n", "\r\n"); - if (opt.prefer_html && !html.empty() && !m_block_html) + if (opt.prefer_html && !html.empty()) { - const auto charset = m_parser->get_html_charset(); - - int codepage = 0; - if (charset.empty()) + if (!m_block_html) { - codepage = get_oom_int (m_mailitem, "InternetCodepage"); - log_debug ("%s:%s: Did not find html charset." - " Using internet Codepage %i.", - SRCNAME, __func__, codepage); - } + const auto charset = m_parser->get_html_charset(); - char *converted = ansi_charset_to_utf8 (charset.c_str(), html.c_str(), - html.size(), codepage); - int ret = put_oom_string (m_mailitem, "HTMLBody", converted ? converted : ""); - xfree (converted); - if (ret) + int codepage = 0; + if (charset.empty()) + { + codepage = get_oom_int (m_mailitem, "InternetCodepage"); + log_debug ("%s:%s: Did not find html charset." + " Using internet Codepage %i.", + SRCNAME, __func__, codepage); + } + + char *converted = ansi_charset_to_utf8 (charset.c_str(), html.c_str(), + html.size(), codepage); + int ret = put_oom_string (m_mailitem, "HTMLBody", converted ? + converted : ""); + xfree (converted); + if (ret) + { + log_error ("%s:%s: Failed to modify html body of item.", + SRCNAME, __func__); + } + + return; + } + else if (!body.empty()) { - log_error ("%s:%s: Failed to modify html body of item.", - SRCNAME, __func__); + /* We had a multipart/alternative mail but html should be + blocked. So we prefer the text/plain part and warn + once about this so that we hopefully don't get too + many bugreports about this. */ + if (!opt.smime_html_warn_shown) + { + std::string caption = _("GpgOL") + std::string (": ") + + std::string (_("HTML display disabled.")); + std::string buf = _("HTML content in unsigned S/MIME mails " + "is insecure."); + buf += "\n"; + buf += _("GpgOL will only show such mails as text."); + + buf += "\n\n"; + buf += _("This message is shown only once."); + + gpgol_message_box (get_window(), buf.c_str(), caption.c_str(), + MB_OK); + opt.smime_html_warn_shown = true; + write_options (); + } } - - return; } - auto body = m_parser->get_body (); if (body.empty () && m_block_html && !html.empty()) { @@ -1163,13 +1191,19 @@ Mail::update_body() } #endif body = html; - std::string buf = _("HTML display disabled."); + std::string caption = _("GpgOL") + std::string (": ") + + std::string (_("HTML display disabled.")); + std::string buf = _("HTML content in unsigned S/MIME mails " + "is insecure."); + buf += "\n"; + buf += _("GpgOL will only show such mails as text."); + buf += "\n\n"; - buf += _("For security reasons HTML content in unsigned, encrypted\n" - "S/MIME mails cannot be displayed.\n\n" - "Please ask the sender to sign the message or to send it as plain text."); + buf += _("Please ask the sender to sign the message or\n" + "to send it with a plain text alternative."); - gpgol_message_box (get_window(), buf.c_str() , _("GpgOL"), MB_OK); + gpgol_message_box (get_window(), buf.c_str(), caption.c_str(), + MB_OK); } find_and_replace (body, "\r\r\n", "\r\n"); commit 5a2f1ac5880d0ce481026034c02e851fab67d48a Author: Andre Heinecke Date: Mon Jun 11 18:12:17 2018 +0200 Cleanup unused options and add a warning shown opt * src/common_indep.h: Update option struct. * src/main.c (init_options): Removed. (write_options, read_options): Update accordingly. * src/mapihelp.cpp (mapi_get_gpgol_body_attachment): Remove obsolete handling to show body as attachment. -- This removes obsolete OL < 2010 Options and adds a new smime_html_warn_shown flag. diff --git a/src/common_indep.h b/src/common_indep.h index 7332dbd..f1805a9 100644 --- a/src/common_indep.h +++ b/src/common_indep.h @@ -186,20 +186,14 @@ struct larger than 1 increases the debug log verbosity. */ int enable_smime; /* Enable S/MIME support. */ - int passwd_ttl; /* Time in seconds the passphrase is stored. */ - protocol_t default_protocol;/* The default protocol. */ int encrypt_default; /* Encrypt by default. */ int sign_default; /* Sign by default. */ - int enc_format; /* Encryption format for attachments. */ char *default_key; /* The key we want to always encrypt to. */ - int enable_default_key; /* Enable the use of DEFAULT_KEY. */ - int preview_decrypt; /* Decrypt in preview window. */ int prefer_html; /* Prefer html in html/text alternatives. */ - int body_as_attachment; /* Present encrypted message as attachment. */ int inline_pgp; /* Only for Addin. Use Inline PGP by default. */ int autoresolve; /* Autresolve keys with --locate-keys. */ int reply_crypt; /* Only for Addin. Encrypt / Sign based on cryptostatus. */ - int deprecation_shown; /* Flag to save if deprecation warning was shown */ + int smime_html_warn_shown; /* Flag to save if unsigned smime warning was shown */ /* The compatibility flags. */ struct diff --git a/src/main.c b/src/main.c index 186620e..02c53df 100644 --- a/src/main.c +++ b/src/main.c @@ -39,16 +39,6 @@ static void drop_locale_dir (char *locale_dir); int g_ol_version_major; - -/* Initialization of gloabl options. These are merely the defaults - and will get updated later from the Registry. That is done later - at the time Outlook calls its entry point the first time. */ -static void -init_options (void) -{ - opt.enc_format = GPG_FMT_CLASSIC; -} - /* For certain operations we need to acquire a log on the logging functions. This lock is controlled by this Mutex. */ HANDLE log_mutex; @@ -169,7 +159,6 @@ DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) if (initialize_main ()) return FALSE; i18n_init (); - init_options (); } else if (reason == DLL_PROCESS_DETACH) { @@ -306,17 +295,6 @@ read_options (void) opt.enable_smime = !val ? 0 : atoi (val); xfree (val); val = NULL; -/* load_extension_value ("defaultProtocol", &val); */ -/* switch ((!val || *val == '0')? 0 : atol (val)) */ -/* { */ -/* case 1: opt.default_protocol = PROTOCOL_OPENPGP; break; */ -/* case 2: opt.default_protocol = PROTOCOL_SMIME; break; */ -/* case 0: */ -/* default: opt.default_protocol = PROTOCOL_UNKNOWN /\*(auto*)*\/; break; */ -/* } */ -/* xfree (val); val = NULL; */ - opt.default_protocol = PROTOCOL_UNKNOWN; /* (auto)*/ - load_extension_value ("encryptDefault", &val); opt.encrypt_default = val == NULL || *val != '1'? 0 : 1; xfree (val); val = NULL; @@ -325,18 +303,6 @@ read_options (void) opt.sign_default = val == NULL || *val != '1'? 0 : 1; xfree (val); val = NULL; - load_extension_value ("previewDecrypt", &val); - opt.preview_decrypt = val == NULL || *val != '1'? 0 : 1; - xfree (val); val = NULL; - - load_extension_value ("enableDefaultKey", &val); - opt.enable_default_key = val == NULL || *val != '1' ? 0 : 1; - xfree (val); val = NULL; - - load_extension_value ("encodingFormat", &val); - opt.enc_format = val == NULL? GPG_FMT_CLASSIC : atol (val); - xfree (val); val = NULL; - load_extension_value ("defaultKey", &val); set_default_key (val); xfree (val); val = NULL; @@ -353,10 +319,6 @@ read_options (void) opt.announce_number = val? atol (val) : 0; xfree (val); val = NULL; - load_extension_value ("bodyAsAttachment", &val); - opt.body_as_attachment = val == NULL || *val != '1'? 0 : 1; - xfree (val); val = NULL; - load_extension_value ("inlinePGP", &val); opt.inline_pgp = val == NULL || *val != '1'? 0 : 1; xfree (val); val = NULL; @@ -366,8 +328,8 @@ read_options (void) load_extension_value ("replyCrypt", &val); opt.reply_crypt = val == NULL ? 1 : *val != '1' ? 0 : 1; xfree (val); val = NULL; - load_extension_value ("deprecationShown", &val); - opt.deprecation_shown = val == NULL || *val != '1'? 0 : 1; + load_extension_value ("smimeHtmlWarnShown", &val); + opt.smime_html_warn_shown = val == NULL || *val != '1'? 0 : 1; xfree (val); val = NULL; /* Note, that on purpose these flags are only Registry changeable. The format of the entry is a string of of "0" and "1" digits; see @@ -426,22 +388,16 @@ write_options (void) char *s_val; } table[] = { {"enableSmime", 0, opt.enable_smime, NULL}, -/* {"defaultProtocol", 3, opt.default_protocol}, */ {"encryptDefault", 0, opt.encrypt_default, NULL}, {"signDefault", 0, opt.sign_default, NULL}, - {"previewDecrypt", 0, opt.preview_decrypt, NULL}, - {"encodingFormat", 1, opt.enc_format, NULL}, {"logFile", 2, 0, (char*) get_log_file ()}, - {"defaultKey", 2, 0, opt.default_key}, - {"enableDefaultKey", 0, opt.enable_default_key, NULL}, {"gitCommit", 4, opt.git_commit, NULL}, {"formsRevision", 1, opt.forms_revision, NULL}, {"announceNumber", 1, opt.announce_number, NULL}, - {"bodyAsAttachment", 0, opt.body_as_attachment, NULL}, {"inlinePGP", 0, opt.inline_pgp, NULL}, {"autoresolve", 0, opt.autoresolve, NULL}, {"replyCrypt", 0, opt.reply_crypt, NULL}, - {"deprecationShown", 0, opt.deprecation_shown, NULL}, + {"smimeHtmlWarnShown", 0, opt.smime_html_warn_shown, NULL}, {NULL, 0, 0, NULL} }; char buf[32]; diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index a4774cb..6d2c04f 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -3330,17 +3330,6 @@ mapi_get_gpgol_body_attachment (LPMESSAGE message, found = 1; if (!r_body) ; /* Body content has not been requested. */ - else if (opt.body_as_attachment && !mapi_test_attach_hidden (att)) - { - /* The body is to be shown as an attachment. */ - body = native_to_utf8 - (bodytype == 2 - ? ("[Open the attachment \"gpgol000.htm\"" - " to view the message.]") - : ("[Open the attachment \"gpgol000.txt\"" - " to view the message.]")); - found = 1; - } else { char *charset; ----------------------------------------------------------------------- Summary of changes: src/common_indep.h | 8 +-- src/mail.cpp | 130 ++++++++++++++++++++++++++++++++++++++---------- src/mail.h | 11 ++++ src/mailitem-events.cpp | 69 ++++++++++++++++++++----- src/main.c | 50 ++----------------- src/mapihelp.cpp | 11 ---- src/windowmessages.cpp | 27 ++++++++-- src/windowmessages.h | 9 +++- 8 files changed, 207 insertions(+), 108 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 11 18:49:58 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Jun 2018 18:49:58 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1.8-BRANCH, updated. libgcrypt-1.8.2-15-g846f8fe Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1.8-BRANCH has been updated via 846f8fe8b3be6d235592db184361df1bc2b07a8a (commit) via 54620a27f4503e703e219e6e11c4be14ce4e3d35 (commit) from 1a0289daa408773e1a6cefb2562288245f49651c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 846f8fe8b3be6d235592db184361df1bc2b07a8a Author: Werner Koch Date: Tue Jun 5 14:33:01 2018 +0200 ecc: Improve gcry_mpi_ec_curve_point * mpi/ec.c (_gcry_mpi_ec_curve_point): Check range of coordinates. * tests/t-mpi-point.c (point_on_curve): New. -- Due to the conversion to affine coordinates we didn't detected points with values >= P. The solution here might not be the best according to the NIST standard (it is done there at an earlier opportunity) but it reliably detects points we do not expect to receive. The new test vectors have been compared against gnutls/nettle. Reported-by: Stephan M?ller Signed-off-by: Werner Koch (cherry picked from commit 7b6c2afd699e889f5f054cc3d202a61bd0ee1dcf) diff --git a/mpi/ec.c b/mpi/ec.c index 4c16603..89077cd 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1518,6 +1518,15 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) y = mpi_new (0); w = mpi_new (0); + /* Check that the point is in range. This needs to be done here and + * not after conversion to affine coordinates. */ + if (mpi_cmpabs (point->x, ctx->p) >= 0) + goto leave; + if (mpi_cmpabs (point->y, ctx->p) >= 0) + goto leave; + if (mpi_cmpabs (point->z, ctx->p) >= 0) + goto leave; + switch (ctx->model) { case MPI_EC_WEIERSTRASS: diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 1eaa08a..f2378bf 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -1045,6 +1045,271 @@ twistededwards_math (void) } +/* Check the point on curve function. */ +static void +point_on_curve (void) +{ + static struct { + const char *curve; + int oncurve; /* Point below is on the curve. */ + const char *qx; + const char *qy; + } t[] = { + { + "NIST P-256", 0, + "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974", + "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3" + }, { + "NIST P-256", 0, + "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651", + "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D" + }, { + "NIST P-256", 0, + "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291", + "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023" + }, { + "NIST P-256", 1, + "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B", + "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63" + }, { + "NIST P-256", 0, + "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53", + "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600" + }, { + "NIST P-256", 1, + "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36", + "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E" + }, { + "NIST P-256", 0, + "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990", + "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E" + }, { + "NIST P-256", 1, + "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE", + "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D" + }, { + "NIST P-256", 1, + "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945", + "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63" + }, { + "NIST P-256", 0, + "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84", + "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F" + }, { + "NIST P-256", 0, + "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC", + "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902" + }, { + "NIST P-256", 0, + "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C", + "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0" + } , { + "NIST P-384", 0, + "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00" + "83EC46A8F2FF3203C5C7F8C7E722A5EF", + "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922" + "96470753DCF46173C9AA4A8A4C2FBE51" + }, { + "NIST P-384", 0, + "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752" + "02CE06CCBE705EA8A38AA2894D4BEEE6", + "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F" + "8E0875F4C4BB1E3D0F8535C7A52306FB82" + }, { + "NIST P-384", 1, + "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23" + "D719ED4116E2CC907AEB92CF22331A60", + "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E" + "9FC63F61EF19DE9B3CEA98D163ABF254" + }, { + "NIST P-384", 0, + "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24" + "EC2F0CA62FF1F90B6515DE356EC2A404", + "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692" + "72F4D3A87E88529754E109BB9B61B03B" + }, { + "NIST P-384", 0, + "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2" + "9A440AD51C94CF5BC28817C8C6E2D302", + "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1" + "8306976291F3ADC0B5ABA42DED376EA9A5" + }, { + "NIST P-384", 0, + "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03" + "B958BF28B022E54E320672C4BAD4EEC0", + "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA" + "9E558E9F58ED1D324C9DCBCB4E8F2A5970" + }, { + "NIST P-384", 0, + "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293" + "18BCB9FC60499D009F949298F3F9F47B", + "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86" + "CFE9C552E2E720F5DA5806503D3784CD" + }, { + "NIST P-384", 0, + "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20" + "823CA8F84D2BBF4EA687885437DE7839", + "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1" + "69F3656C322DE45C4A70DC6DB9A661E599" + }, { + "NIST P-384", 1, + "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3" + "89B92C9A55573A596123415FBFA26991", + "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B" + "F3B04F46DBFFE08151E0F0950CC70081" + }, { + "NIST P-384", 0, + "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB" + "4C0F876575DDEC1BDB3F3F04061C9AE4", + "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352" + "D7BBEEFB803F6CC8FC7895E47F348D33" + }, { + "NIST P-384", 1, + "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36" + "F1D8325E45734D5A0FDD103F4DF6F83E", + "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B" + "F26E8D87EC175577E782AD51A6A12C02" + }, { + "NIST P-384", 1, + "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C" + "187BECA23369DFD6C15CC0DA0629958F", + "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB" + "73DE6AA96140B5C457B7486E06D318CE" + }, { + "NIST P-521", 0, + "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024" + "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70", + "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90" + "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0" + }, { + "NIST P-521", 0, + "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437" + "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3", + "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D" + "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48" + }, { + "NIST P-521", 1, + "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4" + "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8", + "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE" + "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97" + }, { + "NIST P-521", 0, + "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E" + "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D", + "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5" + "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF" + }, { + "NIST P-521", 0, + "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489" + "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117", + "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E" + "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD" + }, { + "NIST P-521", 1, + "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55" + "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56", + "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B" + "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004" + }, { + "NIST P-521", 0, + "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A" + "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023", + "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C" + "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291" + }, { + "NIST P-521", 0, + "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86" + "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE", + "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125" + "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4" + }, { + "NIST P-521", 0, + "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1" + "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03", + "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF" + "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89" + }, { + "NIST P-521", 0, + "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9" + "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93", + "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B" + "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B" + }, { + "NIST P-521", 1, + "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056" + "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C", + "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901" + "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080" + }, { + "NIST P-521", 1, + "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5" + "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1", + "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635" + "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9" + } + }; + gpg_error_t err; + int tidx; + const char *lastcurve = NULL; + gcry_ctx_t ctx = NULL; + gcry_mpi_t qx = NULL; + gcry_mpi_t qy = NULL; + gcry_mpi_point_t Q; + int oncurve; + + wherestr = "point_on_curve"; + for (tidx=0; tidx < DIM (t); tidx++) + { + if (!t[tidx].curve) + { + if (!lastcurve || !ctx) + die ("invalid test vectors at idx %d\n", tidx); + } + else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve)) + { + lastcurve = t[tidx].curve; + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, NULL, lastcurve); + if (err) + die ("error creating context for curve %s at idx %d: %s\n", + lastcurve, tidx, gpg_strerror (err)); + + info ("checking points on curve %s\n", lastcurve); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + qx = hex2mpi (t[tidx].qx); + qy = hex2mpi (t[tidx].qy); + + Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE); + if (!Q) + die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx); + + oncurve = gcry_mpi_ec_curve_point (Q, ctx); + + if (t[tidx].oncurve && !oncurve) + { + fail ("point expected on curve but not identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + else if (!t[tidx].oncurve && oncurve) + { + fail ("point not expected on curve but identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + gcry_mpi_point_release (Q); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + gcry_ctx_release (ctx); +} + + int main (int argc, char **argv) { @@ -1067,6 +1332,7 @@ main (int argc, char **argv) context_alloc (); context_param (); basic_ec_math (); + point_on_curve (); /* The tests are for P-192 and ed25519 which are not supported in FIPS mode. */ commit 54620a27f4503e703e219e6e11c4be14ce4e3d35 Author: Werner Koch Date: Tue Jun 5 14:29:53 2018 +0200 mpi: New internal function _gcry_mpi_cmpabs. * mpi/mpi-cmp.c (_gcry_mpi_cmp): Factor out to ... (do_mpi_cmp): New. Add arg absmode. (_gcry_mpi_cmpabs): New. * src/gcrypt-int.h (mpi_cmpabs): New macro. Signed-off-by: Werner Koch (cherry picked from commit 6606ae44e0de1069b29dd4215ee9748280940e1b) diff --git a/mpi/mpi-cmp.c b/mpi/mpi-cmp.c index 838a7c9..66e0961 100644 --- a/mpi/mpi-cmp.c +++ b/mpi/mpi-cmp.c @@ -54,15 +54,19 @@ _gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) } -int -_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) +/* Helper for _gcry_mpi_cmp and _gcry_mpi_cmpabs. */ +static int +do_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v, int absmode) { mpi_size_t usize; mpi_size_t vsize; + int usign; + int vsign; int cmp; if (mpi_is_opaque (u) || mpi_is_opaque (v)) { + /* We have no signan and thus ABSMODE has no efeect here. */ if (mpi_is_opaque (u) && !mpi_is_opaque (v)) return -1; if (!mpi_is_opaque (u) && mpi_is_opaque (v)) @@ -82,26 +86,42 @@ _gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) usize = u->nlimbs; vsize = v->nlimbs; + usign = absmode? 0 : u->sign; + vsign = absmode? 0 : v->sign; /* Compare sign bits. */ - if (!u->sign && v->sign) + if (!usign && vsign) return 1; - if (u->sign && !v->sign) + if (usign && !vsign) return -1; /* U and V are either both positive or both negative. */ - if (usize != vsize && !u->sign && !v->sign) + if (usize != vsize && !usign && !vsign) return usize - vsize; - if (usize != vsize && u->sign && v->sign) + if (usize != vsize && usign && vsign) return vsize + usize; if (!usize ) return 0; if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) return 0; - if ((cmp < 0?1:0) == (u->sign?1:0)) + if ((cmp < 0?1:0) == (usign?1:0)) return 1; } return -1; } + + +int +_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) +{ + return do_mpi_cmp (u, v, 0); +} + +/* Compare only the absolute values. */ +int +_gcry_mpi_cmpabs (gcry_mpi_t u, gcry_mpi_t v) +{ + return do_mpi_cmp (u, v, 1); +} diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h index ad719be..a69618c 100644 --- a/src/gcrypt-int.h +++ b/src/gcrypt-int.h @@ -368,6 +368,7 @@ int _gcry_mpi_is_neg (gcry_mpi_t a); void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u); void _gcry_mpi_abs (gcry_mpi_t w); int _gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); +int _gcry_mpi_cmpabs (const gcry_mpi_t u, const gcry_mpi_t v); int _gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); gpg_err_code_t _gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, const void *buffer, size_t buflen, @@ -469,6 +470,7 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); #define mpi_abs( w ) _gcry_mpi_abs( (w) ) #define mpi_neg( w, u) _gcry_mpi_neg( (w), (u) ) #define mpi_cmp( u, v ) _gcry_mpi_cmp( (u), (v) ) +#define mpi_cmpabs( u, v ) _gcry_mpi_cmpabs( (u), (v) ) #define mpi_cmp_ui( u, v ) _gcry_mpi_cmp_ui( (u), (v) ) #define mpi_is_neg( a ) _gcry_mpi_is_neg ((a)) ----------------------------------------------------------------------- Summary of changes: mpi/ec.c | 9 ++ mpi/mpi-cmp.c | 34 +++++-- src/gcrypt-int.h | 2 + tests/t-mpi-point.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 304 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 01:01:55 2018 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 12 Jun 2018 01:01:55 +0200 Subject: [git] GnuPG - branch, fix-T4017, created. gnupg-2.2.8-5-ge051c27 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, fix-T4017 has been created at e051c279216ecd4ec9a48e13ccc695f5ab667b2a (commit) - Log ----------------------------------------------------------------- commit e051c279216ecd4ec9a48e13ccc695f5ab667b2a Author: Daniel Kahn Gillmor Date: Mon Jun 11 18:33:26 2018 -0400 gpg: set full --dry-run when used with --show-keys * g10/gpg.c (main): ensure that opt.dry_run matches opt.import_options[IMPORT_DRY_RUN]. -- It seems that the import_options IMPORT_DRY_RUN bit doesn't have the same power as the opt.dry_run bit itself. When one is set or cleared by command-line options or other option parsing, we should ensure that the other is also set or cleared. It would probably be cleaner to have just a single bit, stored in a single place, but that kind of overhaul is beyond the scope of this bugfix. GnuPG-Bug-id: 4017 Signed-off-by: Daniel Kahn Gillmor diff --git a/g10/gpg.c b/g10/gpg.c index c117de3..4f4aae7 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2609,6 +2609,7 @@ main (int argc, char **argv) set_cmd (&cmd, pargs.r_opt); opt.import_options |= IMPORT_SHOW; opt.import_options |= IMPORT_DRY_RUN; + opt.dry_run = 1; opt.import_options &= ~IMPORT_REPAIR_KEYS; opt.list_options |= LIST_SHOW_UNUSABLE_UIDS; opt.list_options |= LIST_SHOW_UNUSABLE_SUBKEYS; @@ -2647,7 +2648,10 @@ main (int argc, char **argv) case oQuiet: opt.quiet = 1; break; case oNoTTY: tty_no_terminal(1); break; - case oDryRun: opt.dry_run = 1; break; + case oDryRun: + opt.dry_run = 1; + opt.import_options |= IMPORT_DRY_RUN; + break; case oInteractive: opt.interactive = 1; break; case oVerbose: opt.verbose++; @@ -3208,14 +3212,19 @@ main (int argc, char **argv) } break; case oImportOptions: - if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1)) - { - if(configname) - log_error(_("%s:%d: invalid import options\n"), - configname,configlineno); - else - log_error(_("invalid import options\n")); - } + { + unsigned int old_import_options = opt.import_options; + if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1)) + { + if(configname) + log_error(_("%s:%d: invalid import options\n"), + configname,configlineno); + else + log_error(_("invalid import options\n")); + } + if ((old_import_options & IMPORT_DRY_RUN) != (opt.import_options & IMPORT_DRY_RUN)) + opt.dry_run = !!(opt.import_options & IMPORT_DRY_RUN); + } break; case oImportFilter: rc = parse_and_set_import_filter (pargs.r.ret_str); ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 06:01:37 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 12 Jun 2018 06:01:37 +0200 Subject: [git] GnuPG - branch, gniibe/decryption-key, updated. gnupg-2.2.7-142-ged9030c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, gniibe/decryption-key has been updated via ed9030cb2a67148dfafa7f2c0d5a0be67a818397 (commit) via ba7e934945a50aa37e3e971067dbfff724fe9696 (commit) via b0c00ce0af1b1ac140ae675299214af34e4e0c1f (commit) from c03a3eb01d2d26bd69e6d7c7d2a5f72229e189e0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ed9030cb2a67148dfafa7f2c0d5a0be67a818397 Author: NIIBE Yutaka Date: Tue Jun 12 10:42:24 2018 +0900 g10: Prefer to available card keys for decryption. * g10/skclist.c (enum_secret_keys): Add logic to prefer decryption keys on cards. Signed-off-by: NIIBE Yutaka diff --git a/g10/skclist.c b/g10/skclist.c index f8c8cad..d40fe6d 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -329,6 +329,9 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) int eof; int state; strlist_t sl; + strlist_t card_list; + char *serialno; + struct agent_card_info_s info; kbnode_t keyblock; kbnode_t node; getkey_ctx_t ctx; @@ -347,6 +350,9 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) if (!sk) { /* Free the context. */ + agent_release_card_info (&c->info); + xfree (c->serialno); + free_strlist (c->card_list); pubkeys_free (c->results); release_kbnode (c->keyblock); getkey_end (ctrl, c->ctx); @@ -390,7 +396,49 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) c->state++; break; - case 3: /* Init search context to enum all secret keys. */ + case 3: /* Init list of card keys to try. */ + err = agent_scd_cardlist (&c->card_list); + if (!err) + agent_scd_serialno (&c->serialno, NULL); + c->sl = c->card_list; + c->state++; + break; + + case 4: /* Get next item from card list. */ + if (c->sl) + { + char *serialno; + + err = agent_scd_serialno (&serialno, c->sl->d); + if (err) + { + if (opt.verbose) + log_info (_("error getting serial number of card: %s\n"), + gpg_strerror (err)); + continue; + } + + xfree (serialno); + agent_release_card_info (&c->info); + err = agent_scd_getattr ("KEY-FPR", &c->info); + if (err) + log_error ("error retrieving key fingerprint from card: %s\n", + gpg_strerror (err)); + + if (c->info.fpr2valid) + name = c->info.fpr2; + c->sl = c->sl->next; + } + else + { + if (c->serialno) + /* Select the original card again. */ + agent_scd_serialno (&c->serialno, c->serialno); + c->state++; + } + break; + + case 5: /* Init search context to enum all secret keys. */ err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1, &keyblock); if (err) @@ -403,7 +451,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) c->state++; break; - case 4: /* Get next item from the context. */ + case 6: /* Get next item from the context. */ if (c->ctx) { err = getkey_next (ctrl, c->ctx, NULL, &keyblock); @@ -446,10 +494,10 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) /* Get the next key from the current keyblock. */ for (; c->node; c->node = c->node->next) - { - if (c->node->pkt->pkttype == PKT_PUBLIC_KEY + { + if (c->node->pkt->pkttype == PKT_PUBLIC_KEY || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { + { pubkey_t r; /* Skip this candidate if it's already enumerated. */ @@ -459,8 +507,8 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) if (r) continue; - copy_public_key (sk, c->node->pkt->pkt.public_key); - c->node = c->node->next; + copy_public_key (sk, c->node->pkt->pkt.public_key); + c->node = c->node->next; r = xtrycalloc (1, sizeof (*r)); if (!r) @@ -475,8 +523,8 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) r->next = c->results; c->results = r; - return 0; /* Found. */ - } + return 0; /* Found. */ + } } /* Dispose the keyblock and continue. */ commit ba7e934945a50aa37e3e971067dbfff724fe9696 Author: NIIBE Yutaka Date: Tue Jun 12 10:36:59 2018 +0900 g10: Move enum_secret_keys to skclist.c. * g10/getkey.c (enum_secret_keys): Move to... * g10/skclist.c (enum_secret_keys): ... here. -- The function enum_secret_keys is not used by gpgv.c, but it is in getkey.c. Extending enum_secret_keys will require change of gpgv.c, so moving the function to the file for gpg is better. Signed-off-by: NIIBE Yutaka diff --git a/g10/getkey.c b/g10/getkey.c index 470bab6..55c8628 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3904,203 +3904,6 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret, } -/* Enumerate some secret keys (specifically, those specified with - * --default-key and --try-secret-key). Use the following procedure: - * - * 1) Initialize a void pointer to NULL - * 2) Pass a reference to this pointer to this function (content) - * and provide space for the secret key (sk) - * 3) Call this function as long as it does not return an error (or - * until you are done). The error code GPG_ERR_EOF indicates the - * end of the listing. - * 4) Call this function a last time with SK set to NULL, - * so that can free it's context. - * - * In pseudo-code: - * - * void *ctx = NULL; - * PKT_public_key *sk = xmalloc_clear (sizeof (*sk)); - * - * while ((err = enum_secret_keys (&ctx, sk))) - * { // Process SK. - * if (done) - * break; - * sk = xmalloc_clear (sizeof (*sk)); - * } - * - * // Release any resources used by CTX. - * enum_secret_keys (&ctx, NULL); - * - * if (gpg_err_code (err) != GPG_ERR_EOF) - * ; // An error occurred. - */ -gpg_error_t -enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) -{ - gpg_error_t err = 0; - const char *name; - kbnode_t keyblock; - struct - { - int eof; - int state; - strlist_t sl; - kbnode_t keyblock; - kbnode_t node; - getkey_ctx_t ctx; - pubkey_t results; - } *c = *context; - - if (!c) - { - /* Make a new context. */ - c = xtrycalloc (1, sizeof *c); - if (!c) - return gpg_error_from_syserror (); - *context = c; - } - - if (!sk) - { - /* Free the context. */ - pubkeys_free (c->results); - release_kbnode (c->keyblock); - getkey_end (ctrl, c->ctx); - xfree (c); - *context = NULL; - return 0; - } - - if (c->eof) - return gpg_error (GPG_ERR_EOF); - - for (;;) - { - /* Loop until we have a keyblock. */ - while (!c->keyblock) - { - /* Loop over the list of secret keys. */ - do - { - name = NULL; - keyblock = NULL; - switch (c->state) - { - case 0: /* First try to use the --default-key. */ - name = parse_def_secret_key (ctrl); - c->state = 1; - break; - - case 1: /* Init list of keys to try. */ - c->sl = opt.secret_keys_to_try; - c->state++; - break; - - case 2: /* Get next item from list. */ - if (c->sl) - { - name = c->sl->d; - c->sl = c->sl->next; - } - else - c->state++; - break; - - case 3: /* Init search context to enum all secret keys. */ - err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1, - &keyblock); - if (err) - { - release_kbnode (keyblock); - keyblock = NULL; - getkey_end (ctrl, c->ctx); - c->ctx = NULL; - } - c->state++; - break; - - case 4: /* Get next item from the context. */ - if (c->ctx) - { - err = getkey_next (ctrl, c->ctx, NULL, &keyblock); - if (err) - { - release_kbnode (keyblock); - keyblock = NULL; - getkey_end (ctrl, c->ctx); - c->ctx = NULL; - } - } - else - c->state++; - break; - - default: /* No more names to check - stop. */ - c->eof = 1; - return gpg_error (GPG_ERR_EOF); - } - } - while ((!name || !*name) && !keyblock); - - if (keyblock) - c->node = c->keyblock = keyblock; - else - { - err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock); - if (err) - { - /* getkey_byname might return a keyblock even in the - error case - I have not checked. Thus better release - it. */ - release_kbnode (c->keyblock); - c->keyblock = NULL; - } - else - c->node = c->keyblock; - } - } - - /* Get the next key from the current keyblock. */ - for (; c->node; c->node = c->node->next) - { - if (c->node->pkt->pkttype == PKT_PUBLIC_KEY - || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - pubkey_t r; - - /* Skip this candidate if it's already enumerated. */ - for (r = c->results; r; r = r->next) - if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key)) - break; - if (r) - continue; - - copy_public_key (sk, c->node->pkt->pkt.public_key); - c->node = c->node->next; - - r = xtrycalloc (1, sizeof (*r)); - if (!r) - { - err = gpg_error_from_syserror (); - free_public_key (sk); - return err; - } - - r->pk = sk; - r->keyblock = NULL; - r->next = c->results; - c->results = r; - - return 0; /* Found. */ - } - } - - /* Dispose the keyblock and continue. */ - release_kbnode (c->keyblock); - c->keyblock = NULL; - } -} - gpg_error_t get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk, const byte *fpr_card, size_t fpr_len) diff --git a/g10/skclist.c b/g10/skclist.c index 78890dc..f8c8cad 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -286,3 +286,201 @@ build_sk_list (ctrl_t ctrl, *ret_sk_list = sk_list; return err; } + + +/* Enumerate some secret keys (specifically, those specified with + * --default-key and --try-secret-key). Use the following procedure: + * + * 1) Initialize a void pointer to NULL + * 2) Pass a reference to this pointer to this function (content) + * and provide space for the secret key (sk) + * 3) Call this function as long as it does not return an error (or + * until you are done). The error code GPG_ERR_EOF indicates the + * end of the listing. + * 4) Call this function a last time with SK set to NULL, + * so that can free it's context. + * + * In pseudo-code: + * + * void *ctx = NULL; + * PKT_public_key *sk = xmalloc_clear (sizeof (*sk)); + * + * while ((err = enum_secret_keys (&ctx, sk))) + * { // Process SK. + * if (done) + * break; + * sk = xmalloc_clear (sizeof (*sk)); + * } + * + * // Release any resources used by CTX. + * enum_secret_keys (&ctx, NULL); + * + * if (gpg_err_code (err) != GPG_ERR_EOF) + * ; // An error occurred. + */ +gpg_error_t +enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) +{ + gpg_error_t err = 0; + const char *name; + kbnode_t keyblock; + struct + { + int eof; + int state; + strlist_t sl; + kbnode_t keyblock; + kbnode_t node; + getkey_ctx_t ctx; + pubkey_t results; + } *c = *context; + + if (!c) + { + /* Make a new context. */ + c = xtrycalloc (1, sizeof *c); + if (!c) + return gpg_error_from_syserror (); + *context = c; + } + + if (!sk) + { + /* Free the context. */ + pubkeys_free (c->results); + release_kbnode (c->keyblock); + getkey_end (ctrl, c->ctx); + xfree (c); + *context = NULL; + return 0; + } + + if (c->eof) + return gpg_error (GPG_ERR_EOF); + + for (;;) + { + /* Loop until we have a keyblock. */ + while (!c->keyblock) + { + /* Loop over the list of secret keys. */ + do + { + name = NULL; + keyblock = NULL; + switch (c->state) + { + case 0: /* First try to use the --default-key. */ + name = parse_def_secret_key (ctrl); + c->state = 1; + break; + + case 1: /* Init list of keys to try. */ + c->sl = opt.secret_keys_to_try; + c->state++; + break; + + case 2: /* Get next item from list. */ + if (c->sl) + { + name = c->sl->d; + c->sl = c->sl->next; + } + else + c->state++; + break; + + case 3: /* Init search context to enum all secret keys. */ + err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1, + &keyblock); + if (err) + { + release_kbnode (keyblock); + keyblock = NULL; + getkey_end (ctrl, c->ctx); + c->ctx = NULL; + } + c->state++; + break; + + case 4: /* Get next item from the context. */ + if (c->ctx) + { + err = getkey_next (ctrl, c->ctx, NULL, &keyblock); + if (err) + { + release_kbnode (keyblock); + keyblock = NULL; + getkey_end (ctrl, c->ctx); + c->ctx = NULL; + } + } + else + c->state++; + break; + + default: /* No more names to check - stop. */ + c->eof = 1; + return gpg_error (GPG_ERR_EOF); + } + } + while ((!name || !*name) && !keyblock); + + if (keyblock) + c->node = c->keyblock = keyblock; + else + { + err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock); + if (err) + { + /* getkey_byname might return a keyblock even in the + error case - I have not checked. Thus better release + it. */ + release_kbnode (c->keyblock); + c->keyblock = NULL; + } + else + c->node = c->keyblock; + } + } + + /* Get the next key from the current keyblock. */ + for (; c->node; c->node = c->node->next) + { + if (c->node->pkt->pkttype == PKT_PUBLIC_KEY + || c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + pubkey_t r; + + /* Skip this candidate if it's already enumerated. */ + for (r = c->results; r; r = r->next) + if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key)) + break; + if (r) + continue; + + copy_public_key (sk, c->node->pkt->pkt.public_key); + c->node = c->node->next; + + r = xtrycalloc (1, sizeof (*r)); + if (!r) + { + err = gpg_error_from_syserror (); + free_public_key (sk); + return err; + } + + r->pk = sk; + r->keyblock = NULL; + r->next = c->results; + c->results = r; + + return 0; /* Found. */ + } + } + + /* Dispose the keyblock and continue. */ + release_kbnode (c->keyblock); + c->keyblock = NULL; + } +} commit b0c00ce0af1b1ac140ae675299214af34e4e0c1f Author: NIIBE Yutaka Date: Mon Jun 11 15:02:57 2018 +0900 g10: Fix comment of enum_secret_keys. * g10/getkey.c (enum_secret_keys): Fix comment for usage of enum_secret_keys, following the previous change. -- Signed-off-by: NIIBE Yutaka diff --git a/g10/getkey.c b/g10/getkey.c index 670dc1d..470bab6 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3925,13 +3925,11 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret, * { // Process SK. * if (done) * break; - * free_public_key (sk); * sk = xmalloc_clear (sizeof (*sk)); * } * * // Release any resources used by CTX. * enum_secret_keys (&ctx, NULL); - * free_public_key (sk); * * if (gpg_err_code (err) != GPG_ERR_EOF) * ; // An error occurred. ----------------------------------------------------------------------- Summary of changes: g10/getkey.c | 199 ----------------------------------------------- g10/skclist.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+), 199 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 06:48:47 2018 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 12 Jun 2018 06:48:47 +0200 Subject: [git] GnuPG - branch, fix-T4019, created. gnupg-2.2.8-5-ge037657 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, fix-T4019 has been created at e037657edaf0b3ee9d2e30f6fe3edf6879976472 (commit) - Log ----------------------------------------------------------------- commit e037657edaf0b3ee9d2e30f6fe3edf6879976472 Author: Daniel Kahn Gillmor Date: Tue Jun 12 00:41:59 2018 -0400 gpg: Add new usage option for drop-subkey filters. * g10/import.c (impex_filter_getval): Add new "usage" property for drop-subkey filter. -- For example, this permits extraction of only encryption-capable subkeys like so: gpg --export-filter 'drop-subkey=usage !~ e' --export $FPR GnuPG-Bug-id: 4019 Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpg.texi b/doc/gpg.texi index 2915d25..d0aa010 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2418,6 +2418,11 @@ The available properties are: Boolean indicating whether a key or subkey is a secret one. (drop-subkey) + @item usage + A string indicating the usage flags for the subkey, from the + sequence ``ecsa?''. For example, a subkey capable of just signing + and authentication would be an exact match for ``sa''. (drop-subkey) + @item sig_created @itemx sig_created_d The first is the timestamp a signature packet was created. The diff --git a/g10/import.c b/g10/import.c index 6d2beaf..b609660 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1296,6 +1296,16 @@ impex_filter_getval (void *cookie, const char *propname) { result = pk_is_disabled (pk)? "1":"0"; } + else if (!strcmp (propname, "usage")) + { + snprintf (numbuf, sizeof numbuf, "%s%s%s%s%s", + (pk->pubkey_usage & PUBKEY_USAGE_ENC)?"e":"", + (pk->pubkey_usage & PUBKEY_USAGE_SIG)?"s":"", + (pk->pubkey_usage & PUBKEY_USAGE_CERT)?"c":"", + (pk->pubkey_usage & PUBKEY_USAGE_AUTH)?"a":"", + (pk->pubkey_usage & PUBKEY_USAGE_UNKNOWN)?"?":""); + result = numbuf; + } else result = NULL; } ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 08:19:49 2018 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 12 Jun 2018 08:19:49 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-147-g2ddfb5b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 2ddfb5bef920919443309ece9fa2930282bbce85 (commit) from 615b9d1fb779f3d5593484aa1e023b0ddff459f0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2ddfb5bef920919443309ece9fa2930282bbce85 Author: Daniel Kahn Gillmor Date: Tue Jun 12 00:41:59 2018 -0400 gpg: Add new usage option for drop-subkey filters. * g10/import.c (impex_filter_getval): Add new "usage" property for drop-subkey filter. -- For example, this permits extraction of only encryption-capable subkeys like so: gpg --export-filter 'drop-subkey=usage !~ e' --export $FPR GnuPG-Bug-id: 4019 Signed-off-by: Daniel Kahn Gillmor diff --git a/doc/gpg.texi b/doc/gpg.texi index 5f114c5..4cfd000 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2428,6 +2428,11 @@ The available properties are: Boolean indicating whether a key or subkey is a secret one. (drop-subkey) + @item usage + A string indicating the usage flags for the subkey, from the + sequence ``ecsa?''. For example, a subkey capable of just signing + and authentication would be an exact match for ``sa''. (drop-subkey) + @item sig_created @itemx sig_created_d The first is the timestamp a signature packet was created. The diff --git a/g10/import.c b/g10/import.c index 1a98e2a..2803997 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1314,6 +1314,16 @@ impex_filter_getval (void *cookie, const char *propname) { result = pk_is_disabled (pk)? "1":"0"; } + else if (!strcmp (propname, "usage")) + { + snprintf (numbuf, sizeof numbuf, "%s%s%s%s%s", + (pk->pubkey_usage & PUBKEY_USAGE_ENC)?"e":"", + (pk->pubkey_usage & PUBKEY_USAGE_SIG)?"s":"", + (pk->pubkey_usage & PUBKEY_USAGE_CERT)?"c":"", + (pk->pubkey_usage & PUBKEY_USAGE_AUTH)?"a":"", + (pk->pubkey_usage & PUBKEY_USAGE_UNKNOWN)?"?":""); + result = numbuf; + } else result = NULL; } ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 5 +++++ g10/import.c | 10 ++++++++++ 2 files changed, 15 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 08:48:35 2018 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Tue, 12 Jun 2018 08:48:35 +0200 Subject: [git] GnuPG - branch, fix-T4018, created. gnupg-2.2.8-5-gee1fc42 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, fix-T4018 has been created at ee1fc420fb9741b2cfaea6fa820a00be2923f514 (commit) - Log ----------------------------------------------------------------- commit ee1fc420fb9741b2cfaea6fa820a00be2923f514 Author: Daniel Kahn Gillmor Date: Tue Jun 12 02:41:30 2018 -0400 gpg: Print revocation certificate details when showing with-colons. * g10/import.c (import_revoke_cert): add options argument, and print colon-delimited output for revocation certificate as requested. -- I looked into trying to make this work with one of the functions in g10/keylist.c, but i saw nothing that will accept a revocation certificate on its own, so i'm replicating the functionality directly in g10/import.c. This is a bit unfortunate because the code for describing a revocation cert now exists in two separate places, but refactoring both list_keyblock_print() and list_keyblock_colon() in g10/keylist.c seems like a much heavier lift. GnuPG-Bug-id: 4018 Signed-off-by: Daniel Kahn Gillmor diff --git a/g10/import.c b/g10/import.c index 6d2beaf..ae32973 100644 --- a/g10/import.c +++ b/g10/import.c @@ -114,7 +114,8 @@ static int import_secret_one (ctrl_t ctrl, kbnode_t keyblock, unsigned int options, int for_migration, import_screener_t screener, void *screener_arg); static int import_revoke_cert (ctrl_t ctrl, - kbnode_t node, struct import_stats_s *stats); + kbnode_t node, unsigned int options, + struct import_stats_s *stats); static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self); static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, @@ -590,7 +591,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, screener, screener_arg); else if (keyblock->pkt->pkttype == PKT_SIGNATURE && IS_KEY_REV (keyblock->pkt->pkt.signature) ) - rc = import_revoke_cert (ctrl, keyblock, stats); + rc = import_revoke_cert (ctrl, keyblock, options, stats); else { log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); @@ -2607,7 +2608,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, * Import a revocation certificate; this is a single signature packet. */ static int -import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) +import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, struct import_stats_s *stats) { PKT_public_key *pk = NULL; kbnode_t onode; @@ -2623,6 +2624,24 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) keyid[0] = node->pkt->pkt.signature->keyid[0]; keyid[1] = node->pkt->pkt.signature->keyid[1]; + if ((options & IMPORT_SHOW) && + (opt.with_colons)) + { + PKT_signature *sig = node->pkt->pkt.signature; + char *issuer_fpr = issuer_fpr = issuer_fpr_string (sig); + + es_fprintf (es_stdout, "rev::%d:%08lX%08lX:%s:%s:::::::%s:::%d:\n", + sig->pubkey_algo, + (ulong) sig->keyid[0], (ulong) sig->keyid[1], + colon_datestr_from_sig (sig), + colon_expirestr_from_sig (sig), + issuer_fpr ? issuer_fpr : "", + sig->digest_algo); + + xfree (issuer_fpr); + es_fflush (es_stdout); + } + pk = xmalloc_clear( sizeof *pk ); rc = get_pubkey (ctrl, pk, keyid ); if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 08:55:40 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 12 Jun 2018 08:55:40 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-148-g8f99299 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 8f99299a54a0ac09f9c90c1085b704db78973fda (commit) from 2ddfb5bef920919443309ece9fa2930282bbce85 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f99299a54a0ac09f9c90c1085b704db78973fda Author: NIIBE Yutaka Date: Tue Jun 12 15:54:18 2018 +0900 card: Fix memory leak for fetch-url sub command. * g10/card-util.c (fetch_url): Release INFO. Signed-off-by: NIIBE Yutaka diff --git a/g10/card-util.c b/g10/card-util.c index 587f181..b7eedc0 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -851,6 +851,7 @@ fetch_url (ctrl_t ctrl) } } + agent_release_card_info (&info); return rc; } ----------------------------------------------------------------------- Summary of changes: g10/card-util.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 09:05:21 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Jun 2018 09:05:21 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-6-ge8f439e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via e8f439e0547463c24f3c10008fee73e6c4259f52 (commit) via 86b64876bef0d8c4be8e309fcf3e2ce21e65a947 (commit) from dc96fd883571a975cfea0882fd38d7b0dd78775b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e8f439e0547463c24f3c10008fee73e6c4259f52 Author: Werner Koch Date: Tue Jun 12 08:44:55 2018 +0200 gpg: Do not import revocations with --show-keys. * g10/import.c (import_revoke_cert): Add arg 'options'. Take care of IMPORT_DRY_RUN. -- GnuPG-bug-id: 4017 Signed-off-by: Werner Koch (cherry picked from commit 6c9e37b2e541e96e7c65e1679982a614b4863fdb) diff --git a/g10/import.c b/g10/import.c index b609660..ed3ada5 100644 --- a/g10/import.c +++ b/g10/import.c @@ -113,8 +113,8 @@ static int import_secret_one (ctrl_t ctrl, kbnode_t keyblock, struct import_stats_s *stats, int batch, unsigned int options, int for_migration, import_screener_t screener, void *screener_arg); -static int import_revoke_cert (ctrl_t ctrl, - kbnode_t node, struct import_stats_s *stats); +static int import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, + struct import_stats_s *stats); static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self); static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, @@ -590,7 +590,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, screener, screener_arg); else if (keyblock->pkt->pkttype == PKT_SIGNATURE && IS_KEY_REV (keyblock->pkt->pkt.signature) ) - rc = import_revoke_cert (ctrl, keyblock, stats); + rc = import_revoke_cert (ctrl, keyblock, options, stats); else { log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); @@ -2617,7 +2617,8 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, * Import a revocation certificate; this is a single signature packet. */ static int -import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) +import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, + struct import_stats_s *stats) { PKT_public_key *pk = NULL; kbnode_t onode; @@ -2707,31 +2708,34 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) /* insert it */ insert_kbnode( keyblock, clone_kbnode(node), 0 ); - /* and write the keyblock back */ - rc = keydb_update_keyblock (ctrl, hd, keyblock ); - if (rc) - log_error (_("error writing keyring '%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - keydb_release (hd); - hd = NULL; - - /* we are ready */ - if (!opt.quiet ) + /* and write the keyblock back unless in dry run mode. */ + if (!(opt.dry_run || (options & IMPORT_DRY_RUN))) { - char *p=get_user_id_native (ctrl, keyid); - log_info( _("key %s: \"%s\" revocation certificate imported\n"), - keystr(keyid),p); - xfree(p); - } - stats->n_revoc++; + rc = keydb_update_keyblock (ctrl, hd, keyblock ); + if (rc) + log_error (_("error writing keyring '%s': %s\n"), + keydb_get_resource_name (hd), gpg_strerror (rc) ); + keydb_release (hd); + hd = NULL; - /* If the key we just revoked was ultimately trusted, remove its - ultimate trust. This doesn't stop the user from putting the - ultimate trust back, but is a reasonable solution for now. */ - if (get_ownertrust (ctrl, pk) == TRUST_ULTIMATE) - clear_ownertrusts (ctrl, pk); + /* we are ready */ + if (!opt.quiet ) + { + char *p=get_user_id_native (ctrl, keyid); + log_info( _("key %s: \"%s\" revocation certificate imported\n"), + keystr(keyid),p); + xfree(p); + } - revalidation_mark (ctrl); + /* If the key we just revoked was ultimately trusted, remove its + * ultimate trust. This doesn't stop the user from putting the + * ultimate trust back, but is a reasonable solution for now. */ + if (get_ownertrust (ctrl, pk) == TRUST_ULTIMATE) + clear_ownertrusts (ctrl, pk); + + revalidation_mark (ctrl); + } + stats->n_revoc++; leave: keydb_release (hd); commit 86b64876bef0d8c4be8e309fcf3e2ce21e65a947 Author: Daniel Kahn Gillmor Date: Tue Jun 12 00:41:59 2018 -0400 gpg: Add new usage option for drop-subkey filters. * g10/import.c (impex_filter_getval): Add new "usage" property for drop-subkey filter. -- For example, this permits extraction of only encryption-capable subkeys like so: gpg --export-filter 'drop-subkey=usage !~ e' --export $FPR GnuPG-Bug-id: 4019 Signed-off-by: Daniel Kahn Gillmor (cherry picked from commit 2ddfb5bef920919443309ece9fa2930282bbce85) diff --git a/doc/gpg.texi b/doc/gpg.texi index 2915d25..d0aa010 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2418,6 +2418,11 @@ The available properties are: Boolean indicating whether a key or subkey is a secret one. (drop-subkey) + @item usage + A string indicating the usage flags for the subkey, from the + sequence ``ecsa?''. For example, a subkey capable of just signing + and authentication would be an exact match for ``sa''. (drop-subkey) + @item sig_created @itemx sig_created_d The first is the timestamp a signature packet was created. The diff --git a/g10/import.c b/g10/import.c index 6d2beaf..b609660 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1296,6 +1296,16 @@ impex_filter_getval (void *cookie, const char *propname) { result = pk_is_disabled (pk)? "1":"0"; } + else if (!strcmp (propname, "usage")) + { + snprintf (numbuf, sizeof numbuf, "%s%s%s%s%s", + (pk->pubkey_usage & PUBKEY_USAGE_ENC)?"e":"", + (pk->pubkey_usage & PUBKEY_USAGE_SIG)?"s":"", + (pk->pubkey_usage & PUBKEY_USAGE_CERT)?"c":"", + (pk->pubkey_usage & PUBKEY_USAGE_AUTH)?"a":"", + (pk->pubkey_usage & PUBKEY_USAGE_UNKNOWN)?"?":""); + result = numbuf; + } else result = NULL; } ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 5 +++++ g10/import.c | 66 ++++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 45 insertions(+), 26 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 09:06:54 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Jun 2018 09:06:54 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-149-gfe621cc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via fe621cc64b13b00914633630f28b4b417892d629 (commit) from 8f99299a54a0ac09f9c90c1085b704db78973fda (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fe621cc64b13b00914633630f28b4b417892d629 Author: Werner Koch Date: Tue Jun 12 08:44:55 2018 +0200 gpg: Do not import revocations with --show-keys. * g10/import.c (import_revoke_cert): Add arg 'options'. Take care of IMPORT_DRY_RUN. -- GnuPG-bug-id: 4017 Signed-off-by: Werner Koch diff --git a/g10/import.c b/g10/import.c index 2803997..9b693e9 100644 --- a/g10/import.c +++ b/g10/import.c @@ -113,8 +113,8 @@ static int import_secret_one (ctrl_t ctrl, kbnode_t keyblock, struct import_stats_s *stats, int batch, unsigned int options, int for_migration, import_screener_t screener, void *screener_arg); -static int import_revoke_cert (ctrl_t ctrl, - kbnode_t node, struct import_stats_s *stats); +static int import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, + struct import_stats_s *stats); static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self); static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, @@ -590,7 +590,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, screener, screener_arg); else if (keyblock->pkt->pkttype == PKT_SIGNATURE && IS_KEY_REV (keyblock->pkt->pkt.signature) ) - rc = import_revoke_cert (ctrl, keyblock, stats); + rc = import_revoke_cert (ctrl, keyblock, options, stats); else { log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); @@ -2636,7 +2636,8 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, * Import a revocation certificate; this is a single signature packet. */ static int -import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) +import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, + struct import_stats_s *stats) { PKT_public_key *pk = NULL; kbnode_t onode; @@ -2726,31 +2727,34 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats) /* insert it */ insert_kbnode( keyblock, clone_kbnode(node), 0 ); - /* and write the keyblock back */ - rc = keydb_update_keyblock (ctrl, hd, keyblock ); - if (rc) - log_error (_("error writing keyring '%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - keydb_release (hd); - hd = NULL; - - /* we are ready */ - if (!opt.quiet ) + /* and write the keyblock back unless in dry run mode. */ + if (!(opt.dry_run || (options & IMPORT_DRY_RUN))) { - char *p=get_user_id_native (ctrl, keyid); - log_info( _("key %s: \"%s\" revocation certificate imported\n"), - keystr(keyid),p); - xfree(p); - } - stats->n_revoc++; + rc = keydb_update_keyblock (ctrl, hd, keyblock ); + if (rc) + log_error (_("error writing keyring '%s': %s\n"), + keydb_get_resource_name (hd), gpg_strerror (rc) ); + keydb_release (hd); + hd = NULL; - /* If the key we just revoked was ultimately trusted, remove its - ultimate trust. This doesn't stop the user from putting the - ultimate trust back, but is a reasonable solution for now. */ - if (get_ownertrust (ctrl, pk) == TRUST_ULTIMATE) - clear_ownertrusts (ctrl, pk); + /* we are ready */ + if (!opt.quiet ) + { + char *p=get_user_id_native (ctrl, keyid); + log_info( _("key %s: \"%s\" revocation certificate imported\n"), + keystr(keyid),p); + xfree(p); + } - revalidation_mark (ctrl); + /* If the key we just revoked was ultimately trusted, remove its + * ultimate trust. This doesn't stop the user from putting the + * ultimate trust back, but is a reasonable solution for now. */ + if (get_ownertrust (ctrl, pk) == TRUST_ULTIMATE) + clear_ownertrusts (ctrl, pk); + + revalidation_mark (ctrl); + } + stats->n_revoc++; leave: keydb_release (hd); ----------------------------------------------------------------------- Summary of changes: g10/import.c | 56 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 26 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 09:22:35 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 12 Jun 2018 09:22:35 +0200 Subject: [git] GnuPG - branch, gniibe/decryption-key, updated. gnupg-2.2.7-143-g92d3dc9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, gniibe/decryption-key has been updated via 92d3dc9e1933cb877fe61942a68a76dcc4aab759 (commit) from ed9030cb2a67148dfafa7f2c0d5a0be67a818397 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 92d3dc9e1933cb877fe61942a68a76dcc4aab759 Author: NIIBE Yutaka Date: Tue Jun 12 16:20:21 2018 +0900 g10: Fix enum_secret_keys for card keys. * g10/skclist.c (enum_secret_keys): Since "KEY-FPR" returns fingerprint in binary, change it to hex string. Signed-off-by: NIIBE Yutaka diff --git a/g10/skclist.c b/g10/skclist.c index d40fe6d..fe24b4a 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -331,6 +331,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) strlist_t sl; strlist_t card_list; char *serialno; + char fpr2[43]; struct agent_card_info_s info; kbnode_t keyblock; kbnode_t node; @@ -350,7 +351,6 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) if (!sk) { /* Free the context. */ - agent_release_card_info (&c->info); xfree (c->serialno); free_strlist (c->card_list); pubkeys_free (c->results); @@ -419,14 +419,19 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) } xfree (serialno); - agent_release_card_info (&c->info); + c->info.fpr2valid = 0; err = agent_scd_getattr ("KEY-FPR", &c->info); if (err) log_error ("error retrieving key fingerprint from card: %s\n", gpg_strerror (err)); if (c->info.fpr2valid) - name = c->info.fpr2; + { + c->fpr2[0] = '0'; + c->fpr2[1] = 'x'; + bin2hex (c->info.fpr2, 20, c->fpr2+2); + name = c->fpr2; + } c->sl = c->sl->next; } else ----------------------------------------------------------------------- Summary of changes: g10/skclist.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 13:41:06 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 12 Jun 2018 13:41:06 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-22-g2d63f58 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 2d63f583988753c5c9aae756f8e7c7f7e478a504 (commit) from c02b9f60f970cde1556d3ab82f6df6794e1d8a47 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2d63f583988753c5c9aae756f8e7c7f7e478a504 Author: Andre Heinecke Date: Tue Jun 12 13:40:43 2018 +0200 po: Update german translation -- diff --git a/po/de.po b/po/de.po index 95fca73..f58d282 100644 --- a/po/de.po +++ b/po/de.po @@ -4,14 +4,15 @@ # # Werner Koch , 2005, 2007. # Andre Heinecke , 2016, 2017, 2018. +# aheinecke , 2018. msgid "" msgstr "" "Project-Id-Version: GpgOL 1.0.0\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" "POT-Creation-Date: 2018-06-12 11:16+0200\n" -"PO-Revision-Date: 2018-04-24 10:59+0100\n" -"Last-Translator: Andre Heinecke \n" -"Language-Team: English \n" +"PO-Revision-Date: 2018-06-12 13:40+0100\n" +"Last-Translator: aheinecke \n" +"Language-Team: English \n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -230,26 +231,27 @@ msgstr "Bitte warten Sie w?hrend die Nachricht entschl?sselt / gepr?ft wird.. #: src/mail.cpp:1127 src/mail.cpp:1196 msgid "HTML display disabled." -msgstr "" +msgstr "HTML Anzeige deaktiviert." #: src/mail.cpp:1128 src/mail.cpp:1197 msgid "HTML content in unsigned S/MIME mails is insecure." -msgstr "" +msgstr "HTML Inhalte in unsignierten S/MIME Mails sind unsicher." #: src/mail.cpp:1131 src/mail.cpp:1200 msgid "GpgOL will only show such mails as text." -msgstr "" +msgstr "GpgOL zeigt solche Mails nur als Text an." #: src/mail.cpp:1134 -#, fuzzy msgid "This message is shown only once." -msgstr "Diese Nachricht ist nicht verschl?sselt." +msgstr "Diese Meldung wird nur einmal angezeigt." #: src/mail.cpp:1203 msgid "" "Please ask the sender to sign the message or\n" "to send it with a plain text alternative." msgstr "" +"Bitten Sie den Absender die Nachrichten zu signieren oder\n" +"sie mit einem alternativen Text Teil zu senden." #: src/mail.cpp:1374 msgid "GpgOL: Oops, G Suite Sync account detected" @@ -566,25 +568,28 @@ msgstr "" #: src/mailitem-events.cpp:779 msgid "Dangerous reply" -msgstr "" +msgstr "Gef?hrliche Antwort" #: src/mailitem-events.cpp:780 msgid "Dangerous forward" -msgstr "" +msgstr "Gef?hrliche Weiterleitung" #: src/mailitem-events.cpp:781 msgid "Unsigned S/MIME mails are not integrity protected." -msgstr "" +msgstr "Unsignierte S/MIME Mails sind nicht integrit?tsgesch?tzt." #: src/mailitem-events.cpp:787 msgid "For security reasons no decrypted contents are included in this reply." msgstr "" +"Aus Sicherheitsgr?nden werden keine entschl?sselte Inhalte in die Antwort" +" aufgenommen." #: src/mailitem-events.cpp:792 msgid "" "For security reasons no decrypted contents are included in the forwarded " "mail." msgstr "" +"Aus Sicherheitsgr?nden werden keine entschl?sselte Inhalte weitergeleitet." #: src/mailitem-events.cpp:847 msgid "" @@ -642,6 +647,8 @@ msgid "" "Data is not integrity protected. Decrypting it could be a security problem. " "(no MDC)" msgstr "" +"Daten sind nicht integrit?tsgesch?tzt. Das Entschl?sseln k?nnte ein" +" Sicherheitsproblem sein. (Kein MDC)" #: src/parsecontroller.cpp:219 src/parsecontroller.cpp:295 msgid "Encrypted message (decryption not possible)" ----------------------------------------------------------------------- Summary of changes: po/de.po | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 13:45:41 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Jun 2018 13:45:41 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-150-g4404726 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 440472663d608660343c54f09172c851f5127c9c (commit) from fe621cc64b13b00914633630f28b4b417892d629 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 440472663d608660343c54f09172c851f5127c9c Author: Werner Koch Date: Tue Jun 12 13:46:00 2018 +0200 Require libgpg-error 1.29 and remove internal logging functions. * configure.ac (NEED_GPG_ERROR_VERSION): Set to 1.29 * common/util.h: Remove replacement error codes. * common/logging.h: Remove fallback to internal logging functions. * common/logging.c: Remove. * common/Makefile.am (common_sources): Remove logging.c Signed-off-by: Werner Koch diff --git a/common/Makefile.am b/common/Makefile.am index 94318da..d288fa3 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -49,7 +49,7 @@ common_sources = \ strlist.c strlist.h \ utf8conv.c utf8conv.h \ argparse.c argparse.h \ - logging.c logging.h \ + logging.h \ dotlock.c dotlock.h \ mischelp.c mischelp.h \ status.c status.h\ diff --git a/common/logging.c b/common/logging.c deleted file mode 100644 index 88860e7..0000000 --- a/common/logging.c +++ /dev/null @@ -1,1121 +0,0 @@ -/* logging.c - Useful logging functions - * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, - * 2009, 2010 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute and/or modify this - * part of GnuPG under the terms of either - * - * - the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * or - * - * - the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * or both in parallel, as here. - * - * GnuPG is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copies of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, see . - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_W32_SYSTEM -# ifdef HAVE_WINSOCK2_H -# include -# endif -# include -#else /*!HAVE_W32_SYSTEM*/ -# include -# include -# include -# include -#endif /*!HAVE_W32_SYSTEM*/ -#include -#include -#include -/* #include */ - -#define GNUPG_COMMON_NEED_AFLOCAL 1 -#include "util.h" -#include "i18n.h" -#include "common-defs.h" -#include "logging.h" -#include "sysutils.h" - -#if defined(GPGRT_ENABLE_LOG_MACROS) && defined(log_debug_string) - /* Nothing to do; the libgpgrt functions are used. */ -#else /* Use our own logging functions. */ - -#ifdef HAVE_W32_SYSTEM -# ifndef S_IRWXG -# define S_IRGRP S_IRUSR -# define S_IWGRP S_IWUSR -# endif -# ifndef S_IRWXO -# define S_IROTH S_IRUSR -# define S_IWOTH S_IWUSR -# endif -#endif - - -#ifdef HAVE_W32CE_SYSTEM -# define isatty(a) (0) -#endif - -#undef WITH_IPV6 -#if defined (AF_INET6) && defined(PF_INET) \ - && defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON) -# define WITH_IPV6 1 -#endif - -#ifndef EAFNOSUPPORT -# define EAFNOSUPPORT EINVAL -#endif -#ifndef INADDR_NONE /* Slowaris is missing that. */ -#define INADDR_NONE ((unsigned long)(-1)) -#endif /*INADDR_NONE*/ - -#ifdef HAVE_W32_SYSTEM -#define sock_close(a) closesocket(a) -#else -#define sock_close(a) close(a) -#endif - - -static estream_t logstream; -static int log_socket = -1; -static char prefix_buffer[80]; -static int with_time; -static int with_prefix; -static int with_pid; -#ifdef HAVE_W32_SYSTEM -static int no_registry; -#endif -static int (*get_pid_suffix_cb)(unsigned long *r_value); -static const char * (*socket_dir_cb)(void); -static int running_detached; -static int force_prefixes; - -static int missing_lf; -static int errorcount; - - -int -log_get_errorcount (int clear) -{ - int n = errorcount; - if( clear ) - errorcount = 0; - return n; -} - -void -log_inc_errorcount (void) -{ - errorcount++; -} - - -/* The following 3 functions are used by es_fopencookie to write logs - to a socket. */ -struct fun_cookie_s -{ - int fd; - int quiet; - int want_socket; - int is_socket; -#ifdef HAVE_W32CE_SYSTEM - int use_writefile; -#endif - char name[1]; -}; - - -/* Write NBYTES of BUFFER to file descriptor FD. */ -static int -writen (int fd, const void *buffer, size_t nbytes, int is_socket) -{ - const char *buf = buffer; - size_t nleft = nbytes; - int nwritten; -#ifndef HAVE_W32_SYSTEM - (void)is_socket; /* Not required. */ -#endif - - while (nleft > 0) - { -#ifdef HAVE_W32_SYSTEM - if (is_socket) - nwritten = send (fd, buf, nleft, 0); - else -#endif - nwritten = write (fd, buf, nleft); - - if (nwritten < 0 && errno == EINTR) - continue; - if (nwritten < 0) - return -1; - nleft -= nwritten; - buf = buf + nwritten; - } - - return 0; -} - - -/* Returns true if STR represents a valid port number in decimal - notation and no garbage is following. */ -static int -parse_portno (const char *str, unsigned short *r_port) -{ - unsigned int value; - - for (value=0; *str && (*str >= '0' && *str <= '9'); str++) - { - value = value * 10 + (*str - '0'); - if (value > 65535) - return 0; - } - if (*str || !value) - return 0; - - *r_port = value; - return 1; -} - - -static gpgrt_ssize_t -fun_writer (void *cookie_arg, const void *buffer, size_t size) -{ - struct fun_cookie_s *cookie = cookie_arg; - - /* FIXME: Use only estream with a callback for socket writing. This - avoids the ugly mix of fd and estream code. */ - - /* Note that we always try to reconnect to the socket but print - error messages only the first time an error occurred. If - RUNNING_DETACHED is set we don't fall back to stderr and even do - not print any error messages. This is needed because detached - processes often close stderr and by writing to file descriptor 2 - we might send the log message to a file not intended for logging - (e.g. a pipe or network connection). */ - if (cookie->want_socket && cookie->fd == -1) - { -#ifdef WITH_IPV6 - struct sockaddr_in6 srvr_addr_in6; -#endif - struct sockaddr_in srvr_addr_in; -#ifndef HAVE_W32_SYSTEM - struct sockaddr_un srvr_addr_un; -#endif - const char *name_for_err = ""; - size_t addrlen; - struct sockaddr *srvr_addr = NULL; - unsigned short port = 0; - int af = AF_LOCAL; - int pf = PF_LOCAL; - const char *name = cookie->name; - - /* Not yet open or meanwhile closed due to an error. */ - cookie->is_socket = 0; - - /* Check whether this is a TCP socket or a local socket. */ - if (!strncmp (name, "tcp://", 6) && name[6]) - { - name += 6; - af = AF_INET; - pf = PF_INET; - } -#ifndef HAVE_W32_SYSTEM - else if (!strncmp (name, "socket://", 9)) - name += 9; -#endif - - if (af == AF_LOCAL) - { - addrlen = 0; -#ifndef HAVE_W32_SYSTEM - memset (&srvr_addr, 0, sizeof srvr_addr); - srvr_addr_un.sun_family = af; - if (!*name && (name = socket_dir_cb ()) && *name) - { - if (strlen (name) + 7 < sizeof (srvr_addr_un.sun_path)-1) - { - strncpy (srvr_addr_un.sun_path, - name, sizeof (srvr_addr_un.sun_path)-1); - strcat (srvr_addr_un.sun_path, "/S.log"); - srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0; - srvr_addr = (struct sockaddr *)&srvr_addr_un; - addrlen = SUN_LEN (&srvr_addr_un); - name_for_err = srvr_addr_un.sun_path; - } - } - else - { - if (*name && strlen (name) < sizeof (srvr_addr_un.sun_path)-1) - { - strncpy (srvr_addr_un.sun_path, - name, sizeof (srvr_addr_un.sun_path)-1); - srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0; - srvr_addr = (struct sockaddr *)&srvr_addr_un; - addrlen = SUN_LEN (&srvr_addr_un); - } - } -#endif /*!HAVE_W32SYSTEM*/ - } - else - { - char *addrstr, *p; -#ifdef HAVE_INET_PTON - void *addrbuf = NULL; -#endif /*HAVE_INET_PTON*/ - - addrstr = xtrymalloc (strlen (name) + 1); - if (!addrstr) - addrlen = 0; /* This indicates an error. */ - else if (*name == '[') - { - /* Check for IPv6 literal address. */ - strcpy (addrstr, name+1); - p = strchr (addrstr, ']'); - if (!p || p[1] != ':' || !parse_portno (p+2, &port)) - { - gpg_err_set_errno (EINVAL); - addrlen = 0; - } - else - { - *p = 0; -#ifdef WITH_IPV6 - af = AF_INET6; - pf = PF_INET6; - memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6); - srvr_addr_in6.sin6_family = af; - srvr_addr_in6.sin6_port = htons (port); -#ifdef HAVE_INET_PTON - addrbuf = &srvr_addr_in6.sin6_addr; -#endif /*HAVE_INET_PTON*/ - srvr_addr = (struct sockaddr *)&srvr_addr_in6; - addrlen = sizeof srvr_addr_in6; -#else - gpg_err_set_errno (EAFNOSUPPORT); - addrlen = 0; -#endif - } - } - else - { - /* Check for IPv4 literal address. */ - strcpy (addrstr, name); - p = strchr (addrstr, ':'); - if (!p || !parse_portno (p+1, &port)) - { - gpg_err_set_errno (EINVAL); - addrlen = 0; - } - else - { - *p = 0; - memset (&srvr_addr_in, 0, sizeof srvr_addr_in); - srvr_addr_in.sin_family = af; - srvr_addr_in.sin_port = htons (port); -#ifdef HAVE_INET_PTON - addrbuf = &srvr_addr_in.sin_addr; -#endif /*HAVE_INET_PTON*/ - srvr_addr = (struct sockaddr *)&srvr_addr_in; - addrlen = sizeof srvr_addr_in; - } - } - - if (addrlen) - { -#ifdef HAVE_INET_PTON - if (inet_pton (af, addrstr, addrbuf) != 1) - addrlen = 0; -#else /*!HAVE_INET_PTON*/ - /* We need to use the old function. If we are here v6 - support isn't enabled anyway and thus we can do fine - without. Note that Windows has a compatible inet_pton - function named inetPton, but only since Vista. */ - srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr); - if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE) - addrlen = 0; -#endif /*!HAVE_INET_PTON*/ - } - - xfree (addrstr); - } - - cookie->fd = addrlen? socket (pf, SOCK_STREAM, 0) : -1; - if (cookie->fd == -1) - { - if (!cookie->quiet && !running_detached - && isatty (es_fileno (es_stderr))) - es_fprintf (es_stderr, "failed to create socket for logging: %s\n", - strerror(errno)); - } - else - { - if (connect (cookie->fd, srvr_addr, addrlen) == -1) - { - if (!cookie->quiet && !running_detached - && isatty (es_fileno (es_stderr))) - es_fprintf (es_stderr, "can't connect to '%s%s': %s\n", - cookie->name, name_for_err, strerror(errno)); - sock_close (cookie->fd); - cookie->fd = -1; - } - } - - if (cookie->fd == -1) - { - if (!running_detached) - { - /* Due to all the problems with apps not running - detached but being called with stderr closed or used - for a different purposes, it does not make sense to - switch to stderr. We therefore disable it. */ - if (!cookie->quiet) - { - /* fputs ("switching logging to stderr\n", stderr);*/ - cookie->quiet = 1; - } - cookie->fd = -1; /*fileno (stderr);*/ - } - } - else /* Connection has been established. */ - { - cookie->quiet = 0; - cookie->is_socket = 1; - } - } - - log_socket = cookie->fd; - if (cookie->fd != -1) - { -#ifdef HAVE_W32CE_SYSTEM - if (cookie->use_writefile) - { - DWORD nwritten; - - WriteFile ((HANDLE)cookie->fd, buffer, size, &nwritten, NULL); - return (gpgrt_ssize_t)size; /* Okay. */ - } -#endif - if (!writen (cookie->fd, buffer, size, cookie->is_socket)) - return (gpgrt_ssize_t)size; /* Okay. */ - } - - if (!running_detached && cookie->fd != -1 - && isatty (es_fileno (es_stderr))) - { - if (*cookie->name) - es_fprintf (es_stderr, "error writing to '%s': %s\n", - cookie->name, strerror(errno)); - else - es_fprintf (es_stderr, "error writing to file descriptor %d: %s\n", - cookie->fd, strerror(errno)); - } - if (cookie->is_socket && cookie->fd != -1) - { - sock_close (cookie->fd); - cookie->fd = -1; - log_socket = -1; - } - - return (gpgrt_ssize_t)size; -} - - -static int -fun_closer (void *cookie_arg) -{ - struct fun_cookie_s *cookie = cookie_arg; - - if (cookie->fd != -1 && cookie->fd != 2) - sock_close (cookie->fd); - xfree (cookie); - log_socket = -1; - return 0; -} - - -/* Common function to either set the logging to a file or a file - descriptor. */ -static void -set_file_fd (const char *name, int fd) -{ - estream_t fp; - int want_socket; -#ifdef HAVE_W32CE_SYSTEM - int use_writefile = 0; -#endif - struct fun_cookie_s *cookie; - - /* Close an open log stream. */ - if (logstream) - { - if (logstream != es_stderr) - es_fclose (logstream); - logstream = NULL; - } - - /* Figure out what kind of logging we want. */ - if (name && !strcmp (name, "-")) - { - name = NULL; - fd = es_fileno (es_stderr); - } - - want_socket = 0; - if (name && !strncmp (name, "tcp://", 6) && name[6]) - want_socket = 1; -#ifndef HAVE_W32_SYSTEM - else if (name && !strncmp (name, "socket://", 9)) - want_socket = 2; -#endif /*HAVE_W32_SYSTEM*/ -#ifdef HAVE_W32CE_SYSTEM - else if (name && !strcmp (name, "GPG2:")) - { - HANDLE hd; - - ActivateDevice (L"Drivers\\"GNUPG_NAME"_Log", 0); - /* Ignore a filename and write the debug output to the GPG2: - device. */ - hd = CreateFile (L"GPG2:", GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - fd = (hd == INVALID_HANDLE_VALUE)? -1 : (int)hd; - name = NULL; - force_prefixes = 1; - use_writefile = 1; - } -#endif /*HAVE_W32CE_SYSTEM*/ - - /* Setup a new stream. */ - - /* The xmalloc below is justified because we can expect that this - function is called only during initialization and there is no - easy way out of this error condition. */ - cookie = xmalloc (sizeof *cookie + (name? strlen (name):0)); - strcpy (cookie->name, name? name:""); - cookie->quiet = 0; - cookie->is_socket = 0; - cookie->want_socket = want_socket; -#ifdef HAVE_W32CE_SYSTEM - cookie->use_writefile = use_writefile; -#endif - if (!name) - cookie->fd = fd; - else if (want_socket) - cookie->fd = -1; - else - { - do - cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT, - (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH)); - while (cookie->fd == -1 && errno == EINTR); - } - log_socket = cookie->fd; - - { - es_cookie_io_functions_t io = { NULL }; - io.func_write = fun_writer; - io.func_close = fun_closer; - - fp = es_fopencookie (cookie, "w", io); - } - - /* On error default to a stderr based estream. */ - if (!fp) - fp = es_stderr; - - es_setvbuf (fp, NULL, _IOLBF, 0); - - logstream = fp; - - /* We always need to print the prefix and the pid for socket mode, - so that the server reading the socket can do something - meaningful. */ - force_prefixes = want_socket; - - missing_lf = 0; -} - - -/* Set the file to write log to. The special names NULL and "-" may - be used to select stderr and names formatted like - "socket:///home/foo/mylogs" may be used to write the logging to the - socket "/home/foo/mylogs". If the connection to the socket fails - or a write error is detected, the function writes to stderr and - tries the next time again to connect the socket. - */ -void -log_set_file (const char *name) -{ - set_file_fd (name? name: "-", -1); -} - -void -log_set_fd (int fd) -{ - if (! gnupg_fd_valid (fd)) - log_fatal ("logger-fd is invalid: %s\n", strerror (errno)); - - set_file_fd (NULL, fd); -} - - -/* Set a function to retrieve the directory name of a socket if - * only "socket://" has been given to log_set_file. */ -void -log_set_socket_dir_cb (const char *(*fnc)(void)) -{ - socket_dir_cb = fnc; -} - - -void -log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value)) -{ - get_pid_suffix_cb = cb; -} - - -void -log_set_prefix (const char *text, unsigned int flags) -{ - if (text) - { - strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1); - prefix_buffer[sizeof (prefix_buffer)-1] = 0; - } - - with_prefix = (flags & GPGRT_LOG_WITH_PREFIX); - with_time = (flags & GPGRT_LOG_WITH_TIME); - with_pid = (flags & GPGRT_LOG_WITH_PID); - running_detached = (flags & GPGRT_LOG_RUN_DETACHED); -#ifdef HAVE_W32_SYSTEM - no_registry = (flags & GPGRT_LOG_NO_REGISTRY); -#endif -} - - -const char * -log_get_prefix (unsigned int *flags) -{ - if (flags) - { - *flags = 0; - if (with_prefix) - *flags |= GPGRT_LOG_WITH_PREFIX; - if (with_time) - *flags |= GPGRT_LOG_WITH_TIME; - if (with_pid) - *flags |= GPGRT_LOG_WITH_PID; - if (running_detached) - *flags |= GPGRT_LOG_RUN_DETACHED; -#ifdef HAVE_W32_SYSTEM - if (no_registry) - *flags |= GPGRT_LOG_NO_REGISTRY; -#endif - } - return prefix_buffer; -} - -/* This function returns true if the file descriptor FD is in use for - logging. This is preferable over a test using log_get_fd in that - it allows the logging code to use more then one file descriptor. */ -int -log_test_fd (int fd) -{ - if (logstream) - { - int tmp = es_fileno (logstream); - if ( tmp != -1 && tmp == fd) - return 1; - } - if (log_socket != -1 && log_socket == fd) - return 1; - return 0; -} - -int -log_get_fd () -{ - return logstream? es_fileno(logstream) : -1; -} - -estream_t -log_get_stream () -{ - if (!logstream) - { - log_set_file (NULL); /* Make sure a log stream has been set. */ - assert (logstream); - } - return logstream; -} - - -static void -print_prefix (int level, int leading_backspace) -{ - if (level != GPGRT_LOG_CONT) - { /* Note this does not work for multiple line logging as we would - * need to print to a buffer first */ - if (with_time && !force_prefixes) - { - struct tm *tp; - time_t atime = time (NULL); - - tp = localtime (&atime); - es_fprintf_unlocked (logstream, "%04d-%02d-%02d %02d:%02d:%02d ", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec ); - } - if (with_prefix || force_prefixes) - es_fputs_unlocked (prefix_buffer, logstream); - if (with_pid || force_prefixes) - { - unsigned long pidsuf; - int pidfmt; - - if (get_pid_suffix_cb && (pidfmt=get_pid_suffix_cb (&pidsuf))) - es_fprintf_unlocked (logstream, pidfmt == 1? "[%u.%lu]":"[%u.%lx]", - (unsigned int)getpid (), pidsuf); - else - es_fprintf_unlocked (logstream, "[%u]", (unsigned int)getpid ()); - } - if ((!with_time && (with_prefix || with_pid)) || force_prefixes) - es_putc_unlocked (':', logstream); - /* A leading backspace suppresses the extra space so that we can - correctly output, programname, filename and linenumber. */ - if (!leading_backspace - && (with_time || with_prefix || with_pid || force_prefixes)) - es_putc_unlocked (' ', logstream); - } - - switch (level) - { - case GPGRT_LOG_BEGIN: break; - case GPGRT_LOG_CONT: break; - case GPGRT_LOG_INFO: break; - case GPGRT_LOG_WARN: break; - case GPGRT_LOG_ERROR: break; - case GPGRT_LOG_FATAL: es_fputs_unlocked ("Fatal: ",logstream ); break; - case GPGRT_LOG_BUG: es_fputs_unlocked ("Ohhhh jeeee: ", logstream); break; - case GPGRT_LOG_DEBUG: es_fputs_unlocked ("DBG: ", logstream ); break; - default: - es_fprintf_unlocked (logstream,"[Unknown log level %d]: ", level); - break; - } -} - - -static void -do_logv (int level, int ignore_arg_ptr, const char *extrastring, - const char *prefmt, const char *fmt, va_list arg_ptr) -{ - int leading_backspace = (fmt && *fmt == '\b'); - - if (!logstream) - { -#ifdef HAVE_W32_SYSTEM - char *tmp; - - tmp = (no_registry - ? NULL - : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR, - "DefaultLogFile")); - log_set_file (tmp && *tmp? tmp : NULL); - xfree (tmp); -#else - log_set_file (NULL); /* Make sure a log stream has been set. */ -#endif - assert (logstream); - } - - es_flockfile (logstream); - if (missing_lf && level != GPGRT_LOG_CONT) - es_putc_unlocked ('\n', logstream ); - missing_lf = 0; - - print_prefix (level, leading_backspace); - if (leading_backspace) - fmt++; - - if (fmt) - { - if (prefmt) - es_fputs_unlocked (prefmt, logstream); - - if (ignore_arg_ptr) - { /* This is used by log_string and comes with the extra - * feature that after a LF the next line is indent at the - * length of the prefix. Note that we do not yet include - * the length of the timestamp and pid in the indent - * computation. */ - const char *p, *pend; - - for (p = fmt; (pend = strchr (p, '\n')); p = pend+1) - es_fprintf_unlocked (logstream, "%*s%.*s", - (int)((p != fmt - && (with_prefix || force_prefixes)) - ?strlen (prefix_buffer)+2:0), "", - (int)(pend - p)+1, p); - es_fputs_unlocked (p, logstream); - } - else - es_vfprintf_unlocked (logstream, fmt, arg_ptr); - if (*fmt && fmt[strlen(fmt)-1] != '\n') - missing_lf = 1; - } - - /* If we have an EXTRASTRING print it now while we still hold the - * lock on the logstream. */ - if (extrastring) - { - int c; - - if (missing_lf) - { - es_putc_unlocked ('\n', logstream); - missing_lf = 0; - } - print_prefix (level, leading_backspace); - es_fputs_unlocked (">> ", logstream); - missing_lf = 1; - while ((c = *extrastring++)) - { - missing_lf = 1; - if (c == '\\') - es_fputs_unlocked ("\\\\", logstream); - else if (c == '\r') - es_fputs_unlocked ("\\r", logstream); - else if (c == '\n') - { - es_fputs_unlocked ("\\n\n", logstream); - if (*extrastring) - { - print_prefix (level, leading_backspace); - es_fputs_unlocked (">> ", logstream); - } - else - missing_lf = 0; - } - else - es_putc_unlocked (c, logstream); - } - if (missing_lf) - { - es_putc_unlocked ('\n', logstream); - missing_lf = 0; - } - } - - if (level == GPGRT_LOG_FATAL) - { - if (missing_lf) - es_putc_unlocked ('\n', logstream); - es_funlockfile (logstream); - exit (2); - } - else if (level == GPGRT_LOG_BUG) - { - if (missing_lf) - es_putc_unlocked ('\n', logstream ); - es_funlockfile (logstream); - /* Using backtrace requires a configure test and to pass - * -rdynamic to gcc. Thus we do not enable it now. */ - /* { */ - /* void *btbuf[20]; */ - /* int btidx, btlen; */ - /* char **btstr; */ - - /* btlen = backtrace (btbuf, DIM (btbuf)); */ - /* btstr = backtrace_symbols (btbuf, btlen); */ - /* if (btstr) */ - /* for (btidx=0; btidx < btlen; btidx++) */ - /* log_debug ("[%d] %s\n", btidx, btstr[btidx]); */ - /* } */ - abort (); - } - else - es_funlockfile (logstream); -} - - -void -log_log (int level, const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt) ; - do_logv (level, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); -} - - -void -log_logv (int level, const char *fmt, va_list arg_ptr) -{ - do_logv (level, 0, NULL, NULL, fmt, arg_ptr); -} - - -/* Same as log_logv but PREFIX is printed immediately before FMT. - * Note that PREFIX is an additional string and independent of the - * prefix set by log_set_prefix. */ -void -log_logv_prefix (int level, const char *prefix, - const char *fmt, va_list arg_ptr) -{ - do_logv (level, 0, NULL, prefix, fmt, arg_ptr); -} - - -static void -do_log_ignore_arg (int level, const char *str, ...) -{ - va_list arg_ptr; - va_start (arg_ptr, str); - do_logv (level, 1, NULL, NULL, str, arg_ptr); - va_end (arg_ptr); -} - - -/* Log STRING at LEVEL but indent from the second line on by the - * length of the prefix. */ -void -log_string (int level, const char *string) -{ - /* We need a dummy arg_ptr, but there is no portable way to create - * one. So we call the do_logv function through a variadic wrapper. */ - do_log_ignore_arg (level, string); -} - - -void -log_info (const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_INFO, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); -} - - -void -log_error (const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_ERROR, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); - /* Protect against counter overflow. */ - if (errorcount < 30000) - errorcount++; -} - - -void -log_fatal (const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_FATAL, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); - abort (); /* Never called; just to make the compiler happy. */ -} - - -void -log_bug (const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_BUG, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); - abort (); /* Never called; just to make the compiler happy. */ -} - - -void -log_debug (const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); -} - - -/* The same as log_debug but at the end of the output STRING is - * printed with LFs expanded to include the prefix and a final --end-- - * marker. */ -void -log_debug_string (const char *string, const char *fmt, ...) -{ - va_list arg_ptr ; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, string, NULL, fmt, arg_ptr); - va_end (arg_ptr); -} - - -void -log_printf (const char *fmt, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, fmt); - do_logv (fmt ? GPGRT_LOG_CONT : GPGRT_LOG_BEGIN, 0, NULL, NULL, fmt, arg_ptr); - va_end (arg_ptr); -} - - -/* Flush the log - this is useful to make sure that the trailing - linefeed has been printed. */ -void -log_flush (void) -{ - do_log_ignore_arg (GPGRT_LOG_CONT, NULL); -} - - -/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw - dump, with TEXT just an empty string, print a trailing linefeed, - otherwise print an entire debug line. */ -void -log_printhex (const void *buffer, size_t length, const char *text) -{ - if (text && *text) - log_debug ("%s ", text); - if (length) - { - const unsigned char *p = buffer; - log_printf ("%02X", *p); - for (length--, p++; length--; p++) - log_printf (" %02X", *p); - } - if (text) - log_printf ("\n"); -} - - -/* -void -log_printcanon () {} -is found in sexputils.c -*/ - -/* -void -log_printsexp () {} -is found in sexputils.c -*/ - -/* Print a microsecond timestamp followed by a FORMAT. */ -void -log_clock (const char *fmt, ...) -{ -#if ENABLE_LOG_CLOCK - static unsigned long long initial; - struct timespec tv; - unsigned long long now; - char clockbuf[50]; - va_list arg_ptr; - - if (clock_gettime (CLOCK_REALTIME, &tv)) - { - log_debug ("error getting the realtime clock value\n"); - return; - } - now = tv.tv_sec * 1000000000ull; - now += tv.tv_nsec; - - if (!initial) - initial = now; - - snprintf (clockbuf, sizeof clockbuf, "[%6llu] ", (now - initial)/1000); - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, NULL, clockbuf, fmt, arg_ptr); - va_end (arg_ptr); - -#else /*!ENABLE_LOG_CLOCK*/ - - /* You may need to link with -ltr to use the above code. */ - va_list arg_ptr; - - va_start (arg_ptr, fmt); - do_logv (GPGRT_LOG_DEBUG, 0, NULL, "[no clock] ", fmt, arg_ptr); - va_end (arg_ptr); - -#endif /*!ENABLE_LOG_CLOCK*/ -} - - -#ifdef GPGRT_HAVE_MACRO_FUNCTION -void -bug_at( const char *file, int line, const char *func ) -{ - log_log (GPGRT_LOG_BUG, "... this is a bug (%s:%d:%s)\n", file, line, func); - abort (); /* Never called; just to make the compiler happy. */ -} -#else /*!GPGRT_HAVE_MACRO_FUNCTION*/ -void -bug_at( const char *file, int line ) -{ - log_log (GPGRT_LOG_BUG, "you found a bug ... (%s:%d)\n", file, line); - abort (); /* Never called; just to make the compiler happy. */ -} -#endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ - - -#ifdef GPGRT_HAVE_MACRO_FUNCTION -void -_log_assert (const char *expr, const char *file, int line, const char *func) -{ - log_log (GPGRT_LOG_BUG, "Assertion \"%s\" in %s failed (%s:%d)\n", - expr, func, file, line); - abort (); /* Never called; just to make the compiler happy. */ -} -#else /*!GPGRT_HAVE_MACRO_FUNCTION*/ -void -_log_assert (const char *expr, const char *file, int line) -{ - log_log (GPGRT_LOG_BUG, "Assertion \"%s\" failed (%s:%d)\n", - expr, file, line); - abort (); /* Never called; just to make the compiler happy. */ -} -#endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ - -#endif /* Use our own logging functions. */ diff --git a/common/logging.h b/common/logging.h index a20b8f8..a5800cb 100644 --- a/common/logging.h +++ b/common/logging.h @@ -38,10 +38,9 @@ #include "mischelp.h" #include "w32help.h" -#if defined(GPGRT_ENABLE_LOG_MACROS) && defined(log_debug_string) - /* We use the libgpg-error provided log functions. but we need one - * more function: */ -# ifdef GPGRT_HAVE_MACRO_FUNCTION +/* We use the libgpg-error provided log functions. but we need one + * more function: */ +#ifdef GPGRT_HAVE_MACRO_FUNCTION # define BUG() bug_at ( __FILE__, __LINE__, __FUNCTION__) static inline void bug_at (const char *file, int line, const char *func) GPGRT_ATTR_NORETURN; @@ -52,7 +51,7 @@ bug_at (const char *file, int line, const char *func) file, line, func); abort (); } -# else +#else # define BUG() bug_at ( __FILE__, __LINE__) static inline void bug_at (const char *file, int line) GPGRT_ATTR_NORETURN; @@ -62,94 +61,9 @@ bug_at (const char *file, int line) gpgrt_log (GPGRT_LOGLVL_BUG, "there is a bug at %s:%d\n", file, line); abort (); } -# endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ - - -#else /* Use gnupg internal logging functions. */ - -int log_get_errorcount (int clear); -void log_inc_errorcount (void); -void log_set_file( const char *name ); -void log_set_fd (int fd); -void log_set_socket_dir_cb (const char *(*fnc)(void)); -void log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value)); -void log_set_prefix (const char *text, unsigned int flags); -const char *log_get_prefix (unsigned int *flags); -int log_test_fd (int fd); -int log_get_fd(void); -estream_t log_get_stream (void); - -#ifdef GPGRT_HAVE_MACRO_FUNCTION - void bug_at (const char *file, int line, const char *func) - GPGRT_ATTR_NORETURN; - void _log_assert (const char *expr, const char *file, int line, - const char *func) GPGRT_ATTR_NORETURN; -# define BUG() bug_at( __FILE__ , __LINE__, __FUNCTION__) -# define log_assert(expr) \ - ((expr) \ - ? (void) 0 \ - : _log_assert (#expr, __FILE__, __LINE__, __FUNCTION__)) -#else /*!GPGRT_HAVE_MACRO_FUNCTION*/ - void bug_at (const char *file, int line); - void _log_assert (const char *expr, const char *file, int line); -# define BUG() bug_at( __FILE__ , __LINE__ ) -# define log_assert(expr) \ - ((expr) \ - ? (void) 0 \ - : _log_assert (#expr, __FILE__, __LINE__)) #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/ -/* Flag values for log_set_prefix. */ -#define GPGRT_LOG_WITH_PREFIX 1 -#define GPGRT_LOG_WITH_TIME 2 -#define GPGRT_LOG_WITH_PID 4 -#define GPGRT_LOG_RUN_DETACHED 256 -#define GPGRT_LOG_NO_REGISTRY 512 - -/* Log levels as used by log_log. */ -enum jnlib_log_levels { - GPGRT_LOG_BEGIN, - GPGRT_LOG_CONT, - GPGRT_LOG_INFO, - GPGRT_LOG_WARN, - GPGRT_LOG_ERROR, - GPGRT_LOG_FATAL, - GPGRT_LOG_BUG, - GPGRT_LOG_DEBUG -}; -#define GPGRT_LOGLVL_BEGIN GPGRT_LOG_BEGIN -#define GPGRT_LOGLVL_CONT GPGRT_LOG_CONT -#define GPGRT_LOGLVL_INFO GPGRT_LOG_INFO -#define GPGRT_LOGLVL_WARN GPGRT_LOG_WARN -#define GPGRT_LOGLVL_ERROR GPGRT_LOG_ERROR -#define GPGRT_LOGLVL_FATAL GPGRT_LOG_FATAL -#define GPGRT_LOGLVL_BUG GPGRT_LOG_BUG -#define GPGRT_LOGLVL_DEBUG GPGRT_LOG_DEBUG - -void log_log (int level, const char *fmt, ...) GPGRT_ATTR_PRINTF(2,3); -void log_logv (int level, const char *fmt, va_list arg_ptr); -void log_logv_prefix (int level, const char *prefix, - const char *fmt, va_list arg_ptr); -void log_string (int level, const char *string); -void log_bug (const char *fmt, ...) GPGRT_ATTR_NR_PRINTF(1,2); -void log_fatal (const char *fmt, ...) GPGRT_ATTR_NR_PRINTF(1,2); -void log_error (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); -void log_info (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); -void log_debug (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); -void log_debug_string (const char *string, const char *fmt, - ...) GPGRT_ATTR_PRINTF(2,3); -void log_printf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); -void log_flush (void); - -/* Print a hexdump of BUFFER. With TEXT passes as NULL print just the - raw dump, with TEXT being an empty string, print a trailing - linefeed, otherwise print an entire debug line with TEXT followed - by the hexdump and a final LF. */ -void log_printhex (const void *buffer, size_t length, const char *text); - -void log_clock (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2); -#endif /* Use gnupg internal logging functions. */ /* Some handy assertion macros which don't abort. */ diff --git a/common/util.h b/common/util.h index f372281..123d880 100644 --- a/common/util.h +++ b/common/util.h @@ -39,21 +39,6 @@ * libgpg-error version. Define them here. * Example: (#if GPG_ERROR_VERSION_NUMBER < 0x011500 // 1.21) */ -#if GPG_ERROR_VERSION_NUMBER < 0x011a00 /* 1.26 */ -# define GPG_ERR_UNKNOWN_FLAG 309 -# define GPG_ERR_INV_ORDER 310 -# define GPG_ERR_ALREADY_FETCHED 311 -# define GPG_ERR_TRY_LATER 312 -# define GPG_ERR_SYSTEM_BUG 666 -# define GPG_ERR_DNS_UNKNOWN 711 -# define GPG_ERR_DNS_SECTION 712 -# define GPG_ERR_DNS_ADDRESS 713 -# define GPG_ERR_DNS_NO_QUERY 714 -# define GPG_ERR_DNS_NO_ANSWER 715 -# define GPG_ERR_DNS_CLOSED 716 -# define GPG_ERR_DNS_VERIFY 717 -# define GPG_ERR_DNS_TIMEOUT 718 -#endif /* Hash function used with libksba. */ diff --git a/configure.ac b/configure.ac index 0665115..4916a5c 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,7 @@ AC_INIT([mym4_package],[mym4_version], [https://bugs.gnupg.org]) # build-aux/speedo.mk and Makefile.am AC_DEFINE_UNQUOTED(GNUPG_SWDB_TAG, "gnupg24", [swdb tag for this branch]) -NEED_GPG_ERROR_VERSION=1.24 +NEED_GPG_ERROR_VERSION=1.29 NEED_LIBGCRYPT_API=1 NEED_LIBGCRYPT_VERSION=1.7.0 ----------------------------------------------------------------------- Summary of changes: common/Makefile.am | 2 +- common/logging.c | 1121 ---------------------------------------------------- common/logging.h | 94 +---- common/util.h | 15 - configure.ac | 2 +- 5 files changed, 6 insertions(+), 1228 deletions(-) delete mode 100644 common/logging.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 14:15:28 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 12 Jun 2018 14:15:28 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-23-ge9839be Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via e9839bebf32222804e986e422fbfc03fbdc266ba (commit) from 2d63f583988753c5c9aae756f8e7c7f7e478a504 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e9839bebf32222804e986e422fbfc03fbdc266ba Author: Andre Heinecke Date: Tue Jun 12 14:14:49 2018 +0200 po: Update portugese translation * po/pt.po: Update translations. -- Translations provided by Marco A.G. Pinto. Thanks! diff --git a/po/pt.po b/po/pt.po index a14281e..a34bd3c 100644 --- a/po/pt.po +++ b/po/pt.po @@ -1,22 +1,24 @@ # pt.po - Portuguese translation for GpgOL # Copyright (C) 2017 g10 Code GmbH # This file is distributed under the same license as the GpgOL package. -# Werner Koch , 2005, 2007. # +# Werner Koch , 2005, 2007. +# aheinecke , 2018. msgid "" msgstr "" "Project-Id-Version: GpgOL 1.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" "POT-Creation-Date: 2018-06-12 11:16+0200\n" -"PO-Revision-Date: 2018-03-09 11:00+0000\n" -"Last-Translator: Marco A.G.Pinto \n" +"PO-Revision-Date: 2018-06-12 14:14+0100\n" +"Last-Translator: aheinecke \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-SourceCharset: UTF-8\n" -"X-Generator: Poedit 2.0.6\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/addin-options.cpp:41 msgid "General" @@ -235,26 +237,27 @@ msgstr "" #: src/mail.cpp:1127 src/mail.cpp:1196 msgid "HTML display disabled." -msgstr "" +msgstr "Mostrar HTML desativado." #: src/mail.cpp:1128 src/mail.cpp:1197 msgid "HTML content in unsigned S/MIME mails is insecure." -msgstr "" +msgstr "O conte?do HTML em e-mails S/MIME n?o assinados ? inseguro." #: src/mail.cpp:1131 src/mail.cpp:1200 msgid "GpgOL will only show such mails as text." -msgstr "" +msgstr "O GpgOL apenas mostrar? esses e-mails como texto." #: src/mail.cpp:1134 -#, fuzzy msgid "This message is shown only once." -msgstr "Esta mensagem n?o est? encriptada." +msgstr "Esta mensagem ? apenas mostrada uma vez." #: src/mail.cpp:1203 msgid "" "Please ask the sender to sign the message or\n" "to send it with a plain text alternative." msgstr "" +"Por favor, pede ao remetente para assinar a mensagem ou\n" +"para envi?-la com a alternativa de texto simples." #: src/mail.cpp:1374 msgid "GpgOL: Oops, G Suite Sync account detected" @@ -560,25 +563,29 @@ msgstr "" #: src/mailitem-events.cpp:779 msgid "Dangerous reply" -msgstr "" +msgstr "Resposta perigosa" #: src/mailitem-events.cpp:780 msgid "Dangerous forward" -msgstr "" +msgstr "Encaminhamento perigoso" #: src/mailitem-events.cpp:781 msgid "Unsigned S/MIME mails are not integrity protected." -msgstr "" +msgstr "Os e-mails S/MIME n?o assinados n?o t?m a integridade protegida." #: src/mailitem-events.cpp:787 msgid "For security reasons no decrypted contents are included in this reply." msgstr "" +"Por raz?es de seguran?a, os conte?dos desencriptados n?o s?o inclu?dos nesta" +" resposta." #: src/mailitem-events.cpp:792 msgid "" "For security reasons no decrypted contents are included in the forwarded " "mail." msgstr "" +"Por raz?es de seguran?a, os conte?dos desencriptados n?o s?o inclu?dos no" +" e-mail encaminhado." #: src/mailitem-events.cpp:847 msgid "" @@ -633,6 +640,8 @@ msgid "" "Data is not integrity protected. Decrypting it could be a security problem. " "(no MDC)" msgstr "" +"Os dados n?o t?m a integridade protegida. Desencriptar poder? ser um problema" +" de seguran?a. (sem MDC)" #: src/parsecontroller.cpp:219 src/parsecontroller.cpp:295 msgid "Encrypted message (decryption not possible)" ----------------------------------------------------------------------- Summary of changes: po/pt.po | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 12 16:13:01 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Jun 2018 16:13:01 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-151-gcb52eb7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via cb52eb76b3ba0269742c5322e10a2b5151dafaf2 (commit) from 440472663d608660343c54f09172c851f5127c9c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cb52eb76b3ba0269742c5322e10a2b5151dafaf2 Author: Werner Koch Date: Tue Jun 12 16:11:19 2018 +0200 Some preparations to eventuallt use gpgrt_argparse. * configure.ac (GNUPG_DEF_COPYRIGHT_LINE: New. * tools/watchgnupg.c (print_version): USe this macro. * common/init.c (_init_common_subsystems): Register argparse functions. Signed-off-by: Werner Koch diff --git a/common/init.c b/common/init.c index 86b71e5..f62c5cd 100644 --- a/common/init.c +++ b/common/init.c @@ -210,7 +210,11 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp) } /* --version et al shall use estream as well. */ - argparse_register_outfnc (writestring_via_estream); + argparse_register_outfnc (writestring_via_estream); /* legacy. */ + gpgrt_set_usage_outfnc (writestring_via_estream); + + /* Register our string mapper with gpgrt. */ + gpgrt_set_fixed_string_mapper (map_static_macro_string); /* Logging shall use the standard socket directory as fallback. */ log_set_socket_dir_cb (gnupg_socketdir); diff --git a/configure.ac b/configure.ac index 4916a5c..0d270a4 100644 --- a/configure.ac +++ b/configure.ac @@ -507,6 +507,9 @@ AH_BOTTOM([ #define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d" #define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d" +#define GNUPG_DEF_COPYRIGHT_LINE \ + "Copyright (C) 2018 Free Software Foundation, Inc." + /* For some systems (DOS currently), we hardcode the path here. For POSIX systems the values are constructed by the Makefiles, so that the values may be overridden by the make invocations; this is to diff --git a/g10/gpg.c b/g10/gpg.c index 8effc53..600f844 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3625,7 +3625,7 @@ main (int argc, char **argv) else { pargs.err = ARGPARSE_PRINT_ERROR; - /* The argparse fucntion calls a plain exit and thus + /* The argparse function calls a plain exit and thus * we need to print a status here. */ write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL)); diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index fc58d14..1db1c78 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -253,7 +253,7 @@ static void print_version (int with_help) { fputs (MYVERSION_LINE "\n" - "Copyright (C) 2017 Free Software Foundation, Inc.\n" + GNUPG_DEF_COPYRIGHT_LINE "\n" "License GPLv3+: " "GNU GPL version 3 or later \n" "This is free software: you are free to change and redistribute it.\n" ----------------------------------------------------------------------- Summary of changes: common/init.c | 6 +++++- configure.ac | 3 +++ g10/gpg.c | 2 +- tools/watchgnupg.c | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 09:00:15 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 13 Jun 2018 09:00:15 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-71-g9010d15 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 9010d1576e278a4274ad3f4aa15776c28f6ba965 (commit) from 7b6c2afd699e889f5f054cc3d202a61bd0ee1dcf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9010d1576e278a4274ad3f4aa15776c28f6ba965 Author: NIIBE Yutaka Date: Wed Jun 13 15:28:58 2018 +0900 ecc: Add blinding for ECDSA. * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Blind secret D with randomized nonce B. -- Reported-by: Keegan Ryan CVE-id: CVE-2018-0495 Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c index 1484830..140e8c0 100644 --- a/cipher/ecc-ecdsa.c +++ b/cipher/ecc-ecdsa.c @@ -50,6 +50,8 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, const void *abuf; unsigned int abits, qbits; mpi_ec_t ctx; + gcry_mpi_t b; /* Random number needed for blinding. */ + gcry_mpi_t bi; /* multiplicative inverse of B. */ if (DBG_CIPHER) log_mpidump ("ecdsa sign hash ", input ); @@ -61,6 +63,15 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, if (rc) return rc; + b = mpi_snew (qbits); + bi = mpi_snew (qbits); + do + { + _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM); + mpi_mod (b, b, skey->E.n); + } + while (!mpi_invm (bi, b, skey->E.n)); + k = NULL; dr = mpi_alloc (0); sum = mpi_alloc (0); @@ -115,8 +126,11 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, } while (!mpi_cmp_ui (r, 0)); - mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ - mpi_addm (sum, hash, dr, skey->E.n); /* sum = hash + (d*r) mod n */ + mpi_mulm (dr, b, skey->d, skey->E.n); + mpi_mulm (dr, dr, r, skey->E.n); /* dr = d*r mod n (blinded with b) */ + mpi_mulm (sum, b, hash, skey->E.n); + mpi_addm (sum, sum, dr, skey->E.n); /* sum = hash + (d*r) mod n (blinded with b) */ + mpi_mulm (sum, bi, sum, skey->E.n); /* undo blinding by b^-1 */ mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */ mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ } @@ -129,6 +143,8 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, } leave: + mpi_free (b); + mpi_free (bi); _gcry_mpi_ec_free (ctx); point_free (&I); mpi_free (x); ----------------------------------------------------------------------- Summary of changes: cipher/ecc-ecdsa.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 09:00:29 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 13 Jun 2018 09:00:29 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1.8-BRANCH, updated. libgcrypt-1.8.2-16-g9be06c6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1.8-BRANCH has been updated via 9be06c6b2e5c96edf40e566bbf51d44c4d46fb07 (commit) from 846f8fe8b3be6d235592db184361df1bc2b07a8a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9be06c6b2e5c96edf40e566bbf51d44c4d46fb07 Author: NIIBE Yutaka Date: Wed Jun 13 15:28:58 2018 +0900 ecc: Add blinding for ECDSA. * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Blind secret D with randomized nonce B. -- (cherry picked from commit 9010d1576e278a4274ad3f4aa15776c28f6ba965) Reported-by: Keegan Ryan CVE-id: CVE-2018-0495 Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c index 1484830..140e8c0 100644 --- a/cipher/ecc-ecdsa.c +++ b/cipher/ecc-ecdsa.c @@ -50,6 +50,8 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, const void *abuf; unsigned int abits, qbits; mpi_ec_t ctx; + gcry_mpi_t b; /* Random number needed for blinding. */ + gcry_mpi_t bi; /* multiplicative inverse of B. */ if (DBG_CIPHER) log_mpidump ("ecdsa sign hash ", input ); @@ -61,6 +63,15 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, if (rc) return rc; + b = mpi_snew (qbits); + bi = mpi_snew (qbits); + do + { + _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM); + mpi_mod (b, b, skey->E.n); + } + while (!mpi_invm (bi, b, skey->E.n)); + k = NULL; dr = mpi_alloc (0); sum = mpi_alloc (0); @@ -115,8 +126,11 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, } while (!mpi_cmp_ui (r, 0)); - mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ - mpi_addm (sum, hash, dr, skey->E.n); /* sum = hash + (d*r) mod n */ + mpi_mulm (dr, b, skey->d, skey->E.n); + mpi_mulm (dr, dr, r, skey->E.n); /* dr = d*r mod n (blinded with b) */ + mpi_mulm (sum, b, hash, skey->E.n); + mpi_addm (sum, sum, dr, skey->E.n); /* sum = hash + (d*r) mod n (blinded with b) */ + mpi_mulm (sum, bi, sum, skey->E.n); /* undo blinding by b^-1 */ mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */ mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ } @@ -129,6 +143,8 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, } leave: + mpi_free (b); + mpi_free (bi); _gcry_mpi_ec_free (ctx); point_free (&I); mpi_free (x); ----------------------------------------------------------------------- Summary of changes: cipher/ecc-ecdsa.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 09:00:48 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 13 Jun 2018 09:00:48 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-7-BRANCH, updated. libgcrypt-1.7.9-2-g325ab0b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-7-BRANCH has been updated via 325ab0b312e624cc581111e1f6ad38b20e5c18c7 (commit) from e16a71c777b7c4ea62be06de5b3cecd3a701a10b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 325ab0b312e624cc581111e1f6ad38b20e5c18c7 Author: NIIBE Yutaka Date: Wed Jun 13 15:28:58 2018 +0900 ecc: Add blinding for ECDSA. * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Blind secret D with randomized nonce B. -- (cherry picked from commit 9010d1576e278a4274ad3f4aa15776c28f6ba965) Reported-by: Keegan Ryan CVE-id: CVE-2018-0495 Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c index 1484830..140e8c0 100644 --- a/cipher/ecc-ecdsa.c +++ b/cipher/ecc-ecdsa.c @@ -50,6 +50,8 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, const void *abuf; unsigned int abits, qbits; mpi_ec_t ctx; + gcry_mpi_t b; /* Random number needed for blinding. */ + gcry_mpi_t bi; /* multiplicative inverse of B. */ if (DBG_CIPHER) log_mpidump ("ecdsa sign hash ", input ); @@ -61,6 +63,15 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, if (rc) return rc; + b = mpi_snew (qbits); + bi = mpi_snew (qbits); + do + { + _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM); + mpi_mod (b, b, skey->E.n); + } + while (!mpi_invm (bi, b, skey->E.n)); + k = NULL; dr = mpi_alloc (0); sum = mpi_alloc (0); @@ -115,8 +126,11 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, } while (!mpi_cmp_ui (r, 0)); - mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ - mpi_addm (sum, hash, dr, skey->E.n); /* sum = hash + (d*r) mod n */ + mpi_mulm (dr, b, skey->d, skey->E.n); + mpi_mulm (dr, dr, r, skey->E.n); /* dr = d*r mod n (blinded with b) */ + mpi_mulm (sum, b, hash, skey->E.n); + mpi_addm (sum, sum, dr, skey->E.n); /* sum = hash + (d*r) mod n (blinded with b) */ + mpi_mulm (sum, bi, sum, skey->E.n); /* undo blinding by b^-1 */ mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */ mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ } @@ -129,6 +143,8 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey, } leave: + mpi_free (b); + mpi_free (bi); _gcry_mpi_ec_free (ctx); point_free (&I); mpi_free (x); ----------------------------------------------------------------------- Summary of changes: cipher/ecc-ecdsa.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 09:07:24 2018 From: cvs at cvs.gnupg.org (by Erwin Bronkhorst) Date: Wed, 13 Jun 2018 09:07:24 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-24-g11b39fb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 11b39fb70f149afcbed8e252fe5ec56212edfc3e (commit) from e9839bebf32222804e986e422fbfc03fbdc266ba (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 11b39fb70f149afcbed8e252fe5ec56212edfc3e Author: Erwin Bronkhorst Date: Mon Jun 4 00:44:09 2018 +0200 Update Dutch translation. diff --git a/po/nl.po b/po/nl.po index bd31a92..899ab2f 100644 --- a/po/nl.po +++ b/po/nl.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: GpgOL 2.1.1\n" "Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" "POT-Creation-Date: 2018-06-12 11:16+0200\n" -"PO-Revision-Date: 2018-05-14 22:49+0200\n" +"PO-Revision-Date: 2018-06-12 21:28+0200\n" "Last-Translator: Erwin Bronkhorst \n" "Language-Team: \n" "Language: nl\n" @@ -231,26 +231,27 @@ msgstr "Een moment geduld voordat het bericht is ontcijferd / geverifieerd..." #: src/mail.cpp:1127 src/mail.cpp:1196 msgid "HTML display disabled." -msgstr "" +msgstr "Weergave van HTML uitgeschakeld." #: src/mail.cpp:1128 src/mail.cpp:1197 msgid "HTML content in unsigned S/MIME mails is insecure." -msgstr "" +msgstr "HTML-inhoud in niet-ondertekende S/MIME e-mail is onveilig." #: src/mail.cpp:1131 src/mail.cpp:1200 msgid "GpgOL will only show such mails as text." -msgstr "" +msgstr "GpgOL zal dergelijke e-mailberichten alleen als tekst weergeven." #: src/mail.cpp:1134 -#, fuzzy msgid "This message is shown only once." -msgstr "Dit bericht is niet versleuteld." +msgstr "Dit bericht wordt eenmalig weergegeven." #: src/mail.cpp:1203 msgid "" "Please ask the sender to sign the message or\n" "to send it with a plain text alternative." msgstr "" +"Vraag de verzender om het bericht te ondertekenen of\n" +" het als platte tekst te versturen." #: src/mail.cpp:1374 msgid "GpgOL: Oops, G Suite Sync account detected" @@ -564,25 +565,29 @@ msgstr "" #: src/mailitem-events.cpp:779 msgid "Dangerous reply" -msgstr "" +msgstr "Gevaarlijke handeling: Beantwoorden" #: src/mailitem-events.cpp:780 msgid "Dangerous forward" -msgstr "" +msgstr "Gevaarlijke handeling: Doorsturen" #: src/mailitem-events.cpp:781 msgid "Unsigned S/MIME mails are not integrity protected." -msgstr "" +msgstr "Ongetekende S/MAIL e-mailberichten zijn niet beschermd op integriteit." #: src/mailitem-events.cpp:787 msgid "For security reasons no decrypted contents are included in this reply." msgstr "" +"Uit veiligheidsoverwegingen wordt er geen ontsleutelde inhoud ingevoegd in " +"dit antwoord." #: src/mailitem-events.cpp:792 msgid "" "For security reasons no decrypted contents are included in the forwarded " "mail." msgstr "" +"Uit veiligheidsoverwegingen wordt er geen ontsleutelde inhoud ingevoegd in " +"deze doorgestuurde e-mail." #: src/mailitem-events.cpp:847 msgid "" @@ -640,6 +645,8 @@ msgid "" "Data is not integrity protected. Decrypting it could be a security problem. " "(no MDC)" msgstr "" +"Gegevens-integriteit is niet beschermd. Ontcijferen kan een " +"beveiligingsprobleem zijn. (geen MDC)" #: src/parsecontroller.cpp:219 src/parsecontroller.cpp:295 msgid "Encrypted message (decryption not possible)" ----------------------------------------------------------------------- Summary of changes: po/nl.po | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 10:01:37 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 10:01:37 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1.8-BRANCH, updated. libgcrypt-1.8.2-18-g6ca6344 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1.8-BRANCH has been updated via 6ca6344429e5ee1657e164509c6b50a717ebec68 (commit) via 5600d2d6b23640b0114655214f18959ee81fe58e (commit) from 9be06c6b2e5c96edf40e566bbf51d44c4d46fb07 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6ca6344429e5ee1657e164509c6b50a717ebec68 Author: Werner Koch Date: Wed Jun 13 10:01:57 2018 +0200 Post release updates -- diff --git a/NEWS b/NEWS index b77980c..b368d76 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.8.4 (unreleased) [C22/A2/R4] +------------------------------------------------ + + Noteworthy changes in version 1.8.3 (2018-06-13) [C22/A2/R3] ------------------------------------------------ @@ -16,6 +20,8 @@ Noteworthy changes in version 1.8.3 (2018-06-13) [C22/A2/R3] - Fix rare assertion failure in gcry_prime_check. + Release info at . + Noteworthy changes in version 1.8.2 (2017-12-13) [C22/A2/R2] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index dfcd4ef..ce11162 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.14" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [8]) -m4_define(mym4_version_micro, [3]) +m4_define(mym4_version_micro, [4]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag @@ -56,7 +56,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=22 LIBGCRYPT_LT_AGE=2 -LIBGCRYPT_LT_REVISION=3 +LIBGCRYPT_LT_REVISION=4 # If the API is changed in an incompatible way: increment the next counter. commit 5600d2d6b23640b0114655214f18959ee81fe58e Author: Werner Koch Date: Wed Jun 13 09:37:25 2018 +0200 Release 1.8.3 diff --git a/AUTHORS b/AUTHORS index 0d1da12..ab7a525 100644 --- a/AUTHORS +++ b/AUTHORS @@ -21,7 +21,7 @@ year that would otherwise be listed individually. List of Copyright holders ========================= - Copyright (C) 1989,1991-2017 Free Software Foundation, Inc. + Copyright (C) 1989,1991-2018 Free Software Foundation, Inc. Copyright (C) 1994 X Consortium Copyright (C) 1996 L. Peter Deutsch Copyright (C) 1997 Werner Koch @@ -30,7 +30,7 @@ List of Copyright holders Copyright (C) 1996-2006 Peter Gutmann, Matt Thomlinson and Blake Coverett Copyright (C) 2003 Nikos Mavroyanopoulos Copyright (C) 2006-2007 NTT (Nippon Telegraph and Telephone Corporation) - Copyright (C) 2012-2017 g10 Code GmbH + Copyright (C) 2012-2018 g10 Code GmbH Copyright (C) 2012 Simon Josefsson, Niels M??ller Copyright (c) 2012 Intel Corporation Copyright (C) 2013 Christian Grothoff diff --git a/NEWS b/NEWS index 204ca66..b77980c 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,21 @@ -Noteworthy changes in version 1.8.3 (unreleased) [C22/A2/R3] +Noteworthy changes in version 1.8.3 (2018-06-13) [C22/A2/R3] ------------------------------------------------ + * Bug fixes: + + - Use blinding for ECDSA signing to mitigate a novel side-channel + attack. [#4011,CVE-2018-0495] + + - Fix incorrect counter overflow handling for GCM when using an IV + size other than 96 bit. [#3764] + + - Fix incorrect output of AES-keywrap mode for in-place encryption + on some platforms. + + - Fix the gcry_mpi_ec_curve_point point validation function. + + - Fix rare assertion failure in gcry_prime_check. + Noteworthy changes in version 1.8.2 (2017-12-13) [C22/A2/R2] ------------------------------------------------ diff --git a/README b/README index c14181a..7ac8e4a 100644 --- a/README +++ b/README @@ -1,10 +1,10 @@ Libgcrypt - The GNU Crypto Library ------------------------------------ - Version 1.7 + Version 1.8 - Copyright (C) 1989,1991-2017 Free Software Foundation, Inc. - Copyright (C) 2012-2017 g10 Code GmbH - Copyright (C) 2013-2017 Jussi Kivilinna + Copyright (C) 1989,1991-2018 Free Software Foundation, Inc. + Copyright (C) 2012-2018 g10 Code GmbH + Copyright (C) 2013-2018 Jussi Kivilinna Libgcrypt is free software. See the file AUTHORS for full copying notices, and LICENSES for notices about contributions that require diff --git a/compat/compat.c b/compat/compat.c index b835293..8b001de 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -30,9 +30,9 @@ _gcry_compat_identification (void) static const char blurb[] = "\n\n" "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n" - "Copyright (C) 2000-2017 Free Software Foundation, Inc.\n" - "Copyright (C) 2012-2017 g10 Code GmbH\n" - "Copyright (C) 2013-2017 Jussi Kivilinna\n" + "Copyright (C) 2000-2018 Free Software Foundation, Inc.\n" + "Copyright (C) 2012-2018 g10 Code GmbH\n" + "Copyright (C) 2013-2018 Jussi Kivilinna\n" "\n" "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" "\n\n"; diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index d2e6293..c18b498 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -2651,10 +2651,10 @@ S-expression returned is: Where @var{r-mpi} and @var{s-mpi} are the result of the DSA sign operation. -For Elgamal signing (which is slow, yields large numbers and probably -is not as secure as the other algorithms), the same format is used -with "elg" replacing "dsa"; for ECDSA signing, the same format is used -with "ecdsa" replacing "dsa". +For Elgamal signing (which is slow, yields large numbers, hard to use +correctly and probably is not as secure as the other algorithms), the +same format is used with "elg" replacing "dsa"; for ECDSA signing, the +same format is used with "ecdsa" replacing "dsa". For the EdDSA algorithm (cf. Ed25515) the required input parameters are: diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index b85d494..ea06612 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -39,7 +39,7 @@ BEGIN VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0" VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT at .@LIBGCRYPT_LT_AGE at .@LIBGCRYPT_LT_REVISION at .@BUILD_REVISION@\0" VALUE "InternalName", "libgcrypt\0" - VALUE "LegalCopyright", "Copyright ? 2017 Free Software Foundation, Inc.\0" + VALUE "LegalCopyright", "Copyright ? 2018 Free Software Foundation, Inc.\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libgcrypt.dll\0" VALUE "PrivateBuild", "\0" ----------------------------------------------------------------------- Summary of changes: AUTHORS | 4 ++-- NEWS | 23 ++++++++++++++++++++++- README | 8 ++++---- compat/compat.c | 6 +++--- configure.ac | 4 ++-- doc/gcrypt.texi | 8 ++++---- src/versioninfo.rc.in | 2 +- 7 files changed, 38 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 10:03:59 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 10:03:59 +0200 Subject: [git] gnupg-doc - branch, master, updated. 823e9076f87a86ea258f6cf5cb0699b033365f11 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 823e9076f87a86ea258f6cf5cb0699b033365f11 (commit) from 51549ca5dbdc01c920fcbd5956f17de439e91d86 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 823e9076f87a86ea258f6cf5cb0699b033365f11 Author: Werner Koch Date: Wed Jun 13 10:04:28 2018 +0200 swdb: Libgcrypt 1.8.3 diff --git a/web/swdb.mac b/web/swdb.mac index 09a3730..4b6cb19 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -97,11 +97,11 @@ # # LIBGCRYPT # -#+macro: libgcrypt_ver 1.8.2 -#+macro: libgcrypt_date 2017-12-13 -#+macro: libgcrypt_size 2897k -#+macro: libgcrypt_sha1 ab8aae5d7a68f8e0988f90e11e7f6a4805af5c8d -#+macro: libgcrypt_sha2 c8064cae7558144b13ef0eb87093412380efa16c4ee30ad12ecb54886a524c07 +#+macro: libgcrypt_ver 1.8.3 +#+macro: libgcrypt_date 2018-06-13 +#+macro: libgcrypt_size 2919k +#+macro: libgcrypt_sha1 13bd2ce69e59ab538e959911dfae80ea309636e3 +#+macro: libgcrypt_sha2 66ec90be036747602f2b48f98312361a9180c97c68a690a5f376fa0f67d0af7c # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 10:17:02 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Wed, 13 Jun 2018 10:17:02 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-7-BRANCH, updated. libgcrypt-1.7.9-6-g3caf35a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-7-BRANCH has been updated via 3caf35a49cb62fb59834b5027ff299e2363a03c4 (commit) via 6dd0cf0744db29ef0d86830dd70f14381f0a5f56 (commit) via 3600e1224f6c89b3e637bdf1cf527ecc9a69afeb (commit) via 528a06b48389c9f10a1b10ff34cdc87bd3723a22 (commit) from 325ab0b312e624cc581111e1f6ad38b20e5c18c7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3caf35a49cb62fb59834b5027ff299e2363a03c4 Author: Jussi Kivilinna Date: Wed Jan 31 20:02:48 2018 +0200 Fix incorrect counter overflow handling for GCM * cipher/cipher-gcm.c (gcm_ctr_encrypt): New function to handle 32-bit CTR increment for GCM. (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt): Do not use generic CTR implementation directly, use gcm_ctr_encrypt instead. * tests/basic.c (_check_gcm_cipher): Add test-vectors for 32-bit CTR overflow. (check_gcm_cipher): Add 'split input to 15 bytes and 17 bytes' test-runs. -- Reported-by: Clemens Lang # ------------------------ >8 ------------------------ > I believe we have found what seems to be a bug in counter overflow > handling in AES-GCM in libgcrypt's implementation. This leads to > incorrect results when using a non-12-byte IV and decrypting payloads > encrypted with other AES-GCM implementations, such as OpenSSL. > > According to the NIST Special Publication 800-38D "Recommendation for > Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC", > section 7.1, algorithm 4, step 3 [NIST38D], the counter increment is > defined as inc_32. Section 6.2 of the same document defines the > incrementing function inc_s for positive integers s as follows: > > | the function increments the right-most s bits of the string, regarded > | as the binary representation of an integer, modulo 2^s; the remaining, > | left-most len(X) - s bits remain unchanged > > (X is the complete counter value in this case) > > This problem does not occur when using a 12-byte IV, because AES-GCM has > a special case for the inital counter value with 12-byte IVs: > > | If len(IV)=96, then J_0 = IV || 0^31 || 1 > > i.e., one would have to encrypt (UINT_MAX - 1) * blocksize of data to > hit an overflow. However, for non-12-byte IVs, the initial counter value > is the output of a hash function, which makes hitting an overflow much > more likely. > > In practice, we have found that using > > iv = 9e 79 18 8c ff 09 56 1e c9 90 99 cc 6d 5d f6 d3 > key = 26 56 e5 73 76 03 c6 95 0d 22 07 31 5d 32 5c 6b a5 54 5f 40 23 98 60 f6 f7 06 6f 7a 4f c2 ca 40 > > will reliably trigger an overflow when encrypting 10 MiB of data. It > seems that this is caused by re-using the AES-CTR implementation for > incrementing the counter. # ------------------------ 8< ------------------------ Bug was introduced by commit bd4bd23a2511a4bce63c3217cca0d4ecf0c79532 "GCM: Use counter mode code for speed-up". GnuPG-bug-id: 3764 Signed-off-by: Jussi Kivilinna (cherry picked from commit ffdc6f3623a0bcb41324d562340b2cd1c288e387) Resolved conflicts: tests/basic.c - use new constified version of TV. Added scissor lines to the original commit messages. Signed-off-by: Werner Koch (cherry picked from commit 0a391b259adcd7ea734dc03c2048a135e018166d) diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c index 2b8b454..6169d14 100644 --- a/cipher/cipher-gcm.c +++ b/cipher/cipher-gcm.c @@ -1,6 +1,6 @@ /* cipher-gcm.c - Generic Galois Counter Mode implementation * Copyright (C) 2013 Dmitry Eremin-Solenikov - * Copyright (C) 2013 Jussi Kivilinna + * Copyright (C) 2013, 2018 Jussi Kivilinna * * This file is part of Libgcrypt. * @@ -556,6 +556,77 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf, } +static gcry_err_code_t +gcm_ctr_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, + const byte *inbuf, size_t inbuflen) +{ + gcry_err_code_t err = 0; + + while (inbuflen) + { + u32 nblocks_to_overflow; + u32 num_ctr_increments; + u32 curr_ctr_low; + size_t currlen = inbuflen; + byte ctr_copy[GCRY_GCM_BLOCK_LEN]; + int fix_ctr = 0; + + /* GCM CTR increments only least significant 32-bits, without carry + * to upper 96-bits of counter. Using generic CTR implementation + * directly would carry 32-bit overflow to upper 96-bit. Detect + * if input length is long enough to cause overflow, and limit + * input length so that CTR overflow happen but updated CTR value is + * not used to encrypt further input. After overflow, upper 96 bits + * of CTR are restored to cancel out modification done by generic CTR + * encryption. */ + + if (inbuflen > c->unused) + { + curr_ctr_low = gcm_add32_be128 (c->u_ctr.ctr, 0); + + /* Number of CTR increments this inbuflen would cause. */ + num_ctr_increments = (inbuflen - c->unused) / GCRY_GCM_BLOCK_LEN + + !!((inbuflen - c->unused) % GCRY_GCM_BLOCK_LEN); + + if ((u32)(num_ctr_increments + curr_ctr_low) < curr_ctr_low) + { + nblocks_to_overflow = 0xffffffffU - curr_ctr_low + 1; + currlen = nblocks_to_overflow * GCRY_GCM_BLOCK_LEN + c->unused; + if (currlen > inbuflen) + { + currlen = inbuflen; + } + + fix_ctr = 1; + buf_cpy(ctr_copy, c->u_ctr.ctr, GCRY_GCM_BLOCK_LEN); + } + } + + err = _gcry_cipher_ctr_encrypt(c, outbuf, outbuflen, inbuf, currlen); + if (err != 0) + return err; + + if (fix_ctr) + { + /* Lower 32-bits of CTR should now be zero. */ + gcry_assert(gcm_add32_be128 (c->u_ctr.ctr, 0) == 0); + + /* Restore upper part of CTR. */ + buf_cpy(c->u_ctr.ctr, ctr_copy, GCRY_GCM_BLOCK_LEN - sizeof(u32)); + + wipememory(ctr_copy, sizeof(ctr_copy)); + } + + inbuflen -= currlen; + inbuf += currlen; + outbuflen -= currlen; + outbuf += currlen; + } + + return err; +} + + gcry_err_code_t _gcry_cipher_gcm_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, @@ -595,7 +666,7 @@ _gcry_cipher_gcm_encrypt (gcry_cipher_hd_t c, return GPG_ERR_INV_LENGTH; } - err = _gcry_cipher_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen); + err = gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen); if (err != 0) return err; @@ -642,7 +713,7 @@ _gcry_cipher_gcm_decrypt (gcry_cipher_hd_t c, do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, inbuf, inbuflen, 0); - return _gcry_cipher_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen); + return gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen); } diff --git a/tests/basic.c b/tests/basic.c index ffb4397..a416095 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1295,7 +1295,8 @@ check_ofb_cipher (void) static void _check_gcm_cipher (unsigned int step) { - struct tv +#define MAX_GCM_DATA_LEN (256 + 32) + static const struct tv { int algo; char key[MAX_DATA_LEN]; @@ -1303,9 +1304,9 @@ _check_gcm_cipher (unsigned int step) int ivlen; unsigned char aad[MAX_DATA_LEN]; int aadlen; - unsigned char plaintext[MAX_DATA_LEN]; + unsigned char plaintext[MAX_GCM_DATA_LEN]; int inlen; - char out[MAX_DATA_LEN]; + char out[MAX_GCM_DATA_LEN]; char tag[MAX_DATA_LEN]; int taglen; int should_fail; @@ -1499,11 +1500,687 @@ _check_gcm_cipher (unsigned int step) "\xee\xb2\xb2\x2a\xaf\xde\x64\x19\xa0\x58\xab\x4f\x6f\x74\x6b\xf4" "\x0f\xc0\xc3\xb7\x80\xf2\x44\x45\x2d\xa3\xeb\xf1\xc5\xd8\x2c\xde" "\xa2\x41\x89\x97\x20\x0e\xf8\x2e\x44\xae\x7e\x3f", - "\xa4\x4a\x82\x66\xee\x1c\x8e\xb0\xc8\xb5\xd4\xcf\x5a\xe9\xf1\x9a" } + "\xa4\x4a\x82\x66\xee\x1c\x8e\xb0\xc8\xb5\xd4\xcf\x5a\xe9\xf1\x9a" }, + /* Test vectors for overflowing CTR. */ + /* After setiv, ctr_low: 0xffffffff */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xdd\x40\xe7", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x7d\x6e\x38\xfd\xd0\x04\x9d\x28\xdf\x4a\x10\x3f\xa3\x9e\xf8\xf8" + "\x6c\x2c\x10\xa7\x91\xab\xc0\x86\xd4\x6d\x69\xea\x58\xc4\xf9\xc0" + "\xd4\xee\xc2\xb0\x9d\x36\xae\xe7\xc9\xa9\x1f\x71\xa8\xee\xa2\x1d" + "\x20\xfd\x79\xc7\xd9\xc4\x90\x51\x38\x97\xb6\x9f\x55\xea\xf3\xf0" + "\x78\xb4\xd3\x8c\xa9\x9b\x32\x7d\x19\x36\x96\xbc\x8e\xab\x80\x9f" + "\x61\x56\xcc\xbd\x3a\x80\xc6\x69\x37\x0a\x89\x89\x21\x82\xb7\x79" + "\x6d\xe9\xb4\x34\xc4\x31\xe0\xbe\x71\xad\xf3\x50\x05\xb2\x61\xab" + "\xb3\x1a\x80\x57\xcf\xe1\x11\x26\xcb\xa9\xd1\xf6\x58\x46\xf1\x69" + "\xa2\xb8\x42\x3c\xe8\x28\x13\xca\x58\xd9\x28\x99\xf8\xc8\x17\x32" + "\x4a\xf9\xb3\x4c\x7a\x47\xad\xe4\x77\x64\xec\x70\xa1\x01\x0b\x88" + "\xe7\x30\x0b\xbd\x66\x25\x39\x1e\x51\x67\xee\xec\xdf\xb8\x24\x5d" + "\x7f\xcb\xee\x7a\x4e\xa9\x93\xf0\xa1\x84\x7b\xfe\x5a\xe3\x86\xb2" + "\xfb\xcd\x39\xe7\x1e\x5e\x48\x65\x4b\x50\x2b\x4a\x99\x46\x3f\x6f" + "\xdb\xd9\x97\xdb\xe5\x6d\xa4\xdd\x6c\x18\x64\x5e\xae\x7e\x2c\xd3" + "\xb4\xf3\x57\x5c\xb5\xf8\x7f\xe5\x87\xb5\x35\xdb\x80\x38\x6e\x2c" + "\x5c\xdd\xeb\x7c\x63\xac\xe4\xb5\x5a\x6a\x40\x6d\x72\x69\x9a\xa9" + "\x8f\x5e\x93\x91\x4d\xce\xeb\x87\xf5\x25\xed\x75\x6b\x3b\x1a\xf2" + "\x0c\xd2\xa4\x10\x45\xd2\x87\xae\x29\x6d\xeb\xea\x66\x5f\xa0\xc2", + "\x8c\x22\xe3\xda\x9d\x94\x8a\xbe\x8a\xbc\x55\x2c\x94\x63\x44\x40" }, + /* After setiv, ctr_low: 0xfffffffe */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xd1\xc1\xdf", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\xac\x6a\x10\x3f\xe2\x8d\xed\x27\x55\x14\xca\x1f\x03\x67\x0a\xa8" + "\xa1\x07\xbf\x00\x73\x5b\x64\xef\xac\x30\x83\x81\x48\x4c\xaa\xd5" + "\xff\xca\xef\x2f\x77\xbe\xfe\x1b\x20\x5c\x86\x19\xc7\xf9\x11\x99" + "\x27\xc5\x57\xa7\x0a\xc2\xa8\x05\xd9\x07\x2b\xb9\x38\xa4\xef\x58" + "\x92\x74\xcf\x89\xc7\xba\xfc\xb9\x70\xac\x86\xe2\x31\xba\x7c\xf9" + "\xc4\xe2\xe0\x4c\x1b\xe4\x3f\x75\x83\x5c\x40\x0e\xa4\x13\x8b\x04" + "\x60\x78\x57\x29\xbb\xe6\x61\x93\xe3\x16\xf9\x58\x07\x75\xd0\x96" + "\xfb\x8f\x6d\x1e\x49\x0f\xd5\x31\x9e\xee\x31\xe6\x0a\x85\x93\x49" + "\x22\xcf\xd6\x1b\x40\x44\x63\x9c\x95\xaf\xf0\x44\x23\x51\x37\x92" + "\x0d\xa0\x22\x37\xb9\x6d\x13\xf9\x78\xba\x27\x27\xed\x08\x7e\x35" + "\xe4\xe2\x28\xeb\x0e\xbe\x3d\xce\x89\x93\x35\x84\x0f\xa0\xf9\x8d" + "\x94\xe9\x5a\xec\xd4\x0d\x1f\x5c\xbe\x6f\x8e\x6a\x4d\x10\x65\xbb" + "\xc7\x0b\xa0\xd5\x5c\x20\x80\x0b\x4a\x43\xa6\xe1\xb0\xe0\x56\x6a" + "\xde\x90\xe0\x6a\x45\xe7\xc2\xd2\x69\x9b\xc6\x62\x11\xe3\x2b\xa5" + "\x45\x98\xb0\x80\xd3\x57\x4d\x1f\x09\x83\x58\xd4\x4d\xa6\xc5\x95" + "\x87\x59\xb0\x58\x6c\x81\x49\xc5\x95\x18\x23\x1b\x6f\x10\x86\xa2" + "\xd9\x56\x19\x30\xec\xd3\x4a\x4b\xe8\x1c\x11\x37\xfb\x31\x60\x4d" + "\x4f\x9b\xc4\x95\xba\xda\x49\x43\x6c\xc7\x3d\x5b\x13\xf9\x91\xf8", + "\xcd\x2b\x83\xd5\x5b\x5a\x8e\x0b\x2e\x77\x0d\x97\xbf\xf7\xaa\xab" }, + /* After setiv, ctr_low: 0xfffffffd */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x8c\x18\x92", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x3d\x6f\x4e\xf6\xd2\x6f\x4e\xce\xa6\xb4\x4a\x9e\xcb\x57\x13\x90" + "\x51\x3b\xf6\xb2\x40\x55\x0c\x2c\xa2\x85\x44\x72\xf2\x90\xaf\x6b" + "\x86\x8c\x75\x2a\x9c\xd6\x52\x50\xee\xc6\x5f\x59\xbc\x8d\x18\xd7" + "\x87\xa5\x7f\xa0\x13\xd1\x5d\x54\x77\x30\xe2\x5d\x1b\x4f\x87\x9f" + "\x3a\x41\xcb\x6a\xdf\x44\x4f\xa2\x1a\xbc\xfb\x4b\x16\x67\xed\x59" + "\x65\xf0\x77\x48\xca\xfd\xf0\xb6\x90\x65\xca\x23\x09\xca\x83\x43" + "\x8f\xf0\x78\xb4\x5f\x96\x2a\xfd\x29\xae\xda\x62\x85\xc5\x87\x4b" + "\x2a\x3f\xba\xbe\x15\x5e\xb0\x4e\x8e\xe7\x66\xae\xb4\x80\x66\x90" + "\x10\x9d\x81\xb9\x64\xd3\x36\x00\xb2\x95\xa8\x7d\xaf\x54\xf8\xbd" + "\x8f\x7a\xb1\xa1\xde\x09\x0d\x10\xc8\x8e\x1e\x18\x2c\x1e\x73\x71" + "\x2f\x1e\xfd\x16\x6e\xbe\xe1\x3e\xe5\xb4\xb5\xbf\x03\x63\xf4\x5a" + "\x0d\xeb\xff\xe0\x61\x80\x67\x51\xb4\xa3\x1f\x18\xa5\xa9\xf1\x9a" + "\xeb\x2a\x7f\x56\xb6\x01\x88\x82\x78\xdb\xec\xb7\x92\xfd\xef\x56" + "\x55\xd3\x72\x35\xcd\xa4\x0d\x19\x6a\xb6\x79\x91\xd5\xcb\x0e\x3b" + "\xfb\xea\xa3\x55\x9f\x77\xfb\x75\xc2\x3e\x09\x02\x73\x7a\xff\x0e" + "\xa5\xf0\x83\x11\xeb\xe7\xff\x3b\xd0\xfd\x7a\x07\x53\x63\x43\x89" + "\xf5\x7b\xc4\x7d\x3b\x2c\x9b\xca\x1c\xf6\xb2\xab\x13\xf5\xc4\x2a" + "\xbf\x46\x77\x3b\x09\xdd\xd1\x80\xef\x55\x11\x3e\xd8\xe4\x42\x22", + "\xa3\x86\xa1\x5f\xe3\x4f\x3b\xed\x12\x23\xeb\x5c\xb8\x0c\xad\x4a" }, + /* After setiv, ctr_low: 0xfffffffc */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xc8\xc3\xaf", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x33\x5f\xdc\x8d\x5d\x77\x7b\x78\xc1\x5b\x7b\xb3\xd9\x08\x9a\x0c" + "\xce\x63\x4e\xef\x19\xf8\x8c\x7a\xcb\x31\x39\x93\x69\x7a\x2c\x97" + "\x3a\xb4\x52\x45\x9e\x7b\x78\xbc\xa9\xad\x54\x7f\x88\xa6\xae\xd5" + "\xc0\x8b\x7a\xe4\x23\x6b\xb2\x29\x98\xea\x25\x7a\xae\x11\x0c\xc9" + "\xf3\x77\xa1\x74\x82\xde\x0c\xec\x68\xce\x94\xfd\xb0\xa0\xc5\x32" + "\xd6\xbb\xc3\xe7\xed\x3c\x6f\x0b\x53\x9d\xf3\xc8\xeb\x4e\xee\x99" + "\x19\xc7\x16\xd1\xa5\x59\x1d\xa9\xd3\xe6\x43\x52\x74\x61\x28\xe6" + "\xac\xd8\x47\x63\xc2\xb7\x53\x39\xc1\x9a\xb0\xa3\xa4\x26\x14\xd0" + "\x88\xa9\x8c\xc5\x6d\xe9\x21\x7c\xb9\xa5\xab\x67\xe3\x8d\xe9\x1d" + "\xe3\x1c\x7b\xcd\xa4\x12\x0c\xd7\xa6\x5d\x41\xcf\xdd\x3d\xfc\xbc" + "\x2a\xbb\xa2\x7a\x9c\x4b\x3a\x42\x6c\x98\x1d\x50\x99\x9c\xfb\xda" + "\x21\x09\x2a\x31\xff\x05\xeb\xa5\xf1\xba\x65\x78\xbe\x15\x8e\x84" + "\x35\xdd\x45\x29\xcc\xcd\x32\x2d\x27\xe9\xa8\x94\x4b\x16\x16\xcc" + "\xab\xf2\xec\xfb\xa0\xb5\x9d\x39\x81\x3e\xec\x5e\x3d\x13\xd1\x83" + "\x04\x79\x2d\xbb\x2c\x76\x76\x93\x28\x77\x27\x13\xdd\x1d\x3e\x89" + "\x3e\x37\x46\x4c\xb8\x34\xbe\xbf\x9f\x4f\x9f\x37\xff\x0c\xe6\x14" + "\x14\x66\x52\x41\x18\xa9\x39\x2b\x0c\xe5\x44\x04\xb0\x93\x06\x64" + "\x67\xf7\xa0\x19\xa7\x61\xcf\x03\x7b\xcb\xc8\xb3\x88\x28\xe4\xe7", + "\xe6\xe8\x0a\xe3\x72\xfc\xe0\x07\x69\x09\xf2\xeb\xbc\xc8\x6a\xf0" }, + /* After setiv, ctr_low: 0xfffffffb */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x95\x1a\xe2", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\xd8\x32\x5a\xe3\x55\x8e\xb3\xc2\x51\x84\x2b\x09\x01\x5e\x6c\xfb" + "\x4a\xc4\x88\xa0\x33\xe7\x3e\xbf\xe5\x7c\xd2\x00\x4c\x1a\x85\x32" + "\x34\xec\x38\x9d\x18\x5f\xf1\x50\x61\x82\xee\xf3\x84\x5a\x84\x4e" + "\xeb\x29\x08\x4c\x7b\xb5\x27\xec\x7d\x79\x77\xd7\xa1\x68\x91\x32" + "\x2d\xf3\x38\xa9\xd6\x27\x16\xfb\x7d\x8b\x09\x5e\xcf\x1b\x74\x6d" + "\xcf\x51\x91\x91\xa1\xe7\x40\x19\x43\x7b\x0d\xa5\xa9\xa5\xf4\x2e" + "\x7f\x1c\xc7\xba\xa2\xea\x00\xdd\x24\x01\xa8\x66\x1e\x88\xf1\xf6" + "\x0c\x9a\xd6\x2b\xda\x3f\x3e\xb2\x98\xea\x89\xc7\xc6\x63\x27\xb7" + "\x6a\x48\x9a\xee\x1e\x70\xa0\xc8\xec\x3d\xc3\x3e\xb5\xf0\xc2\xb1" + "\xb9\x71\x1a\x69\x9d\xdd\x72\x1e\xfe\x72\xa0\x21\xb8\x9f\x18\x96" + "\x26\xcf\x89\x2e\x92\xf1\x02\x65\xa5\xb4\x2e\xb7\x4e\x12\xbd\xa0" + "\x48\xbe\xf6\x5c\xef\x7e\xf3\x0a\xcf\x9d\x1f\x1e\x14\x70\x3e\xa0" + "\x01\x0f\x14\xbf\x38\x10\x3a\x3f\x3f\xc2\x76\xe0\xb0\xe0\x7c\xc6" + "\x77\x6d\x7f\x69\x8e\xa0\x4b\x00\xc3\x9d\xf9\x0b\x7f\x8a\x8e\xd3" + "\x17\x58\x40\xfe\xaf\xf4\x16\x3a\x65\xff\xce\x85\xbb\x80\xfa\xb8" + "\x34\xc9\xef\x3a\xdd\x04\x46\xca\x8f\x70\x48\xbc\x1c\x71\x4d\x6a" + "\x17\x30\x32\x87\x2e\x2e\x54\x9e\x3f\x15\xed\x17\xd7\xa1\xcf\x6c" + "\x5d\x0f\x3c\xee\xf5\x96\xf1\x8f\x68\x1c\xbc\x27\xdc\x10\x3c\x3c", + "\x8c\x31\x06\xbb\xf8\x18\x2d\x9d\xd1\x0d\x03\x56\x2b\x28\x25\x9b" }, + /* After setiv, ctr_low: 0xfffffffa */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x99\x9b\xda", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x7a\x74\x57\xe7\xc1\xb8\x7e\xcf\x91\x98\xf4\x1a\xa4\xdb\x4d\x2c" + "\x6e\xdc\x05\x0b\xd1\x16\xdf\x25\xa8\x1e\x42\xa6\xf9\x09\x36\xfb" + "\x02\x8a\x10\x7d\xa1\x07\x88\x40\xb7\x41\xfd\x64\xf6\xe3\x92\x20" + "\xfd\xc9\xde\xbd\x88\x46\xd3\x1f\x20\x14\x73\x86\x09\xb6\x68\x61" + "\x64\x90\xda\x24\xa8\x0f\x6a\x10\xc5\x01\xbf\x52\x8a\xee\x23\x44" + "\xd5\xb0\xd8\x68\x5e\x77\xc3\x62\xed\xcb\x3c\x1b\x0c\x1f\x13\x92" + "\x2c\x74\x6d\xee\x40\x1b\x6b\xfe\xbe\x3c\xb8\x02\xdd\x24\x9d\xd3" + "\x3d\x4e\xd3\x9b\x18\xfd\xd6\x8f\x95\xef\xa3\xbf\xa9\x2f\x33\xa8" + "\xc2\x37\x69\x58\x92\x42\x3a\x30\x46\x12\x1b\x2c\x04\xf0\xbf\xa9" + "\x79\x55\xcd\xac\x45\x36\x79\xc0\xb4\xb2\x5f\x82\x88\x49\xe8\xa3" + "\xbf\x33\x41\x7a\xcb\xc4\x11\x0e\xcc\x61\xed\xd1\x6b\x59\x5f\x9d" + "\x20\x6f\x85\x01\xd0\x16\x2a\x51\x1b\x79\x35\x42\x5e\x49\xdf\x6f" + "\x64\x68\x31\xac\x49\x34\xfb\x2b\xbd\xb1\xd9\x12\x4e\x4b\x16\xc5" + "\xa6\xfe\x15\xd3\xaf\xac\x51\x08\x95\x1f\x8c\xd2\x52\x37\x8b\x88" + "\xf3\x20\xe2\xf7\x09\x55\x82\x83\x1c\x38\x5f\x17\xfc\x37\x26\x21" + "\xb8\xf1\xfe\xa9\xac\x54\x1e\x53\x83\x53\x3f\x43\xe4\x67\x22\xd5" + "\x86\xec\xf2\xb6\x4a\x8b\x8a\x66\xea\xe0\x92\x50\x3b\x51\xe4\x00" + "\x25\x2a\x7a\x64\x14\xd6\x09\xe1\x6c\x75\x32\x28\x53\x5e\xb3\xab", + "\x5d\x4b\xb2\x8f\xfe\xa5\x7f\x01\x6d\x78\x6c\x13\x58\x08\xe4\x94" }, + /* After setiv, ctr_low: 0xfffffff9 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xc4\x42\x97", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\xf5\xc1\xed\xb8\x7f\x55\x7b\xb5\x47\xed\xaa\x42\xd2\xda\x33\x41" + "\x4a\xe0\x36\x6d\x51\x28\x40\x9c\x35\xfb\x11\x65\x18\x83\x9c\xb5" + "\x02\xb2\xa7\xe5\x52\x27\xa4\xe8\x57\x3d\xb3\xf5\xea\xcb\x21\x07" + "\x67\xbe\xbe\x0f\xf6\xaa\x32\xa1\x4b\x5e\x79\x4f\x50\x67\xcd\x80" + "\xfc\xf1\x65\xf2\x6c\xd0\xdb\x17\xcc\xf9\x52\x93\xfd\x5e\xa6\xb9" + "\x5c\x9f\xa8\xc6\x36\xb7\x80\x80\x6a\xea\x62\xdc\x61\x13\x45\xbe" + "\xab\x8f\xd8\x99\x17\x51\x9b\x29\x04\x6e\xdb\x3e\x9f\x83\xc6\x35" + "\xb3\x90\xce\xcc\x74\xec\xcb\x04\x41\xac\xb1\x92\xde\x20\xb1\x67" + "\xb0\x38\x14\xaa\x7d\xee\x3c\xb2\xd3\xbb\x2f\x88\x0b\x73\xcf\x7b" + "\x69\xc1\x55\x5b\x2b\xf2\xd4\x38\x2b\x3c\xef\x04\xc9\x14\x7c\x31" + "\xd6\x61\x88\xa8\xb3\x8c\x69\xb4\xbc\xaa\x0d\x15\xd2\xd5\x27\x63" + "\xc4\xa4\x80\xe9\x2b\xe9\xd2\x34\xc9\x0e\x3f\x7b\xd3\x43\x0d\x47" + "\x5d\x37\x8e\x42\xa4\x4e\xef\xcd\xbb\x3a\x5b\xa4\xe1\xb0\x8d\x64" + "\xb7\x0b\x58\x52\xec\x55\xd0\xef\x23\xfe\xf2\x8d\xe0\xd1\x6a\x2c" + "\xaa\x1c\x03\xc7\x3e\x58\x4c\x61\x72\x07\xc6\xfd\x0e\xbc\xd4\x6b" + "\x99\x4f\x91\xda\xff\x6f\xea\x81\x0c\x76\x85\x5d\x0c\x7f\x1c\xb8" + "\x84\x8c\x2f\xe1\x36\x3e\x68\xa0\x57\xf5\xdf\x13\x0a\xd6\xe1\xcd" + "\xae\x23\x99\x4e\xed\x7a\x72\x1b\x7c\xe5\x65\xd1\xb7\xcf\x2f\x73", + "\x1e\x2f\xcf\x3c\x95\x9a\x29\xec\xd3\x37\x90\x8c\x84\x8a\xfb\x95" }, + /* After setiv, ctr_low: 0xfffffff8 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xfa\xc7\x4f", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x14\x33\xc6\x9d\x04\xd3\x48\x29\x0c\x6a\x24\x27\xdf\x5f\x0a\xd2" + "\x71\xd6\xd0\x18\x04\xc0\x9f\x72\x0a\x60\xb7\x10\x52\x56\xf7\xae" + "\x64\xb0\x28\xd4\xfd\x25\x93\x8e\x67\x7e\xac\xc2\x93\xc7\x54\x2e" + "\x82\x93\x88\x6a\xb9\x8b\x73\xbc\x88\xec\x27\xdd\x4f\x9b\x21\x9e" + "\x77\x98\x70\x0b\xf4\xd8\x55\xfe\xf4\xc3\x3a\xcb\xca\x3a\xfb\xd4" + "\x52\x72\x2f\xf8\xac\xa9\x6a\xf5\x13\xab\x7a\x2e\x9f\x52\x41\xbd" + "\x87\x90\x68\xad\x17\xbd\x5a\xff\xc3\xc6\x10\x4d\xc1\xfe\xfc\x72" + "\x21\xb5\x53\x4a\x3f\xe0\x15\x9f\x29\x36\x23\xc0\x9a\x31\xb2\x0f" + "\xcd\x2f\xa6\xd0\xfc\xe6\x4d\xed\x68\xb3\x3d\x26\x67\xab\x40\xf0" + "\xab\xcf\x72\xc0\x50\xb1\x1e\x86\x38\xe2\xe0\x46\x3a\x2e\x3e\x1d" + "\x07\xd6\x9d\xe8\xfc\xa3\xe7\xac\xc9\xa0\xb3\x22\x05\xbc\xbf\xd2" + "\x63\x44\x66\xfc\xb4\x7b\xb4\x70\x7e\x96\xa9\x16\x1b\xb2\x7d\x93" + "\x44\x92\x5e\xbd\x16\x34\xa7\x11\xd0\xdf\x52\xad\x6f\xbd\x23\x3c" + "\x3d\x58\x16\xaf\x99\x8b\xbb\xa0\xdc\x3a\xff\x17\xda\x56\xba\x77" + "\xae\xc4\xb1\x51\xe2\x61\x4f\xf0\x66\x1b\x4c\xac\x79\x34\x1c\xfd" + "\x6c\x5f\x9a\x2c\x60\xfc\x47\x00\x5f\x2d\x81\xcc\xa9\xdd\x2b\xf4" + "\x5b\x53\x44\x61\xd4\x13\x5a\xf3\x93\xf0\xc9\x24\xd4\xe6\x60\x6f" + "\x78\x02\x0c\x75\x9d\x0d\x23\x97\x35\xe2\x06\x8a\x49\x5e\xe5\xbe", + "\x23\xc0\x4a\x2f\x98\x93\xca\xbd\x2e\x44\xde\x05\xcc\xe7\xf1\xf5" }, + /* After setiv, ctr_low: 0xfffffff7 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4c\xa7\x1e\x02", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x51\x51\x64\x89\xeb\x9f\xf9\xd6\xb1\xa6\x73\x5f\xf1\x62\xb5\xe4" + "\x00\x80\xdb\x4c\x1c\xce\xe5\x00\xeb\xea\x6c\x57\xe4\x27\xfc\x71" + "\x08\x8c\xa1\xfc\x59\x1d\x07\x45\x3c\xc9\x4e\x0f\xb6\xea\x96\x90" + "\xae\xf7\x81\x1e\x7e\x6c\x5e\x50\xaf\x34\x3e\xa0\x55\x59\x8e\xe7" + "\xc1\xba\x48\xfa\x9e\x07\xf6\x6a\x24\x54\x3e\x9b\xa5\xfe\x31\x16" + "\x3d\x4d\x9c\xc4\xe1\xec\x26\xa0\x8b\x59\xa6\xf3\x94\xf8\x88\xda" + "\x1f\x88\x23\x5f\xfb\xfd\x79\xa2\xd3\x62\x30\x66\x69\xd9\x0d\x05" + "\xc0\x75\x4c\xb8\x48\x34\x1d\x97\xcf\x29\x6a\x12\x1c\x26\x54\x1d" + "\x80\xa9\x06\x74\x86\xff\xc6\xb4\x72\xee\x34\xe2\x56\x06\x6c\xf5" + "\x11\xe7\x26\x71\x47\x6b\x05\xbd\xe4\x0b\x40\x78\x84\x3c\xf9\xf2" + "\x78\x34\x2b\x3c\x5f\x0e\x4c\xfb\x17\x39\xdc\x59\x6b\xd1\x56\xac" + "\xe4\x1f\xb9\x19\xbc\xec\xb1\xd0\x6d\x47\x3b\x37\x4d\x0d\x6b\x65" + "\x7c\x70\xe9\xec\x58\xcc\x09\xd4\xd9\xbf\x9f\xe0\x6c\x7f\x60\x28" + "\xd8\xdf\x8e\xd1\x6a\x73\x42\xf3\x50\x01\x79\x68\x41\xc3\xba\x19" + "\x1e\x2d\x30\xc2\x81\x2c\x9f\x11\x8b\xd0\xdc\x31\x3b\x01\xfe\x53" + "\xa5\x11\x13\x22\x89\x40\xb9\x1b\x12\x89\xef\x9a\xcb\xa8\x03\x4f" + "\x54\x1a\x15\x6d\x11\xba\x05\x09\xd3\xdb\xbf\x05\x42\x3a\x5a\x27" + "\x3b\x34\x5c\x58\x8a\x5c\xa4\xc2\x28\xdc\xb2\x3a\xe9\x99\x01\xd6", + "\x30\xb2\xb5\x11\x8a\x3a\x8d\x70\x67\x71\x14\xde\xed\xa7\x43\xb5" }, + /* After setiv, ctr_low: 0xfffffff6 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\xab\x9f\x3a", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x05\x72\x44\xa0\x99\x11\x1d\x2c\x4b\x03\x4f\x20\x92\x88\xbe\x55" + "\xee\x31\x2c\xd9\xc0\xc1\x64\x77\x79\xd7\x3e\xfa\x5a\x7d\xf0\x48" + "\xf8\xc8\xfe\x81\x8f\x89\x92\xa6\xc2\x07\xdc\x9f\x3f\xb2\xc8\xf2" + "\xf3\xe9\xe1\xd3\xed\x55\xb4\xab\xc3\x22\xed\x8f\x00\xde\x32\x95" + "\x91\xc0\xc5\xf3\xd3\x93\xf0\xee\x56\x14\x8f\x96\xff\xd0\x6a\xbd" + "\xfc\x57\xc2\xc3\x7b\xc1\x1d\x56\x48\x3f\xa6\xc7\x92\x47\xf7\x2f" + "\x0b\x85\x1c\xff\x87\x29\xe1\xbb\x9b\x14\x6c\xac\x51\x0a\xc0\x7b" + "\x22\x25\xb0\x48\x92\xad\x09\x09\x6e\x39\x8e\x96\x13\x05\x55\x92" + "\xbd\xd7\x5d\x95\x35\xdd\x8a\x9d\x05\x59\x60\xae\xbb\xc0\x85\x92" + "\x4c\x8b\xa0\x3f\xa2\x4a\xe5\x2e\xde\x85\x1a\x39\x10\x22\x11\x1b" + "\xdd\xcc\x96\xf4\x93\x97\xf5\x81\x85\xf3\x33\xda\xa1\x9a\xba\xfd" + "\xb8\xaf\x60\x81\x37\xf1\x02\x88\x54\x15\xeb\x21\xd1\x19\x1a\x1f" + "\x28\x9f\x02\x27\xca\xce\x97\xda\xdc\xd2\x0f\xc5\x0e\x2e\xdd\x4f" + "\x1d\x24\x62\xe4\x6e\x4a\xbe\x96\x95\x38\x0c\xe9\x26\x14\xf3\xf0" + "\x92\xbc\x97\xdc\x38\xeb\x64\xc3\x04\xc1\xa2\x6c\xad\xbd\xf8\x03" + "\xa0\xa4\x68\xaa\x9d\x1f\x09\xe6\x62\x95\xa2\x1c\x32\xef\x62\x28" + "\x7e\x54\x6d\x4b\x6a\xcc\x4a\xd0\x82\x47\x46\x0d\x45\x3c\x36\x03" + "\x86\x90\x44\x65\x18\xac\x19\x75\xe6\xba\xb1\x9a\xb4\x5d\x84\x9b", + "\x31\x22\x2b\x11\x6e\x2b\x94\x56\x37\x9d\xc3\xa5\xde\xe7\x6e\xc9" }, + /* After setiv, ctr_low: 0xfffffff5 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xf6\x46\x77", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x6e\x32\xdb\x04\x32\x57\x15\x78\x0e\x4c\x70\x66\x5c\x91\x43\x0c" + "\x63\x73\xb8\x86\xad\xb0\xf1\x34\x0f\x0c\x7e\xd3\x4e\xcb\xc9\xea" + "\x19\x3c\xb8\x14\xd0\xab\x9e\x9b\x22\xda\x7a\x96\xa7\xf5\xa2\x99" + "\x58\xe3\xd6\x72\x0f\xf5\xdf\x88\xd1\x33\xb1\xe5\x03\x72\x62\x1c" + "\xa7\xf2\x67\x50\x0e\x70\xc3\x7a\x6c\x4a\x90\xba\x78\x9e\xd2\x0b" + "\x29\xd4\xc8\xa7\x57\x06\xf2\xf4\x01\x4b\x30\x53\xea\xf7\xde\xbf" + "\x1c\x12\x03\xcf\x9f\xcf\x80\x8b\x77\xfd\x73\x48\x79\x19\xbe\x38" + "\x75\x0b\x6d\x78\x7d\x79\x05\x98\x65\x3b\x35\x8f\x68\xff\x30\x7a" + "\x6e\xf7\x10\x9e\x11\x25\xc4\x95\x97\x7d\x92\x0f\xbf\x38\x95\xbd" + "\x5d\x2a\xf2\x06\x2c\xd9\x5a\x80\x91\x4e\x22\x7d\x5f\x69\x85\x03" + "\xa7\x5d\xda\x22\x09\x2b\x8d\x29\x67\x7c\x8c\xf6\xb6\x49\x20\x63" + "\xb9\xb6\x4d\xb6\x37\xa3\x7b\x19\xa4\x28\x90\x83\x55\x3d\x4e\x18" + "\xc8\x65\xbc\xd1\xe7\xb5\xcf\x65\x28\xea\x19\x11\x5c\xea\x83\x8c" + "\x44\x1f\xac\xc5\xf5\x3a\x4b\x1c\x2b\xbf\x76\xd8\x98\xdb\x50\xeb" + "\x64\x45\xae\xa5\x39\xb7\xc8\xdf\x5a\x73\x6d\x2d\x0f\x4a\x5a\x17" + "\x37\x66\x1c\x3d\x27\xd5\xd6\x7d\xe1\x08\x7f\xba\x4d\x43\xc2\x29" + "\xf7\xbe\x83\xec\xd0\x3b\x2e\x19\x9e\xf7\xbf\x1b\x16\x34\xd8\xfa" + "\x32\x17\x2a\x90\x55\x93\xd5\x3e\x14\x8d\xd6\xa1\x40\x45\x09\x52", + "\x89\xf2\xae\x78\x38\x8e\xf2\xd2\x52\xa8\xba\xb6\xf2\x5d\x7c\xfc" }, + /* After setiv, ctr_low: 0xfffffff4 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\xb2\x9d\x4a", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x1d\xb8\x77\xcd\xcd\xfe\xde\x07\x97\xcb\x97\x3a\x4f\xa0\xd0\xe6" + "\xcc\xcf\x8b\x71\xd5\x65\x3d\xc4\x17\x52\xe7\x1d\x6a\x68\x4a\x77" + "\xca\x04\x4a\xef\x8e\x7e\xce\x79\xa1\x80\x0d\x9e\xd5\xf4\xce\x66" + "\x4d\x54\xb1\x09\xd1\xb6\xb0\x43\x28\xe8\x53\xe2\x24\x9c\x76\xc5" + "\x4d\x22\xf3\x6e\x13\xf3\xd7\xe0\x85\xb8\x9e\x0b\x17\x22\xc0\x79" + "\x2b\x72\x57\xaa\xbd\x43\xc3\xf7\xde\xce\x22\x41\x3c\x7e\x37\x1a" + "\x55\x2e\x36\x0e\x7e\xdc\xb3\xde\xd7\x33\x36\xc9\xc8\x56\x93\x51" + "\x68\x77\x9a\xb0\x08\x5c\x22\x35\xef\x5c\x9b\xbf\x3e\x20\x8a\x84" + "\x3d\xb3\x60\x10\xe1\x97\x30\xd7\xb3\x6f\x40\x5a\x2c\xe0\xe5\x52" + "\x19\xb6\x2b\xed\x6e\x8e\x18\xb4\x8d\x78\xbd\xc4\x9f\x4f\xbd\x82" + "\x98\xd6\x71\x3d\x71\x5b\x78\x73\xee\x8e\x4b\x37\x88\x9e\x21\xca" + "\x00\x6c\xc2\x96\x8d\xf0\xcd\x09\x58\x54\x5a\x58\x59\x8e\x9b\xf8" + "\x72\x93\xd7\xa0\xf9\xc4\xdc\x48\x89\xaa\x31\x95\xda\x4e\x2f\x79" + "\x1e\x37\x49\x92\x2e\x32\x2e\x76\x54\x2a\x64\xa8\x96\x67\xe9\x75" + "\x10\xa6\xeb\xad\xc6\xa8\xec\xb7\x18\x0a\x32\x26\x8d\x6e\x03\x74" + "\x0e\x1f\xfc\xde\x76\xff\x6e\x96\x42\x2d\x80\x0a\xc6\x78\x70\xc4" + "\xd8\x56\x7b\xa6\x38\x2f\xf6\xc0\x9b\xd7\x21\x6e\x88\x5d\xc8\xe5" + "\x02\x6a\x09\x1e\xb3\x46\x44\x80\x82\x5b\xd1\x66\x06\x61\x4f\xb8", + "\x16\x0e\x73\xa3\x14\x43\xdb\x15\x9c\xb0\x0d\x30\x6d\x9b\xe1\xb1" }, + /* After setiv, ctr_low: 0xfffffff3 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xef\x44\x07", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x42\x71\x54\xe2\xdb\x50\x5d\x3c\x10\xbd\xf8\x60\xbd\xdb\x26\x14" + "\x7d\x13\x59\x98\x28\xfb\x43\x42\xca\x72\xe6\xd8\x58\x00\xa2\x1b" + "\x6a\x61\xb4\x3a\x80\x6b\x9e\x14\xbd\x11\x33\xab\xe9\xb9\x91\x95" + "\xd7\x5d\xc3\x98\x1f\x7f\xcb\xa8\xf0\xec\x31\x26\x51\xea\x2e\xdf" + "\xd9\xde\x70\xf5\x84\x27\x3a\xac\x22\x05\xb9\xce\x2a\xfb\x2a\x83" + "\x1e\xce\x0e\xb2\x31\x35\xc6\xe6\xc0\xd7\xb0\x5f\xf5\xca\xdb\x13" + "\xa7\xfe\x4f\x85\xa3\x4f\x94\x5c\xc1\x04\x12\xde\x6f\xa1\xdb\x41" + "\x59\x82\x22\x22\x65\x97\x6d\xc8\x67\xab\xf3\x90\xeb\xa4\x00\xb3" + "\x7d\x94\x3d\x7b\x2a\xe2\x85\x36\x87\x16\xb8\x19\x92\x02\xe0\x43" + "\x42\x85\xa1\xe6\xb8\x11\x30\xcc\x2c\xd8\x63\x09\x0e\x53\x5f\xa3" + "\xe0\xd4\xee\x0e\x04\xee\x65\x61\x96\x84\x42\x0c\x68\x8d\xb7\x48" + "\xa3\x02\xb4\x82\x69\xf2\x35\xe4\xce\x3b\xe3\x44\xce\xad\x49\x32" + "\xab\xda\x04\xea\x06\x60\xa6\x2a\x7d\xee\x0f\xb8\x95\x90\x22\x62" + "\x9c\x78\x59\xd3\x7b\x61\x02\x65\x63\x96\x9f\x67\x50\xa0\x61\x43" + "\x53\xb2\x3f\x22\xed\x8c\x42\x39\x97\xd9\xbc\x6e\x81\xb9\x21\x97" + "\xc6\x5b\x68\xd7\x7f\xd0\xc5\x4a\xfb\x74\xc4\xfd\x9a\x2a\xb8\x9b" + "\x48\xe0\x00\xea\x6d\xf5\x30\x26\x61\x8f\xa5\x45\x70\xc9\x3a\xea" + "\x6d\x19\x11\x57\x0f\x21\xe6\x0a\x53\x94\xe3\x0c\x99\xb0\x2f\xc5", + "\x92\x92\x89\xcd\x4f\x3c\x6d\xbc\xe8\xb3\x70\x14\x5b\x3c\x12\xe4" }, + /* After setiv, ctr_low: 0xfffffff2 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xe3\xc5\x3f", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\x41\xc3\xcb\xd7\x6e\xde\x2a\xc6\x15\x05\xc6\xba\x27\xae\xcd\x37" + "\xc0\xe5\xbf\xb9\x5c\xdc\xd6\xad\x1a\xe1\x35\x7c\xc0\x85\x85\x51" + "\x8c\x98\x06\xc0\x72\x43\x71\x7a\x2d\x7c\x81\x3c\xe7\xd6\x32\x8e" + "\x22\x2b\x46\x95\x6a\xde\x45\x40\x56\xe9\x63\x32\x68\xbf\xb6\x78" + "\xb7\x86\x00\x9d\x2c\x9e\xed\x67\xc1\x9b\x09\x9e\xd9\x0a\x56\xcb" + "\x57\xc9\x48\x14\x23\x4e\x97\x04\xb5\x85\x25\x1d\xcb\x1a\x79\x9b" + "\x54\x06\x95\xad\x16\x81\x84\x3a\x38\xec\x41\x90\x2a\xfa\x50\xe0" + "\xb9\x20\xa6\xeb\xfe\x2e\x5c\xa1\xf6\x3c\x69\x4c\xce\xf8\x30\xe0" + "\x87\x68\xa2\x3a\x9d\xad\x75\xd4\xa5\x6b\x0a\x90\x65\xa2\x27\x64" + "\x9d\xf5\xa0\x6f\xd0\xd3\x62\xa5\x2d\xae\x02\x89\xb4\x1a\xfa\x32" + "\x9b\xa0\x44\xdd\x50\xde\xaf\x41\xa9\x89\x1e\xb0\x41\xbc\x9c\x41" + "\xb0\x35\x5e\xf1\x9a\xd9\xab\x57\x53\x21\xca\x39\xfc\x8b\xb4\xd4" + "\xb2\x19\x8a\xe9\xb2\x24\x1e\xce\x2e\x19\xb0\xd2\x93\x30\xc4\x70" + "\xe2\xf8\x6a\x8a\x99\x3b\xed\x71\x7e\x9e\x98\x99\x2a\xc6\xdd\xcf" + "\x43\x32\xdb\xfb\x27\x22\x89\xa4\xc5\xe0\xa2\x94\xe9\xcf\x9d\x48" + "\xab\x3f\xfa\x4f\x75\x63\x46\xdd\xfe\xfa\xf0\xbf\x6e\xa1\xf9\xca" + "\xb1\x77\x79\x35\x6c\x33\xe1\x57\x68\x50\xe9\x78\x4e\xe4\xe2\xf0" + "\xcf\xe4\x23\xde\xf4\xa7\x34\xb3\x44\x97\x38\xd2\xbd\x27\x44\x0e", + "\x75\x0a\x41\x3b\x87\xe3\xc7\xf6\xd6\xe3\xab\xfa\x4b\xbe\x2e\x56" }, + /* After setiv, ctr_low: 0xfffffff1 */ + { GCRY_CIPHER_AES256, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5a\xbe\x1c\x72", + 16, + "", 0, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 288, + "\xf1\x3c\x7a\xa4\xa9\xaf\xe7\x49\x19\x7d\xad\x50\xc1\x6a\x84\x87" + "\xf5\x69\xe4\xe5\xc2\x0a\x90\x33\xc3\xeb\x76\x63\x5f\x9b\x1d\xf9" + "\x53\x4a\x2a\x6d\x6b\x61\xe0\x5d\xed\xcb\x98\x0d\xf2\x57\x33\x12" + "\xd1\x44\xaa\x7a\x7e\x4e\x41\x0e\xe6\xa7\x9f\x17\x92\x28\x91\xad" + "\xca\xce\xf2\xa8\x73\x4a\xad\x89\x62\x73\x0b\x9a\x68\x91\xa8\x11" + "\x44\x01\xfd\x57\xe4\xf8\x84\x55\x2b\x66\xdb\xb9\xd6\xee\x83\xe5" + "\x57\xea\x5c\x6a\x23\x87\xdd\x0a\x45\x63\xb4\x0c\x8f\xc5\x9f\x22" + "\xf3\x4f\x4e\x6f\x7b\x14\x62\xf7\x80\x59\x4a\xc5\xc8\xae\x8a\x6f" + "\x5e\xe3\x1e\xe6\xae\xec\x99\x77\x6b\x88\x14\xe3\x58\x88\x61\x74" + "\x38\x91\xa1\x32\xb8\xd2\x39\x6b\xe2\xcb\x8e\x77\xde\x92\x36\x78" + "\xad\x50\xcf\x08\xb8\xfa\x29\x59\xb4\x68\x1b\x23\x10\x57\x32\x92" + "\xf8\xec\xe1\x97\xdb\x30\x85\x22\xb5\x68\x2f\xf2\x98\xda\x06\xee" + "\x65\x02\xe7\xf9\xc8\xc1\xca\x8f\xd3\xed\x4a\x3c\x09\xdd\xde\x64" + "\xd9\x85\x17\x2c\x62\x41\x35\x24\xed\x6b\x87\x78\x1e\xb5\x7a\x9b" + "\xa3\x90\xa3\x99\xc7\x39\x51\x10\xb7\x6a\x12\x3b\x64\xfe\x32\x3c" + "\xb6\x84\x9a\x3f\x95\xd3\xcb\x22\x69\x9c\xf9\xb7\xc2\x8b\xf4\x55" + "\x68\x60\x11\x20\xc5\x3e\x0a\xc0\xba\x00\x0e\x88\x96\x66\xfa\xf0" + "\x75\xbc\x2b\x9c\xff\xc5\x33\x7b\xaf\xb2\xa6\x34\x78\x44\x9c\xa7", + "\x01\x24\x0e\x17\x17\xe5\xfc\x90\x07\xfa\x78\xd5\x5d\x66\xa3\xf5" }, }; gcry_cipher_hd_t hde, hdd; - unsigned char out[MAX_DATA_LEN]; + unsigned char out[MAX_GCM_DATA_LEN]; unsigned char tag[GCRY_GCM_BLOCK_LEN]; int i, keylen; gcry_error_t err = 0; @@ -1833,8 +2510,12 @@ check_gcm_cipher (void) _check_gcm_cipher(1); /* Split input to 7 byte buffers. */ _check_gcm_cipher(7); + /* Split input to 15 byte buffers. */ + _check_gcm_cipher(15); /* Split input to 16 byte buffers. */ _check_gcm_cipher(16); + /* Split input to 17 byte buffers. */ + _check_gcm_cipher(17); } commit 6dd0cf0744db29ef0d86830dd70f14381f0a5f56 Author: Werner Koch Date: Wed Jun 13 10:14:27 2018 +0200 ecc: Improve gcry_mpi_ec_curve_point * mpi/ec.c (_gcry_mpi_ec_curve_point): Check range of coordinates. * tests/t-mpi-point.c (point_on_curve): New. -- Due to the conversion to affine coordinates we didn't detected points with values >= P. The solution here might not be the best according to the NIST standard (it is done there at an earlier opportunity) but it reliably detects points we do not expect to receive. The new test vectors have been compared against gnutls/nettle. Reported-by: Stephan M?ller Signed-off-by: Werner Koch (cherry picked from commit 7b6c2afd699e889f5f054cc3d202a61bd0ee1dcf) (cherry picked from commit 846f8fe8b3be6d235592db184361df1bc2b07a8a) Solved two minor merge conflicts in t-mpi-point diff --git a/mpi/ec.c b/mpi/ec.c index 1469339..a7ab3a0 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1504,6 +1504,15 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) y = mpi_new (0); w = mpi_new (0); + /* Check that the point is in range. This needs to be done here and + * not after conversion to affine coordinates. */ + if (mpi_cmpabs (point->x, ctx->p) >= 0) + goto leave; + if (mpi_cmpabs (point->y, ctx->p) >= 0) + goto leave; + if (mpi_cmpabs (point->z, ctx->p) >= 0) + goto leave; + switch (ctx->model) { case MPI_EC_WEIERSTRASS: diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 84da7cc..79c9aca 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -30,6 +30,10 @@ #define PGM "t-mpi-point" +#ifndef DIM +# define DIM(v) (sizeof(v)/sizeof((v)[0])) +#endif + static const char *wherestr; static int verbose; static int debug; @@ -1095,6 +1099,271 @@ twistededwards_math (void) } +/* Check the point on curve function. */ +static void +point_on_curve (void) +{ + static struct { + const char *curve; + int oncurve; /* Point below is on the curve. */ + const char *qx; + const char *qy; + } t[] = { + { + "NIST P-256", 0, + "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974", + "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3" + }, { + "NIST P-256", 0, + "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651", + "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D" + }, { + "NIST P-256", 0, + "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291", + "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023" + }, { + "NIST P-256", 1, + "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B", + "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63" + }, { + "NIST P-256", 0, + "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53", + "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600" + }, { + "NIST P-256", 1, + "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36", + "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E" + }, { + "NIST P-256", 0, + "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990", + "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E" + }, { + "NIST P-256", 1, + "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE", + "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D" + }, { + "NIST P-256", 1, + "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945", + "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63" + }, { + "NIST P-256", 0, + "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84", + "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F" + }, { + "NIST P-256", 0, + "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC", + "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902" + }, { + "NIST P-256", 0, + "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C", + "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0" + } , { + "NIST P-384", 0, + "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00" + "83EC46A8F2FF3203C5C7F8C7E722A5EF", + "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922" + "96470753DCF46173C9AA4A8A4C2FBE51" + }, { + "NIST P-384", 0, + "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752" + "02CE06CCBE705EA8A38AA2894D4BEEE6", + "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F" + "8E0875F4C4BB1E3D0F8535C7A52306FB82" + }, { + "NIST P-384", 1, + "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23" + "D719ED4116E2CC907AEB92CF22331A60", + "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E" + "9FC63F61EF19DE9B3CEA98D163ABF254" + }, { + "NIST P-384", 0, + "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24" + "EC2F0CA62FF1F90B6515DE356EC2A404", + "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692" + "72F4D3A87E88529754E109BB9B61B03B" + }, { + "NIST P-384", 0, + "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2" + "9A440AD51C94CF5BC28817C8C6E2D302", + "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1" + "8306976291F3ADC0B5ABA42DED376EA9A5" + }, { + "NIST P-384", 0, + "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03" + "B958BF28B022E54E320672C4BAD4EEC0", + "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA" + "9E558E9F58ED1D324C9DCBCB4E8F2A5970" + }, { + "NIST P-384", 0, + "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293" + "18BCB9FC60499D009F949298F3F9F47B", + "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86" + "CFE9C552E2E720F5DA5806503D3784CD" + }, { + "NIST P-384", 0, + "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20" + "823CA8F84D2BBF4EA687885437DE7839", + "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1" + "69F3656C322DE45C4A70DC6DB9A661E599" + }, { + "NIST P-384", 1, + "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3" + "89B92C9A55573A596123415FBFA26991", + "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B" + "F3B04F46DBFFE08151E0F0950CC70081" + }, { + "NIST P-384", 0, + "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB" + "4C0F876575DDEC1BDB3F3F04061C9AE4", + "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352" + "D7BBEEFB803F6CC8FC7895E47F348D33" + }, { + "NIST P-384", 1, + "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36" + "F1D8325E45734D5A0FDD103F4DF6F83E", + "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B" + "F26E8D87EC175577E782AD51A6A12C02" + }, { + "NIST P-384", 1, + "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C" + "187BECA23369DFD6C15CC0DA0629958F", + "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB" + "73DE6AA96140B5C457B7486E06D318CE" + }, { + "NIST P-521", 0, + "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024" + "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70", + "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90" + "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0" + }, { + "NIST P-521", 0, + "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437" + "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3", + "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D" + "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48" + }, { + "NIST P-521", 1, + "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4" + "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8", + "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE" + "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97" + }, { + "NIST P-521", 0, + "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E" + "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D", + "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5" + "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF" + }, { + "NIST P-521", 0, + "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489" + "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117", + "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E" + "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD" + }, { + "NIST P-521", 1, + "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55" + "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56", + "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B" + "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004" + }, { + "NIST P-521", 0, + "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A" + "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023", + "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C" + "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291" + }, { + "NIST P-521", 0, + "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86" + "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE", + "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125" + "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4" + }, { + "NIST P-521", 0, + "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1" + "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03", + "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF" + "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89" + }, { + "NIST P-521", 0, + "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9" + "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93", + "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B" + "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B" + }, { + "NIST P-521", 1, + "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056" + "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C", + "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901" + "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080" + }, { + "NIST P-521", 1, + "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5" + "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1", + "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635" + "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9" + } + }; + gpg_error_t err; + int tidx; + const char *lastcurve = NULL; + gcry_ctx_t ctx = NULL; + gcry_mpi_t qx = NULL; + gcry_mpi_t qy = NULL; + gcry_mpi_point_t Q; + int oncurve; + + wherestr = "point_on_curve"; + for (tidx=0; tidx < DIM (t); tidx++) + { + if (!t[tidx].curve) + { + if (!lastcurve || !ctx) + die ("invalid test vectors at idx %d\n", tidx); + } + else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve)) + { + lastcurve = t[tidx].curve; + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, NULL, lastcurve); + if (err) + die ("error creating context for curve %s at idx %d: %s\n", + lastcurve, tidx, gpg_strerror (err)); + + /*info ("checking points on curve %s\n", lastcurve);*/ + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + qx = hex2mpi (t[tidx].qx); + qy = hex2mpi (t[tidx].qy); + + Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE); + if (!Q) + die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx); + + oncurve = gcry_mpi_ec_curve_point (Q, ctx); + + if (t[tidx].oncurve && !oncurve) + { + fail ("point expected on curve but not identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + else if (!t[tidx].oncurve && oncurve) + { + fail ("point not expected on curve but identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + gcry_mpi_point_release (Q); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + gcry_ctx_release (ctx); +} + + int main (int argc, char **argv) { @@ -1117,6 +1386,7 @@ main (int argc, char **argv) context_alloc (); context_param (); basic_ec_math (); + point_on_curve (); /* The tests are for P-192 and ed25519 which are not supported in FIPS mode. */ commit 3600e1224f6c89b3e637bdf1cf527ecc9a69afeb Author: Werner Koch Date: Tue Jun 5 14:29:53 2018 +0200 mpi: New internal function _gcry_mpi_cmpabs. * mpi/mpi-cmp.c (_gcry_mpi_cmp): Factor out to ... (do_mpi_cmp): New. Add arg absmode. (_gcry_mpi_cmpabs): New. * src/gcrypt-int.h (mpi_cmpabs): New macro. Signed-off-by: Werner Koch (cherry picked from commit 6606ae44e0de1069b29dd4215ee9748280940e1b) (cherry picked from commit 54620a27f4503e703e219e6e11c4be14ce4e3d35) diff --git a/mpi/mpi-cmp.c b/mpi/mpi-cmp.c index 838a7c9..66e0961 100644 --- a/mpi/mpi-cmp.c +++ b/mpi/mpi-cmp.c @@ -54,15 +54,19 @@ _gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) } -int -_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) +/* Helper for _gcry_mpi_cmp and _gcry_mpi_cmpabs. */ +static int +do_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v, int absmode) { mpi_size_t usize; mpi_size_t vsize; + int usign; + int vsign; int cmp; if (mpi_is_opaque (u) || mpi_is_opaque (v)) { + /* We have no signan and thus ABSMODE has no efeect here. */ if (mpi_is_opaque (u) && !mpi_is_opaque (v)) return -1; if (!mpi_is_opaque (u) && mpi_is_opaque (v)) @@ -82,26 +86,42 @@ _gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) usize = u->nlimbs; vsize = v->nlimbs; + usign = absmode? 0 : u->sign; + vsign = absmode? 0 : v->sign; /* Compare sign bits. */ - if (!u->sign && v->sign) + if (!usign && vsign) return 1; - if (u->sign && !v->sign) + if (usign && !vsign) return -1; /* U and V are either both positive or both negative. */ - if (usize != vsize && !u->sign && !v->sign) + if (usize != vsize && !usign && !vsign) return usize - vsize; - if (usize != vsize && u->sign && v->sign) + if (usize != vsize && usign && vsign) return vsize + usize; if (!usize ) return 0; if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) return 0; - if ((cmp < 0?1:0) == (u->sign?1:0)) + if ((cmp < 0?1:0) == (usign?1:0)) return 1; } return -1; } + + +int +_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) +{ + return do_mpi_cmp (u, v, 0); +} + +/* Compare only the absolute values. */ +int +_gcry_mpi_cmpabs (gcry_mpi_t u, gcry_mpi_t v) +{ + return do_mpi_cmp (u, v, 1); +} diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h index 549605b..3f89b72 100644 --- a/src/gcrypt-int.h +++ b/src/gcrypt-int.h @@ -379,6 +379,7 @@ int _gcry_mpi_is_neg (gcry_mpi_t a); void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u); void _gcry_mpi_abs (gcry_mpi_t w); int _gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); +int _gcry_mpi_cmpabs (const gcry_mpi_t u, const gcry_mpi_t v); int _gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); gpg_err_code_t _gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, const void *buffer, size_t buflen, @@ -479,6 +480,7 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); #define mpi_abs( w ) _gcry_mpi_abs( (w) ) #define mpi_neg( w, u) _gcry_mpi_neg( (w), (u) ) #define mpi_cmp( u, v ) _gcry_mpi_cmp( (u), (v) ) +#define mpi_cmpabs( u, v ) _gcry_mpi_cmpabs( (u), (v) ) #define mpi_cmp_ui( u, v ) _gcry_mpi_cmp_ui( (u), (v) ) #define mpi_is_neg( a ) _gcry_mpi_is_neg ((a)) commit 528a06b48389c9f10a1b10ff34cdc87bd3723a22 Author: Stephan Mueller Date: Mon Mar 12 22:24:37 2018 +0100 AES-KW: fix in-place encryption * cipher/cipher-aeswrap.c: move memmove call before KW IV setting -- In case AES-KW in-place encryption is performed, the plaintext must be moved to the correct destination location before the first semiblock of the destination buffer is modified. Without the patch, the first semiblock of the plaintext is overwritten with a6a6a6a6a6a6a6a6. Signed-off-by: Stephan Mueller (cherry picked from commit 330ec66e0babdabb658dc7d6db78f37b2a1b996e) (cherry picked from commit bbf88f0e9d481486ceca079e2611e84db8d039c7) diff --git a/cipher/cipher-aeswrap.c b/cipher/cipher-aeswrap.c index 698742d..a8d0e03 100644 --- a/cipher/cipher-aeswrap.c +++ b/cipher/cipher-aeswrap.c @@ -70,6 +70,9 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, a = outbuf; /* We store A directly in OUTBUF. */ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */ + /* Copy the inbuf to the outbuf. */ + memmove (r+8, inbuf, inbuflen); + /* If an IV has been set we use that IV as the Alternative Initial Value; if it has not been set we use the standard value. */ if (c->marks.iv) @@ -77,9 +80,6 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, else memset (a, 0xa6, 8); - /* Copy the inbuf to the outbuf. */ - memmove (r+8, inbuf, inbuflen); - memset (t, 0, sizeof t); /* t := 0. */ for (j = 0; j <= 5; j++) ----------------------------------------------------------------------- Summary of changes: cipher/cipher-aeswrap.c | 6 +- cipher/cipher-gcm.c | 77 +++++- mpi/ec.c | 9 + mpi/mpi-cmp.c | 34 ++- src/gcrypt-int.h | 2 + tests/basic.c | 691 +++++++++++++++++++++++++++++++++++++++++++++++- tests/t-mpi-point.c | 270 +++++++++++++++++++ 7 files changed, 1071 insertions(+), 18 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 10:25:17 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 10:25:17 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-7-BRANCH, updated. libgcrypt-1.7.9-8-g2ace21b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-7-BRANCH has been updated via 2ace21b1a8e4c512b8539a2eedf9ce2ab2ebc534 (commit) via ff8f7e53ce6b8a5681667595c6287323652ae157 (commit) from 3caf35a49cb62fb59834b5027ff299e2363a03c4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2ace21b1a8e4c512b8539a2eedf9ce2ab2ebc534 Author: Werner Koch Date: Wed Jun 13 10:25:34 2018 +0200 Post release updates. -- diff --git a/NEWS b/NEWS index 8ea5bc5..3125539 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.7.11 (unreleased) [C21/A1/R11] +------------------------------------------------- + + Noteworthy changes in version 1.7.10 (2018-06-13) [C21/A1/R10] ------------------------------------------------- diff --git a/configure.ac b/configure.ac index 76e25d6..e6217da 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.14" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [7]) -m4_define(mym4_version_micro, [10]) +m4_define(mym4_version_micro, [11]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag @@ -56,7 +56,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=21 LIBGCRYPT_LT_AGE=1 -LIBGCRYPT_LT_REVISION=10 +LIBGCRYPT_LT_REVISION=11 # If the API is changed in an incompatible way: increment the next counter. commit ff8f7e53ce6b8a5681667595c6287323652ae157 Author: Werner Koch Date: Wed Jun 13 10:18:08 2018 +0200 Release 1.7.10 diff --git a/NEWS b/NEWS index 14c5ee8..8ea5bc5 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,19 @@ -Noteworthy changes in version 1.7.10 (unreleased) [C21/A1/R10] +Noteworthy changes in version 1.7.10 (2018-06-13) [C21/A1/R10] ------------------------------------------------- + * Bug fixes: + + - Use blinding for ECDSA signing to mitigate a novel side-channel + attack. [#4011,CVE-2018-0495] + + - Fix incorrect counter overflow handling for GCM when using an IV + size other than 96 bit. [#3764] + + - Fix incorrect output of AES-keywrap mode for in-place encryption + on some platforms. + + - Fix the gcry_mpi_ec_curve_point point validation function. + Noteworthy changes in version 1.7.9 (2017-08-27) [C21/A1/R9] ------------------------------------------------ ----------------------------------------------------------------------- Summary of changes: NEWS | 19 ++++++++++++++++++- configure.ac | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 10:37:37 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 10:37:37 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-72-g0d51ea9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 0d51ea9b88b618368a7b916f26ebfe61bdf70503 (commit) from 9010d1576e278a4274ad3f4aa15776c28f6ba965 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0d51ea9b88b618368a7b916f26ebfe61bdf70503 Author: Werner Koch Date: Wed Jun 13 10:37:59 2018 +0200 Add NEWS from the 1.8 and 1.7 branches. -- diff --git a/AUTHORS b/AUTHORS index 49ab941..eb24236 100644 --- a/AUTHORS +++ b/AUTHORS @@ -21,7 +21,7 @@ year that would otherwise be listed individually. List of Copyright holders ========================= - Copyright (C) 1989,1991-2017 Free Software Foundation, Inc. + Copyright (C) 1989,1991-2018 Free Software Foundation, Inc. Copyright (C) 1994 X Consortium Copyright (C) 1996 L. Peter Deutsch Copyright (C) 1997 Werner Koch @@ -30,14 +30,14 @@ List of Copyright holders Copyright (C) 1996-2006 Peter Gutmann, Matt Thomlinson and Blake Coverett Copyright (C) 2003 Nikos Mavroyanopoulos Copyright (C) 2006-2007 NTT (Nippon Telegraph and Telephone Corporation) - Copyright (C) 2012-2017 g10 Code GmbH + Copyright (C) 2012-2018 g10 Code GmbH Copyright (C) 2012 Simon Josefsson, Niels M?ller Copyright (c) 2012 Intel Corporation Copyright (C) 2013 Christian Grothoff Copyright (C) 2013-2017 Jussi Kivilinna Copyright (C) 2013-2014 Dmitry Eremin-Solenikov Copyright (C) 2014 Stephan Mueller - Copyright (C) 2017 Bundesamt f?r Sicherheit in der Informationstechnik + Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik Authors with a FSF copyright assignment diff --git a/NEWS b/NEWS index 8049d7d..a4841b3 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,42 @@ Noteworthy changes in version 1.9.0 (unreleased) [C22/A3/R0] ------------------------------------------------ + * Bug fixes + + - Use blinding for ECDSA signing to mitigate a novel side-channel + attack. [#4011,CVE-2018-0495] [also in 1.8.3, 1.7.10] + + - Fix incorrect counter overflow handling for GCM when using an IV + size other than 96 bit. [#3764] [also in 1.8.3, 1.7.10] + + - Fix incorrect output of AES-keywrap mode for in-place encryption + on some platforms. [also in 1.8.3, 1.7.10] + + - Fix the gcry_mpi_ec_curve_point point validation function. + [also in 1.8.3, 1.7.10] + + - Fix rare assertion failure in gcry_prime_check. [also in 1.8.3] + + - Do not use /dev/srandom on OpenBSD. [also in 1.8.2] + + - Fix test suite failure on systems with large pages. [#3351] + [also in 1.8.2] + + - Fix test suite to not use mmap on Windows. [also in 1.8.2] + + - Fix fatal out of secure memory status in the s-expression parser + on heavy loaded systems. [also in 1.8.2] * Interface changes relative to the 1.8.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gcry_mpi_get_ui NEW function. GCRYCTL_AUTO_EXPAND_SECMEM NEW control code. + * Release dates of 1.8.x versions: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Version 1.8.2 (2017-12-13) + Version 1.8.3 (2018-06-13) + Noteworthy changes in version 1.8.1 (2017-08-27) [C22/A2/R1] ------------------------------------------------ @@ -129,11 +159,13 @@ Noteworthy changes in version 1.8.0 (2017-07-18) [C22/A2/R0] * Release dates of 1.7.x versions: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Version 1.7.8 (2017-06-29) [C21/A1/R8] - Version 1.7.7 (2017-06-02) [C21/A1/R7] - Version 1.7.6 (2017-01-18) [C21/A1/R6] - Version 1.7.5 (2016-12-15) [C21/A1/R5] - Version 1.7.4 (2016-12-09) [C21/A1/R4] + Version 1.7.10 (2018-06-13) [C21/A1/R10] + Version 1.7.9 (2017-08-27) [C21/A1/R9] + Version 1.7.8 (2017-06-29) [C21/A1/R8] + Version 1.7.7 (2017-06-02) [C21/A1/R7] + Version 1.7.6 (2017-01-18) [C21/A1/R6] + Version 1.7.5 (2016-12-15) [C21/A1/R5] + Version 1.7.4 (2016-12-09) [C21/A1/R4] Noteworthy changes in version 1.7.3 (2016-08-17) [C21/A1/R3] diff --git a/README b/README index c14181a..7ac8e4a 100644 --- a/README +++ b/README @@ -1,10 +1,10 @@ Libgcrypt - The GNU Crypto Library ------------------------------------ - Version 1.7 + Version 1.8 - Copyright (C) 1989,1991-2017 Free Software Foundation, Inc. - Copyright (C) 2012-2017 g10 Code GmbH - Copyright (C) 2013-2017 Jussi Kivilinna + Copyright (C) 1989,1991-2018 Free Software Foundation, Inc. + Copyright (C) 2012-2018 g10 Code GmbH + Copyright (C) 2013-2018 Jussi Kivilinna Libgcrypt is free software. See the file AUTHORS for full copying notices, and LICENSES for notices about contributions that require diff --git a/compat/compat.c b/compat/compat.c index b835293..8b001de 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -30,9 +30,9 @@ _gcry_compat_identification (void) static const char blurb[] = "\n\n" "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n" - "Copyright (C) 2000-2017 Free Software Foundation, Inc.\n" - "Copyright (C) 2012-2017 g10 Code GmbH\n" - "Copyright (C) 2013-2017 Jussi Kivilinna\n" + "Copyright (C) 2000-2018 Free Software Foundation, Inc.\n" + "Copyright (C) 2012-2018 g10 Code GmbH\n" + "Copyright (C) 2013-2018 Jussi Kivilinna\n" "\n" "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" "\n\n"; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index a1cb15a..d2dfe80 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1,6 +1,6 @@ /* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- - * Copyright (C) 1998-2017 Free Software Foundation, Inc. - * Copyright (C) 2012-2017 g10 Code GmbH + * Copyright (C) 1998-2018 Free Software Foundation, Inc. + * Copyright (C) 2012-2018 g10 Code GmbH * * This file is part of Libgcrypt. * ----------------------------------------------------------------------- Summary of changes: AUTHORS | 6 +++--- NEWS | 42 +++++++++++++++++++++++++++++++++++++----- README | 8 ++++---- compat/compat.c | 6 +++--- src/gcrypt.h.in | 4 ++-- 5 files changed, 49 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 12:25:34 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 12:25:34 +0200 Subject: [git] gnupg-doc - branch, master, updated. 9689413979faa7ebe03616c5bea0181d7b13ba85 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 9689413979faa7ebe03616c5bea0181d7b13ba85 (commit) from 823e9076f87a86ea258f6cf5cb0699b033365f11 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9689413979faa7ebe03616c5bea0181d7b13ba85 Author: Werner Koch Date: Wed Jun 13 12:25:38 2018 +0200 swdb: New gnupg w32 installer with latest Libgcrypt diff --git a/web/swdb.mac b/web/swdb.mac index 4b6cb19..6b9f46b 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -16,11 +16,11 @@ #+macro: gnupg22_sha1 d87553a125832ea90e8aeb3ceeecf24f88de56fb #+macro: gnupg22_sha2 777b4cb8ced21965a5053d4fa20fe11484f0a478f3d011cef508a1a49db50dcd #+macro: gnupg22_branch STABLE-BRANCH-2-2 -#+macro: gnupg22_w32_ver 2.2.8_20180608 -#+macro: gnupg22_w32_date 2018-06-08 -#+macro: gnupg22_w32_size 3916k -#+macro: gnupg22_w32_sha1 231b29631647328934a35f8c6baa483e7594e26a -#+macro: gnupg22_w32_sha2 21d4123d1455c925f8a570f94bc7e87a205edbff1ad78fabe8b7b5a3614b1aa2 +#+macro: gnupg22_w32_ver 2.2.8_20180613 +#+macro: gnupg22_w32_date 2018-06-13 +#+macro: gnupg22_w32_size 3915k +#+macro: gnupg22_w32_sha1 c91b0132319e2b9811901e453f6cb20c06cd73e2 +#+macro: gnupg22_w32_sha2 6d2b9269cc808d3dceffe3d7f368738402e7faed49cd823799bcfbdaedc57d3f # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 15:21:12 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Wed, 13 Jun 2018 15:21:12 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-60-gaed402c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via aed402c5d572b60246f1f8e57ae269f8c91b0b7c (commit) via d0fc4ded58f4a6a86c5ee0a36a3d3c669e244d0d (commit) from e154554e9a48a08219649a58be0b641c561e1748 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aed402c5d572b60246f1f8e57ae269f8c91b0b7c Author: Maximilian Krambach Date: Wed Jun 13 15:22:03 2018 +0200 js: getDefaultKey and verify fix -- * DemoExtension/maindemo.js - added a Demo for retrieving the default signing key * src/Errors.js - add a new Error if no default key can be determined * src/Key.js added documentation and a TODO marker for hasSecret. * src/Keyring.js implemented getDefaultKey * src/permittedOperations.js: Added missing entry for verify, added config_opt diff --git a/lang/js/CHECKLIST b/lang/js/CHECKLIST index fe26018..2e70dff 100644 --- a/lang/js/CHECKLIST +++ b/lang/js/CHECKLIST @@ -13,10 +13,11 @@ receiving an answer [*] Key handling (import/export, modifying, status queries) [x] Import (not importing secret) [x] Export (not exporting secret) - [x] status queries + [*] status queries + [ ] getHasSecret [ ] key generation [ ] modification - [*] Configuration handling + [x] Configuration handling [ ] check for completeness Communication with other implementations diff --git a/lang/js/DemoExtension/maindemo.js b/lang/js/DemoExtension/maindemo.js index 5cde1ce..67b811f 100644 --- a/lang/js/DemoExtension/maindemo.js +++ b/lang/js/DemoExtension/maindemo.js @@ -36,7 +36,7 @@ document.addEventListener('DOMContentLoaded', function() { 'answer').value = answer.data; } }, function(errormsg){ - alert( errormsg.code + ' ' + errormsg.msg); + alert( errormsg.message); }); }); @@ -50,8 +50,18 @@ document.addEventListener('DOMContentLoaded', function() { 'answer').value = answer.data; } }, function(errormsg){ - alert( errormsg.code + ' ' + errormsg.msg); + alert(errormsg.message); }); }); + + document.getElementById('getdefaultkey').addEventListener('click', + function(){ + gpgmejs.Keyring.getDefaultKey().then(function(answer){ + document.getElementById('defaultkey').innerHtml = + answer.fingerprint; + }, function(errormsg){ + alert(errormsg.message); + }); + }); }); }); diff --git a/lang/js/DemoExtension/mainui.html b/lang/js/DemoExtension/mainui.html index 76b8a22..91be7bb 100644 --- a/lang/js/DemoExtension/mainui.html +++ b/lang/js/DemoExtension/mainui.html @@ -29,5 +29,16 @@

Result data:

+ +
+
    +
  • + Default Key: +
    + +
  • + + +
diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js index dabf6a5..73e7438 100644 --- a/lang/js/src/Errors.js +++ b/lang/js/src/Errors.js @@ -78,6 +78,11 @@ const err_list = { msg:'This property has not been retrieved yet from GPG', type: 'error' }, + 'KEY_NO_DEFAULT': { + msg:'A default key could not be established. Please check yout gpg ' + + 'configuration', + type: 'error' + }, // generic 'PARAM_WRONG':{ msg: 'Invalid parameter was found', diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index 5986254..3e4f1c7 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -192,6 +192,7 @@ export class GPGME_Key { * Query the armored block of the non- secret parts of the Key directly * from gpg. * @returns {Promise} + * @async */ getArmor(){ let me = this; @@ -211,6 +212,13 @@ export class GPGME_Key { }); } + /** + * Find out if the Key includes a secret part + * @returns {Promise} + * + * @async + */ + // TODO: Does not work yet, result is always false getHasSecret(){ let me = this; return new Promise(function(resolve, reject) { diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index 0d4e3c5..e07a593 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -99,7 +99,61 @@ export class GPGME_Keyring { }); } - // getDefaultKey() Big TODO + /** + * Returns the Key to be used by default for signing operations, + * looking up the gpg configuration, or returning the first key that + * contains a secret key. + * @returns {Promise} + * + * @async + * TODO: getHasSecret always returns false at this moment, so this fucntion + * still does not fully work as intended. + * + */ + getDefaultKey() { + let me = this; + return new Promise(function(resolve, reject){ + let msg = createMessage('config_opt'); + msg.setParameter('component', 'gpg'); + msg.setParameter('option', 'default-key'); + msg.post().then(function(response){ + if (response.value !== undefined + && response.value.hasOwnProperty('string') + && typeof(response.value.string) === 'string' + ){ + me.getKeys(response.value.string,true).then(function(keys){ + if(keys.length === 1){ + resolve(keys[0]); + } else { + reject(gpgme_error('KEY_NO_DEFAULT')); + } + }, function(error){ + reject(error); + }); + } else { + // TODO: this is overly 'expensive' in communication + // and probably performance, too + me.getKeys(null,true).then(function(keys){ + for (let i=0; i < keys.length; i++){ + console.log(keys[i]); + console.log(keys[i].get('hasSecret')); + if (keys[i].get('hasSecret') === true){ + resolve(keys[i]); + break; + } + if (i === keys.length -1){ + reject(gpgme_error('KEY_NO_DEFAULT')); + } + } + }, function(error){ + reject(error); + }); + } + }, function(error){ + reject(error); + }); + }); + } /** * diff --git a/lang/js/src/permittedOperations.js b/lang/js/src/permittedOperations.js index 91612ad..044ae4a 100644 --- a/lang/js/src/permittedOperations.js +++ b/lang/js/src/permittedOperations.js @@ -314,7 +314,7 @@ export const permittedOperations = { }, createkey: { - pinentry: true, + pinentry: true, required: { userid: { allowed: ['string'] @@ -332,7 +332,59 @@ export const permittedOperations = { type: [''], data: {'fingerprint': 'string'} } + }, + + verify: { + required: { + data: { + allowed: ['string'] + } + }, + optional: { + 'protocol': { + allowed: ['string'], + allowed_data: ['cms', 'openpgp'] + }, + 'signature': { + allowed: ['string'] + }, + 'base64':{ + allowed: ['boolean'] + } + }, + answer: { + type: ['plaintext'], + data:{ + data: 'string', + base64:'boolean', + info: 'object' + // file_name: Optional string of the plaintext file name. + // is_mime: Boolean if the messages claims it is MIME. + // signatures: Array of signatures + } + } + }, + + config_opt: { + required: { + 'component':{ + allowed: ['string'], + // allowed_data: ['gpg'] // TODO check all available + }, + 'option': { + allowed: ['string'], + // allowed_data: ['default-key'] // TODO check all available + } + }, + optional: {}, + answer: { + type: [], + data: { + option: 'object' + } + } } + /** * TBD handling of secrets * TBD key modification? commit d0fc4ded58f4a6a86c5ee0a36a3d3c669e244d0d Author: Maximilian Krambach Date: Wed Jun 13 11:49:37 2018 +0200 js: less confusing icons for test/Demo extension -- * The current test icon was just a generic pin. Changed that by the gnupg lock symbol with 'Demo'/'Tests' written on it. Original taken from gnupg artwork/icons/lock-wing.svg. diff --git a/lang/js/BrowserTestExtension/testicon.png b/lang/js/BrowserTestExtension/testicon.png index 12c3f5d..a98463d 100644 Binary files a/lang/js/BrowserTestExtension/testicon.png and b/lang/js/BrowserTestExtension/testicon.png differ diff --git a/lang/js/DemoExtension/testicon.png b/lang/js/DemoExtension/testicon.png index 12c3f5d..84284e0 100644 Binary files a/lang/js/DemoExtension/testicon.png and b/lang/js/DemoExtension/testicon.png differ ----------------------------------------------------------------------- Summary of changes: lang/js/BrowserTestExtension/testicon.png | Bin 16192 -> 2697 bytes lang/js/CHECKLIST | 5 +-- lang/js/DemoExtension/maindemo.js | 14 ++++++-- lang/js/DemoExtension/mainui.html | 11 ++++++ lang/js/DemoExtension/testicon.png | Bin 16192 -> 2670 bytes lang/js/src/Errors.js | 5 +++ lang/js/src/Key.js | 8 +++++ lang/js/src/Keyring.js | 56 +++++++++++++++++++++++++++++- lang/js/src/permittedOperations.js | 54 +++++++++++++++++++++++++++- 9 files changed, 147 insertions(+), 6 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 16:11:46 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 16:11:46 +0200 Subject: [git] Pinentry - branch, master, updated. pinentry-1.1.0-7-g779b8e6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The standard pinentry collection". The branch, master has been updated via 779b8e6df7d2678d40bc61ba9e9ff35324a40d03 (commit) from 948105b7a34ec9a9e5479d376b7c86bafee50a01 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 779b8e6df7d2678d40bc61ba9e9ff35324a40d03 Author: Werner Koch Date: Wed Jun 13 16:10:53 2018 +0200 core: Add info about tty mode etc to 'getinfo ttyinfo' * configure.ac: Check for 'stat'. * pinentry/pinentry.c: Include types.h and stat.h. (device_stat_string): New. (cmd_getinfo): Print more info. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index e305e44..51a2313 100644 --- a/configure.ac +++ b/configure.ac @@ -221,7 +221,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS(string.h unistd.h langinfo.h termio.h locale.h utime.h wchar.h) dnl Checks for library functions. -AC_CHECK_FUNCS(seteuid stpcpy mmap) +AC_CHECK_FUNCS(seteuid stpcpy mmap stat) GNUPG_CHECK_MLOCK dnl Checks for standard types. diff --git a/pinentry/pinentry.c b/pinentry/pinentry.c index 30c333b..cd813d8 100644 --- a/pinentry/pinentry.c +++ b/pinentry/pinentry.c @@ -27,6 +27,8 @@ #endif #include #include +#include +#include #include #include #ifndef HAVE_W32_SYSTEM @@ -1706,6 +1708,33 @@ cmd_message (assuan_context_t ctx, char *line) return cmd_confirm (ctx, "--one-button"); } + +/* Return a staically allocated string with information on the mode, + * uid, and gid of DEVICE. On error "?" is returned if DEVICE is + * NULL, "-" is returned. */ +static const char * +device_stat_string (const char *device) +{ +#ifdef HAVE_STAT + static char buf[40]; + struct stat st; + + if (!device || !*device) + return "-"; + + if (stat (device, &st)) + return "?"; /* Error */ + snprintf (buf, sizeof buf, "%lo/%lu/%lu", + (unsigned long)st.st_mode, + (unsigned long)st.st_uid, + (unsigned long)st.st_gid); + return buf; +#else + return "-"; +#endif +} + + /* GETINFO Multipurpose function to return a variety of information. @@ -1721,7 +1750,7 @@ cmd_getinfo (assuan_context_t ctx, char *line) { int rc; const char *s; - char buffer[100]; + char buffer[150]; if (!strcmp (line, "version")) { @@ -1753,10 +1782,17 @@ cmd_getinfo (assuan_context_t ctx, char *line) } else if (!strcmp (line, "ttyinfo")) { - snprintf (buffer, sizeof buffer, "%s %s %s", + snprintf (buffer, sizeof buffer, "%s %s %s %s %lu/%lu", pinentry.ttyname? pinentry.ttyname : "-", pinentry.ttytype? pinentry.ttytype : "-", - pinentry.display? pinentry.display : "-" ); + pinentry.display? pinentry.display : "-", + device_stat_string (pinentry.ttyname), +#ifdef HAVE_DOSISH_SYSTEM + 0l, 0l +#else + (unsigned long)geteuid (), (unsigned long)getegid () +#endif + ); buffer[sizeof buffer -1] = 0; rc = assuan_send_data (ctx, buffer, strlen (buffer)); } ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 +- pinentry/pinentry.c | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 13 18:38:35 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Jun 2018 18:38:35 +0200 Subject: [git] gnupg-doc - branch, master, updated. 969e129dbd6b94a71433f12333a166fd2fbe9e8b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 969e129dbd6b94a71433f12333a166fd2fbe9e8b (commit) from 9689413979faa7ebe03616c5bea0181d7b13ba85 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 969e129dbd6b94a71433f12333a166fd2fbe9e8b Author: Werner Koch Date: Wed Jun 13 18:39:03 2018 +0200 web: Release info for libgcrypt 1.8.3 diff --git a/web/index.org b/web/index.org index 53df6f1..872a068 100644 --- a/web/index.org +++ b/web/index.org @@ -65,6 +65,13 @@ The latest release news:\\ # GnuPG's latest news are available as [[http://feedvalidator.org/check.cgi?url%3Dhttps://www.gnupg.org/news.en.rss][RSS 2.0 compliant]] feed. Just # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** Libgcrypt 1.8.3 released (2018-06-13) + +We are pleased to announce the availability of [[file:software/libgcrypt/index.org][Libgcrypt]] version 1.8.3 +and 1.7.10. These releases fix a local side-channel attack on ECDSA +signature as described in the white pager "Return of the Hidden Number +Proble" and got assigned {{{CVE(2018-0495)}}}. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000426.html][more]]} + ** GnuPG 1.4.23 released (2018-06-11) :important: Although GnuPG 1.4 is of very limited use today we did a maintenance ----------------------------------------------------------------------- Summary of changes: web/index.org | 7 +++++++ 1 file changed, 7 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 14 06:16:37 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 14 Jun 2018 06:16:37 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-153-g3e6ad30 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3e6ad302eaf3a4a9f3e60379133b3dfdbe0e1b2d (commit) via 5b40338f12762cd74238c2d2b3101c33dd2d0ed3 (commit) from cb52eb76b3ba0269742c5322e10a2b5151dafaf2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3e6ad302eaf3a4a9f3e60379133b3dfdbe0e1b2d Author: NIIBE Yutaka Date: Thu Jun 14 13:10:57 2018 +0900 libdns: Sync to upstream. * dirmngr/dns.c (dns_nssconf_loadfile): Handle exclamation mark. -- Reverting local change, merge upstream's debug-tracing branch. (commit 21281fc1b63bb74d51762b8e363c49b1a258783d) Fixes-commit: d4c0187dd93163f12e9f953366adef81ecf526a6 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 8e8b6db..13ef4b8 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -6096,17 +6096,9 @@ int dns_nssconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) { dns_anyconf_skip(" \t", fp); if ('[' == dns_anyconf_peek(fp)) { - dns_anyconf_skip("[ \t", fp); + dns_anyconf_skip("[! \t", fp); - for (;;) { - if ('!' == dns_anyconf_peek(fp)) { - dns_anyconf_skip("! \t", fp); - /* FIXME: negating statuses; currently not implemented */ - dns_anyconf_skip("^#;]\n", fp); /* skip to end of criteria */ - break; - } - - if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) break; + while (dns_anyconf_scan(&cf, "%w_", fp, &error)) { dns_anyconf_skip("= \t", fp); if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) { dns_anyconf_pop(&cf); /* discard status */ commit 5b40338f12762cd74238c2d2b3101c33dd2d0ed3 Author: NIIBE Yutaka Date: Thu Jun 14 13:01:45 2018 +0900 dirmngr: Fix recursive resolver mode. * dirmngr/dns-stuff.c (libdns_init): Initialize options.recurse. -- To reproduce an error, run: ./t-dns-stuff --debug --recursive-resolver www.gnupg.org Then, it returns "No name" error. That's because there was only setup for root servers, and no setup for recursive query in fact. Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 7324aae..ffac816 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -612,6 +612,8 @@ libdns_init (void) } } + ld.resolv_conf->options.recurse = recursive_resolver_p (); + /* dns_hints_local for stub mode, dns_hints_root for recursive. */ ld.hints = (recursive_resolver ? dns_hints_root (ld.resolv_conf, &derr) ----------------------------------------------------------------------- Summary of changes: dirmngr/dns-stuff.c | 2 ++ dirmngr/dns.c | 12 ++---------- 2 files changed, 4 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 14 10:26:01 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 14 Jun 2018 10:26:01 +0200 Subject: [git] gnupg-doc - branch, master, updated. 73c278e7b09fa18bc35fce117a9e05e37d791fe1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 73c278e7b09fa18bc35fce117a9e05e37d791fe1 (commit) from 969e129dbd6b94a71433f12333a166fd2fbe9e8b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 73c278e7b09fa18bc35fce117a9e05e37d791fe1 Author: Werner Koch Date: Thu Jun 14 10:26:30 2018 +0200 web: typo fix diff --git a/web/index.org b/web/index.org index 872a068..1e82ba3 100644 --- a/web/index.org +++ b/web/index.org @@ -69,8 +69,8 @@ The latest release news:\\ We are pleased to announce the availability of [[file:software/libgcrypt/index.org][Libgcrypt]] version 1.8.3 and 1.7.10. These releases fix a local side-channel attack on ECDSA -signature as described in the white pager "Return of the Hidden Number -Proble" and got assigned {{{CVE(2018-0495)}}}. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000426.html][more]]} +signature as described in the white pager ?Return of the Hidden Number +Problem? and got assigned {{{CVE(2018-0495)}}}. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000426.html][more]]} ** GnuPG 1.4.23 released (2018-06-11) :important: ----------------------------------------------------------------------- Summary of changes: web/index.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 14 12:15:42 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Thu, 14 Jun 2018 12:15:42 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-61-g3c783bd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via 3c783bd09ce54b0d50dc3bea201e70e4fcbbf6a3 (commit) from aed402c5d572b60246f1f8e57ae269f8c91b0b7c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3c783bd09ce54b0d50dc3bea201e70e4fcbbf6a3 Author: Maximilian Krambach Date: Thu Jun 14 12:15:51 2018 +0200 js: add verify and signature parsing -- * src/gpgmejs.js: - Added verify method - Added verification results in decrypt (if signatures are present in the message) - Added a base64 option to decrypt * src/Signature.js: Convenience class for verification results. Used for e.g. converting timestamps to javascript time, quick overall validity checks * src/Keyring.js: removed debug code * src/Errors.js add two new Signature errors diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js index 73e7438..a8cd8b5 100644 --- a/lang/js/src/Errors.js +++ b/lang/js/src/Errors.js @@ -83,6 +83,14 @@ const err_list = { 'configuration', type: 'error' }, + 'SIG_WRONG': { + msg:'A malformed signature was created', + type: 'error' + }, + 'SIG_NO_SIGS': { + msg:'There were no signatures found', + type: 'error' + }, // generic 'PARAM_WRONG':{ msg: 'Invalid parameter was found', diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index e07a593..451f936 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -135,8 +135,6 @@ export class GPGME_Keyring { // and probably performance, too me.getKeys(null,true).then(function(keys){ for (let i=0; i < keys.length; i++){ - console.log(keys[i]); - console.log(keys[i].get('hasSecret')); if (keys[i].get('hasSecret') === true){ resolve(keys[i]); break; diff --git a/lang/js/src/Signature.js b/lang/js/src/Signature.js new file mode 100644 index 0000000..d7d0598 --- /dev/null +++ b/lang/js/src/Signature.js @@ -0,0 +1,193 @@ +/* gpgme.js - Javascript integration for gpgme + * Copyright (C) 2018 Bundesamt f?r Sicherheit in der Informationstechnik + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1+ + * + * Author(s): + * Maximilian Krambach + */ + +/** + * Validates a signature object and returns + * @param {Object} sigObject Object as returned by gpgme-json. The definition + * of the expected values are to be found in the constants 'expKeys', 'expSum', + * 'expNote' in this file. + * @returns {GPGME_Signature} Signature Object + */ + +import { gpgme_error } from './Errors'; + +export function createSignature(sigObject){ + if ( + typeof(sigObject) !=='object' || + !sigObject.hasOwnProperty('summary') || + !sigObject.hasOwnProperty('fingerpprint') || + !sigObject.hasOwnProperty('timestamp') + //TODO check if timestamp is mandatory in specification + ){ + return gpgme_error('SIG_WRONG'); + } + let keys = Object.keys(sigObject); + for (let i=0; i< keys.length; i++){ + if ( typeof(sigObject[keys[i]]) !== expKeys[keys[i]] ){ + return gpgme_error('SIG_WRONG'); + } + } + let sumkeys = Object.keys(sigObject.summary); + for (let i=0; i< sumkeys.length; i++){ + if ( typeof(sigObject.summary[sumkeys[i]]) !== expSum[sumkeys[i]] ){ + return gpgme_error('SIG_WRONG'); + } + } + if (sigObject.hasOwnProperty('notations')){ + if (!Array.isArray(sigObject.notations)){ + return gpgme_error('SIG_WRONG'); + } + for (let i=0; i < sigObject.notations.length; i++){ + let notation = sigObject.notations[i]; + let notekeys = Object.keys(notation); + for (let j=0; j < notekeys.length; j++){ + if ( typeof(notation[notekeys[j]]) !== expNote[notekeys[j]] ){ + return gpgme_error('SIG_WRONG'); + } + } + } + } + return new GPGME_Signature(sigObject); +} + + +/** + * Representing the details of a signature. It is supposed to be read-only. The + * full details as given by gpgme-json can be accessed from the _rawSigObject. + * ) + */ +class GPGME_Signature { + constructor(sigObject){ + this._rawSigObject = sigObject; + } + + /** + * The signatures' fingerprint + */ + get fingerprint(){ + return this._rawSigObject.fingerprint; + } + + /** + * The expiration of this Signature as Javascript date, or null if + * signature does not expire + * @returns {Date | null} + */ + get expiration(){ + if (!this._rawSigObject.exp_timestamp){ + return null; + } + return new Date(this._rawSigObject.exp_timestamp* 1000); + } + + /** + * The creation date of this Signature in Javascript Date + * @returns {Date} + */ + get timestamp(){ + return new Date(this._rawSigObject.timestamp* 1000); + } + + /** + * The overall validity of the key. If false, errorDetails may contain + * additional information + */ + get valid() { + if (this._rawSigObject.valid === true){ + return true; + } else { + return false; + } + } + + /** + * gives more information on non-valid signatures. Refer to the gpgme docs + * https://www.gnupg.org/documentation/manuals/gpgme/Verify.html for + * details on the values + * @returns {Object} Object with boolean properties + */ + get errorDetails(){ + let properties = ['revoked', 'key-expired', 'sig-expired', + 'key-missing', 'crl-missing', 'crl-too-old', 'bad-policy', + 'sys-error']; + let result = {}; + for (let i=0; i< properties.length; i++){ + if ( this._rawSigObject.hasOwnProperty(properties[i]) ){ + result[properties[i]] = this._rawSigObject[properties[i]]; + } + } + return result; + } + +} + +/** + * Keys and their value's type for the signature Object + */ +const expKeys = { + 'wrong_key_usage': 'boolean', + 'chain_model': 'boolean', + 'summary': 'object', + 'is_de_vs': 'boolean', + 'status_string':'string', + 'fingerprint':'string', + 'validity_string': 'string', + 'pubkey_algo_name':'string', + 'hash_algo_name':'string', + 'pka_address':'string', + 'status_code':'number', + 'timestamp':'number', + 'exp_timestamp':'number', + 'pka_trust':'number', + 'validity':'number', + 'validity_reason':'number', + 'notations': 'object' +}; + +/** + * Keys and their value's type for the summary + */ +const expSum = { + 'valid': 'boolean', + 'green': 'boolean', + 'red': 'boolean', + 'revoked': 'boolean', + 'key-expired': 'boolean', + 'sig-expired': 'boolean', + 'key-missing': 'boolean', + 'crl-missing': 'boolean', + 'crl-too-old': 'boolean', + 'bad-policy': 'boolean', + 'sys-error': 'boolean' +}; + +/** + * Keys and their value's type for notations objects + */ +const expNote = { + 'human_readable': 'boolean', + 'critical':'boolean', + 'name': 'string', + 'value': 'string', + 'flags': 'number' +}; diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index 7fa7643..a0f7e96 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -26,6 +26,7 @@ import {GPGME_Message, createMessage} from './Message'; import {toKeyIdArray} from './Helpers'; import { gpgme_error } from './Errors'; import { GPGME_Keyring } from './Keyring'; +import { createSignature } from './Signature'; export class GpgME { /** @@ -107,15 +108,28 @@ export class GpgME { * Decrypt a Message * @param {String|Object} data text/data to be decrypted. Accepts Strings * and Objects with a getText method - * @returns {Promise} decrypted message: - data: The decrypted data. - base64: Boolean indicating whether data is base64 encoded. - mime: A Boolean indicating whether the data is a MIME object. - signatures: Array of signature Objects TODO not yet implemented. - // should be an object that can tell if all signatures are valid. + * @param {Boolean} base64 (optional) false if the data is an armored block, + * true if it is base64 encoded binary data + * @returns {Promise} result: Decrypted Message and information + * @returns {String} result.data: The decrypted data. + * @returns {Boolean} result.base64: indicating whether data is base64 + * encoded. + * @returns {Boolean} result.is_mime: Indicating whether the data is a MIME + * object. + * @returns {String} result.file_name: The optional original file name + * @returns {Object} message.signatures Verification details for signatures: + * @returns {Boolean} message.signatures.all_valid: true if all signatures + * are valid + * @returns {Number} message.signatures.count: Number of signatures found + * @returns {Number} message.signatures.failures Number of invalid + * signatures + * @returns {Array} message.signatures.signatures. Two arrays + * (good & bad) of {@link GPGME_Signature} objects, offering further + * information. + * * @async */ - decrypt(data){ + decrypt(data, base64=false){ if (data === undefined){ return Promise.reject(gpgme_error('MSG_EMPTY')); } @@ -124,8 +138,32 @@ export class GpgME { if (msg instanceof Error){ return Promise.reject(msg); } + if (base64 === true){ + msg.setParameter('base64', true); + } putData(msg, data); - return msg.post(); + if (base64 === true){ + msg.setParameter('base64', true); + } + return new Promise(function(resolve, reject){ + msg.post().then(function(result){ + let _result = {data: result.data}; + _result.base64 = result.base64 ? true: false; + _result.is_mime = result.mime ? true: false; + if (result.file_name){ + _result.file_name = result.file_name; + } + if ( + result.hasOwnProperty('signatures') && + Array.isArray(result.signatures) + ) { + _result.signatures = collectSignatures(result.signatures); + } + resolve(_result); + }, function(error){ + reject(error); + }); + }); } /** @@ -179,6 +217,59 @@ export class GpgME { }); }); } + + /** + * Verifies data. + * @param {String|Object} data text/data to be verified. Accepts Strings + * and Objects with a gettext method + * @param {String} (optional) A detached signature. If not present, opaque + * mode is assumed + * @param {Boolean} (optional) Data and signature are base64 encoded + * // TODO verify if signature really is assumed to be base64 + * @returns {Promise} result: + * @returns {Boolean} result.data: The verified data + * @returns {Boolean} result.is_mime: The message claims it is MIME + * @returns {String} result.file_name: The optional filename of the message + * @returns {Boolean} result.all_valid: true if all signatures are valid + * @returns {Number} result.count: Number of signatures found + * @returns {Number} result.failures Number of unsuccessful signatures + * @returns {Array} result.signatures. Two arrays (good & bad) of + * {@link GPGME_Signature} objects, offering further information. + */ + verify(data, signature, base64 = false){ + let msg = createMessage('verify'); + let dt = this.putData(msg, data); + if (dt instanceof Error){ + return Promise.reject(dt); + } + if (signature){ + if (typeof(signature)!== 'string'){ + return Promise.reject(gpgme_error('PARAM_WRONG')); + } else { + msg.setParameter('signature', signature); + } + } + if (base64 === true){ + msg.setParameter('base64', true); + } + return new Promise(function(resolve, reject){ + msg.post().then(function (message){ + if (!message.info.signatures){ + reject(gpgme_error('SIG_NO_SIGS')); + } else { + let _result = collectSignatures(message.info.signatures); + _result.is_mime = message.info.is_mime? true: false; + if (message.info.filename){ + _result.file_name = message.info.filename; + } + _result.data = message.data; + resolve(_result); + } + }, function(error){ + reject(error); + }); + }); + } } /** @@ -209,3 +300,34 @@ function putData(message, data){ return gpgme_error('PARAM_WRONG'); } } + +function collectSignatures(sigs){ + if (!Array.isArray(sigs)){ + return gpgme_error('SIG_NO_SIGS'); + } + let summary = { + all_valid: false, + count: sigs.length, + failures: 0, + signatures: { + good: [], + bad: [], + } + }; + for (let i=0; i< sigs.length; i++){ + let sigObj = createSignature(sigs[i]); + if (sigObj instanceof Error){ + return gpgme_error('SIG_WRONG'); + } + if (sigObj.valid !== true){ + summary.failures += 1; + summary.signatures.bad.push(sigObj); + } else { + summary.signatures.good.push(sigObj); + } + } + if (summary.failures === 0){ + summary.all_valid = true; + } + return summary; +} \ No newline at end of file ----------------------------------------------------------------------- Summary of changes: lang/js/src/Errors.js | 8 ++ lang/js/src/Keyring.js | 2 - lang/js/src/Signature.js | 193 +++++++++++++++++++++++++++++++++++++++++++++++ lang/js/src/gpgmejs.js | 138 +++++++++++++++++++++++++++++++-- 4 files changed, 331 insertions(+), 10 deletions(-) create mode 100644 lang/js/src/Signature.js hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 14 14:50:21 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Thu, 14 Jun 2018 14:50:21 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-62-g3cd428b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via 3cd428ba442f43e470b977e27e18ff52567baba5 (commit) from 3c783bd09ce54b0d50dc3bea201e70e4fcbbf6a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3cd428ba442f43e470b977e27e18ff52567baba5 Author: Maximilian Krambach Date: Thu Jun 14 14:50:25 2018 +0200 js: import result feedback -- * src/Keyring.js: Changed and documented the import result feedback towards the javascript side diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index 451f936..43d257d 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -155,26 +155,36 @@ export class GPGME_Keyring { /** * - * @param {String} armored Armored Key block of the Kex(s) to be imported + * @param {String} armored Armored Key block of the Key(s) to be imported * into gnupg * @param {Boolean} prepare_sync prepare the keys for synched use * (see getKeys()). - * @returns {Promise>} An array of objects for the Keys - * considered: - * Key.key : The key itself as a GPGME_Key - * Key.status : - * 'nochange' if the Key was not changed, - * 'newkey' if the Key was imported in gpg, and did not exist - * previously, - * 'change' if the key existed, but details were updated. For - * details, Key.changes is available. - * Key.changes.userId: userIds changed - * Key.changes.signature: signatures changed - * Key.changes.subkey: subkeys changed - * // TODO: not yet implemented: Information about Keys that failed - * (e.g. malformed Keys, secretKeys are not accepted) + * + * @returns {Promise} result: A summary and an array of Keys + * considered + * + * @returns result.summary: Numerical summary of the result. See the + * feedbackValues variable for available values and the gnupg documentation + * https://www.gnupg.org/documentation/manuals/gpgme/Importing-Keys.html + * for details on their meaning. + * @returns {Array} result.Keys: Array of objects containing: + * @returns {GPGME_Key} Key.key The resulting key + * @returns {String} Key.status: + * 'nochange' if the Key was not changed, + * 'newkey' if the Key was imported in gpg, and did not exist + * previously, + * 'change' if the key existed, but details were updated. For + * details, Key.changes is available. + * @returns {Boolean} Key.changes.userId: userIds changed + * @returns {Boolean} Key.changes.signature: signatures changed + * @returns {Boolean} Key.changes.subkey: subkeys changed */ importKey(armored, prepare_sync) { + let feedbackValues = ['considered', 'no_user_id', 'imported', + 'imported_rsa', 'unchanged', 'new_user_ids', 'new_sub_keys', + 'new_signatures', 'new_revocations', 'secret_read', + 'secret_imported', 'secret_unchanged', 'skipped_new_keys', + 'not_imported', 'skipped_v3_keys']; if (!armored || typeof(armored) !== 'string'){ return Promise.reject(gpgme_error('PARAM_WRONG')); } @@ -185,8 +195,8 @@ export class GPGME_Keyring { msg.post().then(function(response){ let infos = {}; let fprs = []; - for (let res=0; res < response.result[0].imports.length; res++){ - let result = response.result[0].imports[res]; + for (let res=0; res This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via bcdbf8b8ebe9d61160e0b007dabe1b6462ffbc93 (commit) via 1c0b6681e4f322b88ac35d1f21c03d3cfc35fc23 (commit) from 3e6ad302eaf3a4a9f3e60379133b3dfdbe0e1b2d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bcdbf8b8ebe9d61160e0b007dabe1b6462ffbc93 Author: NIIBE Yutaka Date: Fri Jun 15 12:58:29 2018 +0900 libdns: Fix connect and try next nameserver when ECONNREFUSED. * dirmngr/dns.c (dns_so_check): When EINVAL, release the association by connect with AF_UNSPEC and try again. Also try again for ECONNREFUSED. (dns_res_exec): Try next nameserver when ECONNREFUSED. -- GnuPG-bug-id: T3374 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 178070a..d2445a0 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -7614,8 +7614,23 @@ retry: so->state++; /* FALL THROUGH */ case DNS_SO_UDP_CONN: + udp_connect_retry: error = dns_connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote)); dns_trace_sys_connect(so->trace, so->udp, SOCK_DGRAM, (struct sockaddr *)&so->remote, error); + + /* Linux returns EINVAL when address was bound to + localhost and it's external IP address now. */ + if (error == EINVAL) { + struct sockaddr unspec_addr; + memset (&unspec_addr, 0, sizeof unspec_addr); + unspec_addr.sa_family = AF_UNSPEC; + connect(so->udp, &unspec_addr, sizeof unspec_addr); + goto udp_connect_retry; + } else if (error == ECONNREFUSED) + /* Error for previous socket operation may + be reserverd asynchronously. */ + goto udp_connect_retry; + if (error) goto error; @@ -8824,7 +8839,10 @@ exec: if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf)) dgoto(R->sp, DNS_R_FOREACH_A); - if ((error = dns_so_check(&R->so))) + error = dns_so_check(&R->so); + if (error == ECONNREFUSED) + dgoto(R->sp, DNS_R_FOREACH_A); + else if (error) goto error; if (!dns_p_setptr(&F->answer, dns_so_fetch(&R->so, &error))) @@ -8957,7 +8975,10 @@ exec: if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf)) dgoto(R->sp, DNS_R_FOREACH_AAAA); - if ((error = dns_so_check(&R->so))) + error = dns_so_check(&R->so); + if (error == ECONNREFUSED) + dgoto(R->sp, DNS_R_FOREACH_AAAA); + else if (error) goto error; if (!dns_p_setptr(&F->answer, dns_so_fetch(&R->so, &error))) commit 1c0b6681e4f322b88ac35d1f21c03d3cfc35fc23 Author: NIIBE Yutaka Date: Fri Jun 15 10:38:22 2018 +0900 libdns: Clear struct sockaddr_storage by zero. * dirmngr/dns.c (dns_resconf_pton): Clear SS. (dns_resconf_setiface): Clear ->IFACE. (dns_hints_root, send_query): Clear SS. -- POSIX requires clear the structure of struct sockaddr_in6. On macOS, in some case like bind, it is better to clear even for struct sockaddr_in. Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 13ef4b8..178070a 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -5549,6 +5549,7 @@ int dns_resconf_pton(struct sockaddr_storage *ss, const char *src) { unsigned short port = 0; int ch, af = AF_INET, error; + memset(ss, 0, sizeof *ss); while ((ch = *src++)) { switch (ch) { case ' ': @@ -6311,6 +6312,7 @@ int dns_resconf_setiface(struct dns_resolv_conf *resconf, const char *addr, unsi int af = (strchr(addr, ':'))? AF_INET6 : AF_INET; int error; + memset(&resconf->iface, 0, sizeof (struct sockaddr_storage)); if ((error = dns_pton(af, addr, dns_sa_addr(af, &resconf->iface, NULL)))) return error; @@ -6622,6 +6624,7 @@ struct dns_hints *dns_hints_root(struct dns_resolv_conf *resconf, int *error_) { for (i = 0; i < lengthof(root_hints); i++) { af = root_hints[i].af; + memset(&ss, 0, sizeof ss); if ((error = dns_pton(af, root_hints[i].addr, dns_sa_addr(af, &ss, NULL)))) goto error; @@ -10866,6 +10869,7 @@ static int send_query(int argc, char *argv[]) { struct dns_socket *so; int error, type; + memset(&ss, 0, sizeof ss); if (argc > 1) { ss.ss_family = (strchr(argv[1], ':'))? AF_INET6 : AF_INET; ----------------------------------------------------------------------- Summary of changes: dirmngr/dns.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 15 08:38:51 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 15 Jun 2018 08:38:51 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-26-g39ab613 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 39ab613bc5fa359ab3039ec3c84aed734c1d9f29 (commit) via 26d0b30ccf6b578db41ab37a4da181ce8194f7d9 (commit) from 11b39fb70f149afcbed8e252fe5ec56212edfc3e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 39ab613bc5fa359ab3039ec3c84aed734c1d9f29 Author: Andre Heinecke Date: Fri Jun 15 08:38:01 2018 +0200 po: Update formatting of pt/de * po/de.po, po/pt.po: Update formatting. diff --git a/po/de.po b/po/de.po index f58d282..83391a4 100644 --- a/po/de.po +++ b/po/de.po @@ -581,8 +581,8 @@ msgstr "Unsignierte S/MIME Mails sind nicht integrit?tsgesch?tzt." #: src/mailitem-events.cpp:787 msgid "For security reasons no decrypted contents are included in this reply." msgstr "" -"Aus Sicherheitsgr?nden werden keine entschl?sselte Inhalte in die Antwort" -" aufgenommen." +"Aus Sicherheitsgr?nden werden keine entschl?sselte Inhalte in die Antwort " +"aufgenommen." #: src/mailitem-events.cpp:792 msgid "" @@ -647,8 +647,8 @@ msgid "" "Data is not integrity protected. Decrypting it could be a security problem. " "(no MDC)" msgstr "" -"Daten sind nicht integrit?tsgesch?tzt. Das Entschl?sseln k?nnte ein" -" Sicherheitsproblem sein. (Kein MDC)" +"Daten sind nicht integrit?tsgesch?tzt. Das Entschl?sseln k?nnte ein " +"Sicherheitsproblem sein. (Kein MDC)" #: src/parsecontroller.cpp:219 src/parsecontroller.cpp:295 msgid "Encrypted message (decryption not possible)" diff --git a/po/pt.po b/po/pt.po index a34bd3c..625f737 100644 --- a/po/pt.po +++ b/po/pt.po @@ -576,16 +576,16 @@ msgstr "Os e-mails S/MIME n?o assinados n?o t?m a integridade protegida." #: src/mailitem-events.cpp:787 msgid "For security reasons no decrypted contents are included in this reply." msgstr "" -"Por raz?es de seguran?a, os conte?dos desencriptados n?o s?o inclu?dos nesta" -" resposta." +"Por raz?es de seguran?a, os conte?dos desencriptados n?o s?o inclu?dos nesta " +"resposta." #: src/mailitem-events.cpp:792 msgid "" "For security reasons no decrypted contents are included in the forwarded " "mail." msgstr "" -"Por raz?es de seguran?a, os conte?dos desencriptados n?o s?o inclu?dos no" -" e-mail encaminhado." +"Por raz?es de seguran?a, os conte?dos desencriptados n?o s?o inclu?dos no e-" +"mail encaminhado." #: src/mailitem-events.cpp:847 msgid "" @@ -640,8 +640,8 @@ msgid "" "Data is not integrity protected. Decrypting it could be a security problem. " "(no MDC)" msgstr "" -"Os dados n?o t?m a integridade protegida. Desencriptar poder? ser um problema" -" de seguran?a. (sem MDC)" +"Os dados n?o t?m a integridade protegida. Desencriptar poder? ser um " +"problema de seguran?a. (sem MDC)" #: src/parsecontroller.cpp:219 src/parsecontroller.cpp:295 msgid "Encrypted message (decryption not possible)" commit 26d0b30ccf6b578db41ab37a4da181ce8194f7d9 Author: Andre Heinecke Date: Fri Jun 15 08:36:33 2018 +0200 Add ukrainian translation * po/uk.po: New. * po/LINGUAS: Add it. -- Translation provided by Yuri Chornoivan. Thanks! diff --git a/po/LINGUAS b/po/LINGUAS index 343d8de..ecafe68 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -4,5 +4,6 @@ sv pt fr nl +uk zh_CN zh_TW diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..374f9c5 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,760 @@ +# uk.po - Ukrainian translation for GpgOL +# Copyright (C) 2005, 2007 g10 Code GmbH +# This file is distributed under the same license as the GpgOL package. +# +# Yuri Chornoivan , 2018. +msgid "" +msgstr "" +"Project-Id-Version: GpgOL 1.0.0\n" +"Report-Msgid-Bugs-To: bug-gpgol at g10code.com\n" +"POT-Creation-Date: 2018-06-12 11:16+0200\n" +"PO-Revision-Date: 2018-06-12 19:38+0200\n" +"Last-Translator: Yuri Chornoivan \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: src/addin-options.cpp:41 +msgid "General" +msgstr "????????" + +#: src/addin-options.cpp:42 +msgid "Enable the S/MIME support" +msgstr "????????? ????????? S/MIME" + +#: src/addin-options.cpp:44 +msgid "Message sending" +msgstr "?????????? ????????????" + +#: src/addin-options.cpp:45 +msgid "&Encrypt new messages by default" +msgstr "?????? &????????? ???? ????????????" + +#: src/addin-options.cpp:46 +msgid "&Sign new messages by default" +msgstr "?????? &??????????? ???? ????????????" + +#: src/addin-options.cpp:47 +msgid "&Send OpenPGP mails without attachments as PGP/Inline" +msgstr "&????????? ???????????? OpenPGP ??? ???????? ?? PGP/Inline" + +#: src/addin-options.cpp:49 +msgid "S&elect crypto settings automatically for reply and forward" +msgstr "??????????? ??&????? ????????? ???????????? ??? ????????? ? ?????????" + +#: src/addin-options.cpp:51 +msgid "&Resolve recipient keys automatically" +msgstr "??????????? ??&??????? ????? ???????????" + +#: src/addin-options.cpp:54 +msgid "Debug..." +msgstr "????????????" + +#: src/addin-options.cpp:55 +msgid "Configure GnuPG" +msgstr "??????????? GnuPG" + +#: src/addin-options.cpp:56 +msgid "Version " +msgstr "?????? " + +#: src/addin-options.cpp:114 src/ribbon-callbacks.cpp:665 +msgid "" +"Could not find Kleopatra.\n" +"Please reinstall Gpg4win with the Kleopatra component enabled." +msgstr "" +"?? ??????? ?????? Kleopatra.\n" +"???? ?????, ???????? ?????????? Gpg4win, ?????????? ???????????? ?????????? " +"Kleopatra." + +#: src/addin-options.cpp:116 src/gpgoladdin.cpp:375 src/gpgoladdin.cpp:897 +#: src/gpgoladdin.cpp:932 src/gpgoladdin.cpp:1016 src/gpgoladdin.cpp:1018 +#: src/gpgoladdin.cpp:1055 src/mail.cpp:837 src/mail.cpp:1126 src/mail.cpp:1195 +#: src/mailitem-events.cpp:778 src/mailitem-events.cpp:797 src/main.c:371 +#: src/ribbon-callbacks.cpp:604 src/ribbon-callbacks.cpp:615 +#: src/ribbon-callbacks.cpp:667 src/wks-helper.cpp:442 +#: src/cryptcontroller.cpp:299 +msgid "GpgOL" +msgstr "GpgOL" + +#: src/common.c:239 +msgid "GpgOL - Save attachment" +msgstr "GpgOL ? ?????????? ?????????" + +#: src/common.c:1073 +msgid "GpgOL Error" +msgstr "??????? GpgOL" + +#: src/config-dialog.c:38 +msgid "Debug output (for analysing problems)" +msgstr "???????????? ???? (??? ??????? ???????)" + +#: src/gpgoladdin.cpp:507 src/mail.cpp:1934 src/mail.cpp:2005 +msgid "GpgOL: Encrypted Message" +msgstr "GpgOL: ??????????? ????????????" + +#: src/gpgoladdin.cpp:508 src/mail.cpp:1935 src/mail.cpp:2006 +msgid "GpgOL: Trusted Sender Address" +msgstr "GpgOL: ???????? ?????? ???????????" + +#: src/gpgoladdin.cpp:833 +msgid "Encrypt the message" +msgstr "??????????? ????????????" + +#: src/gpgoladdin.cpp:835 +msgid "Encrypts the message and all attachments before sending" +msgstr "??????????? ???????????? ? ??? ????????? ?? ????? ?? ??????????" + +#: src/gpgoladdin.cpp:837 +msgid "Sign the message" +msgstr "????????? ????????????" + +#: src/gpgoladdin.cpp:839 +msgid "Sign the message and all attachments before sending" +msgstr "????????? ???????????? ? ??? ????????? ?? ????? ?? ??????????" + +#: src/gpgoladdin.cpp:842 +msgid "Sign and encrypt the message" +msgstr "????????? ? ??????????? ????????????" + +#: src/gpgoladdin.cpp:844 +msgid "" +"Encrypting and cryptographically signing a message means that the recipients " +"can be sure that no one modified the message and only the recipients can " +"read it" +msgstr "" +"?????????? ?? ?????????????? ???????????? ???????????? ???????, ?? " +"?????????? ??????? ???? ?????, ?? ????? ?? ?????? ???? ?? ????????????. ???? " +"??????? ???? ?????????? ??????? ????????? ????????? ????????????." + +#: src/gpgoladdin.cpp:848 +msgid "Open the settings dialog for GpgOL" +msgstr "???????? ????????? ????? ?????????? GpgOL" + +#: src/gpgoladdin.cpp:898 src/gpgoladdin.cpp:1019 +msgid "Secure" +msgstr "????????" + +#: src/gpgoladdin.cpp:899 src/gpgoladdin.cpp:1020 +msgid "Sign" +msgstr "?????????" + +#: src/gpgoladdin.cpp:900 src/gpgoladdin.cpp:1021 +msgid "Encrypt" +msgstr "???????????" + +#: src/gpgoladdin.cpp:1023 +msgid "&Print decrypted" +msgstr "&??????????? ????????????" + +#: src/mail.cpp:324 +msgid "" +"Not all attachments were encrypted or signed.\n" +"The unsigned / unencrypted attachments are:\n" +"\n" +msgstr "" +"?? ??? ????????? ??????????? ??? ?????????.\n" +"????????????? ??? ??????????????? ??????????? ? ????:\n" +"\n" + +#: src/mail.cpp:329 +msgid "" +"Not all attachments were signed.\n" +"The unsigned attachments are:\n" +"\n" +msgstr "" +"?? ??? ????????? ?????????.\n" +"????????????? ??????????? ? ????:\n" +"\n" + +#: src/mail.cpp:334 +msgid "" +"Not all attachments were encrypted.\n" +"The unencrypted attachments are:\n" +"\n" +msgstr "" +"?? ??? ????????? ???????????.\n" +"??????????????? ??????????? ? ????:\n" +"\n" + +#: src/mail.cpp:374 +msgid "" +"Note: The attachments may be encrypted or signed on a file level but the " +"GpgOL status does not apply to them." +msgstr "" +"??????????: ????????? ???? ???? ??????????? ??? ????????? ?? ????? ??????, " +"??? ?? ?? ?????????? ????? ? GpgOL." + +#: src/mail.cpp:377 +msgid "GpgOL Warning" +msgstr "???????????? GpgOL" + +#: src/mail.cpp:835 +#, c-format +msgid "" +"Crypto operation failed:\n" +"%s" +msgstr "" +"??????? ??????????????? ???:\n" +"%s" + +#: src/mail.cpp:936 +msgid "Pubkey directory confirmation" +msgstr "????????????? ???????? ????????? ??????" + +#: src/mail.cpp:937 +msgid "" +"This is a confirmation request to publish your Pubkey in the directory for " +"your domain.\n" +"\n" +"

If you did not request to publish your Pubkey in your providers " +"directory, simply ignore this message.

\n" +msgstr "" +"?? ????? ???? ????????????? ???????????? ?????? ?????????? ????? ? ???????? " +"??? ?????? ??????.\n" +"\n" +"

???? ?? ?? ????????? ?????? ???? ???????????? ?????? ?????????? ????? ? " +"???????? ?????? ???????? ??????, ?????? ???????????? ?? ????????????.

\n" + +#: src/mail.cpp:945 +msgid "message" +msgstr "????????????" + +#: src/mail.cpp:946 +msgid "Please wait while the message is being decrypted / verified..." +msgstr "" +"???? ?????, ?????????, ???? ???????????? ???? ???????????? ??? ???????????" + +#: src/mail.cpp:1127 src/mail.cpp:1196 +msgid "HTML display disabled." +msgstr "????? HTML ????????." + +#: src/mail.cpp:1128 src/mail.cpp:1197 +msgid "HTML content in unsigned S/MIME mails is insecure." +msgstr "????? ????? HTML ? ???????????? ????????????? S/MIME ?? ? ?????????." + +#: src/mail.cpp:1131 src/mail.cpp:1200 +msgid "GpgOL will only show such mails as text." +msgstr "GpgOL ???????????? ???? ????? ? ????? ???????????." + +#: src/mail.cpp:1134 +msgid "This message is shown only once." +msgstr "?? ???????????? ???? ???????? ???? ???? ???." + +#: src/mail.cpp:1203 +msgid "" +"Please ask the sender to sign the message or\n" +"to send it with a plain text alternative." +msgstr "" +"???? ?????, ????????? ??????????? ????????? ????????????\n" +"??? ????????? ???? ? ??????? ???????? ??????." + +#: src/mail.cpp:1374 +msgid "GpgOL: Oops, G Suite Sync account detected" +msgstr "GpgOL: ??? ????, ???????? ????????? ????? G Suite Sync" + +#: src/mail.cpp:1376 +msgid "" +"G Suite Sync breaks outgoing crypto mails with attachments.\n" +"Using crypto and attachments with G Suite Sync is not supported.\n" +"\n" +"See: https://dev.gnupg.org/T3545 for details." +msgstr "" +"G Suite Sync ??????? ???????????? ???????? ??????????? ???????????.\n" +"????????? ???????????? ???????????? ? ?????????? ? G Suite Sync ?? " +"???????????.\n" +"\n" +"?????????? ??? ?? ???: https://dev.gnupg.org/T3545" + +#: src/mail.cpp:2194 +msgid "Security Level 4" +msgstr "?????? ??????? 4" + +#: src/mail.cpp:2198 +msgid "Trust Level 4" +msgstr "?????? ?????????? 4" + +#: src/mail.cpp:2202 +msgid "Security Level 3" +msgstr "?????? ??????? 3" + +#: src/mail.cpp:2206 +msgid "Trust Level 3" +msgstr "?????? ?????????? 3" + +#: src/mail.cpp:2210 +msgid "Security Level 2" +msgstr "?????? ??????? 2" + +#: src/mail.cpp:2214 +msgid "Trust Level 2" +msgstr "?????? ?????????? 2" + +#: src/mail.cpp:2218 +msgid "Encrypted" +msgstr "???????????" + +#: src/mail.cpp:2227 src/mail.cpp:2229 src/ribbon-callbacks.cpp:517 +msgid "Insecure" +msgstr "??????????" + +#: src/mail.cpp:2241 +msgid "Signed and encrypted message" +msgstr "????????? ? ??????????? ????????????" + +#: src/mail.cpp:2245 +msgid "Signed message" +msgstr "????????? ????????????" + +#: src/mail.cpp:2249 +msgid "Encrypted message" +msgstr "??????????? ????????????" + +#: src/mail.cpp:2252 src/ribbon-callbacks.cpp:540 +msgid "Insecure message" +msgstr "?????????? ????????????" + +#: src/mail.cpp:2263 src/mail.cpp:2274 +msgid "You cannot be sure who sent, modified and read the message in transit." +msgstr "" +"?? ?? ?????? ???? ????? ???? ????, ??? ????????, ?????? ?? ????? " +"???????????? ??? ??? ???????????." + +#: src/mail.cpp:2266 +msgid "The message was signed but the verification failed with:" +msgstr "???????????? ???? ?????????, ??? ???? ?? ??????? ?????????:" + +#: src/mail.cpp:2284 +msgid "The encryption was VS-NfD-compliant." +msgstr "?????????? ??????? ?? VS-NfD." + +#: src/mail.cpp:2288 +msgid "The encryption was not VS-NfD-compliant." +msgstr "?????????? ?? ??????? ?? VS-NfD." + +#: src/mail.cpp:2292 +msgid "You cannot be sure who sent the message because it is not signed." +msgstr "" +"?? ?? ?????? ???? ????? ????, ??? ???????? ?? ????????????, ???????? ???? ?? " +"?????????." + +#: src/mail.cpp:2315 +msgid "You signed this message." +msgstr "?? ????????? ?? ????????????." + +#: src/mail.cpp:2319 +msgid "The senders identity was certified by yourself." +msgstr "??????? ??????????? ????????????? ????." + +#: src/mail.cpp:2323 +msgid "The sender is allowed to certify identities for you." +msgstr "??????????? ????????? ????????????? ??????? ??? ???." + +#: src/mail.cpp:2336 +msgid "The senders identity was certified by several trusted people." +msgstr "??????? ??????????? ????????????? ?????????? ?????????? ???????." + +#: src/mail.cpp:2341 +#, c-format +msgid "" +"The senders identity is certified by the trusted issuer:\n" +"'%s'\n" +msgstr "" +"??????? ??????????? ????????????? ????????? ???????? ????????????:\n" +"?%s?\n" + +#: src/mail.cpp:2349 +msgid "Some trusted people have certified the senders identity." +msgstr "??????? ??????????? ????????????? ?????????? ?????????? ???????." + +#: src/mail.cpp:2359 +#, c-format +msgid "" +"The senders address is trusted, because you have established a communication " +"history with this address starting on %s.\n" +"You encrypted %i and verified %i messages since." +msgstr "" +"?????? ??????????? ? ?????? ??????, ???????? ???? ??????????? ??????? " +"??????????? ? ???, ????????? ? %s.\n" +"? ???? ???? ???? ??????????? %i ? ?????????? %i ???????????." + +#: src/mail.cpp:2375 +msgid "The senders signature was verified for the first time." +msgstr "?????? ??????????? ?????????? ??????." + +#: src/mail.cpp:2382 +#, c-format +msgid "" +"The senders address is not trustworthy yet because you only verified %i " +"messages and encrypted %i messages to it since %s." +msgstr "" +"?????? ??????????? ?? ? ?? ?????? ??????, ???????? ???? ?????????? %i " +"??????????? ?? ??????????? %i ??????????? ?? ????? ? %s." + +#: src/mail.cpp:2396 +msgid "But the sender address is not trustworthy because:" +msgstr "??? ?????? ??????????? ?? ? ?????? ??????, ????????:" + +#: src/mail.cpp:2397 +msgid "The sender address is not trustworthy because:" +msgstr "?????? ??????????? ?? ? ?????? ??????, ????????:" + +#: src/mail.cpp:2405 +msgid "The signature is invalid: \n" +msgstr "?????? ? ???????????: \n" + +#: src/mail.cpp:2410 +msgid "There was an error verifying the signature.\n" +msgstr "??? ??? ?????? ?????????? ?????? ??????? ???????.\n" + +#: src/mail.cpp:2419 +msgid "The signature is expired.\n" +msgstr "????? ??? ??????? ?????????.\n" + +#: src/mail.cpp:2423 +msgid "The used key" +msgstr "???????????? ????" + +#: src/mail.cpp:2423 +msgid "The used certificate" +msgstr "???????????? ??????????" + +#: src/mail.cpp:2431 +msgid "is not available." +msgstr "? ???????????." + +#: src/mail.cpp:2435 +msgid "is revoked." +msgstr "??????????." + +#: src/mail.cpp:2439 +msgid "is expired." +msgstr ", ????? ??? ?????????." + +#: src/mail.cpp:2443 +msgid "is not meant for signing." +msgstr "?? ?????????? ??? ????????????." + +#: src/mail.cpp:2447 src/mail.cpp:2451 +msgid "could not be checked for revocation." +msgstr "?? ???? ???? ?????????? ?? ???????????." + +#: src/mail.cpp:2456 +msgid "is not the same as the key that was used for this address in the past." +msgstr "" +"?? ? ??? ?????, ?? ? ????, ???? ???????????????? ??? ???? ?????? ? ????????." + +#: src/mail.cpp:2462 +#, c-format +msgid "does not claim the address: \"%s\"." +msgstr "?? ?????????? ??????: ?%s?." + +#: src/mail.cpp:2475 +msgid "is not certified by any trustworthy key." +msgstr "?? ? ?????????????? ????-???? ?????? ?????? ??????." + +#: src/mail.cpp:2479 +msgid "" +"is not certified by a trustworthy Certificate Authority or the Certificate " +"Authority is unknown." +msgstr "" +"?? ?????????? ?????? ?????? ??????? ???????????? ??? ?????? ???????????? ? " +"?????????." + +#: src/mail.cpp:2484 +msgid "The sender marked this address as revoked." +msgstr "???????????? ????????? ?? ?????? ?? ??????????." + +#: src/mail.cpp:2488 +msgid "is marked as not trustworthy." +msgstr "????????? ?? ?? ????? ??????." + +#: src/mail.cpp:2498 +msgid "The signature is VS-NfD-compliant." +msgstr "?????? ? ???????? ?? VS-NfD." + +#: src/mail.cpp:2502 +msgid "The signature is not VS-NfD-compliant." +msgstr "?????? ?? ? ???????? ?? VS-NfD." + +#: src/mail.cpp:2510 +msgid "The encryption is VS-NfD-compliant." +msgstr "?????????? ? ???????? ?? VS-NfD." + +#: src/mail.cpp:2514 +msgid "The encryption is not VS-NfD-compliant." +msgstr "?????????? ?? ??????? ?? VS-NfD." + +#: src/mail.cpp:2525 +msgid "Click here to change the key used for this address." +msgstr "????????? ???, ??? ??????? ????, ???? ??????????? ??? ???? ??????." + +#: src/mail.cpp:2529 +msgid "Click here for details about the key." +msgstr "????????? ???, ??? ????????? ?????? ??? ????." + +#: src/mail.cpp:2530 +msgid "Click here for details about the certificate." +msgstr "????????? ???, ??? ????????? ?????? ??? ??????????." + +#: src/mail.cpp:2534 +msgid "Click here to search the key on the configured keyserver." +msgstr "????????? ???, ??? ???????? ???? ?? ????????????? ??????? ??????." + +#: src/mail.cpp:2535 +msgid "Click here to search the certificate on the configured X509 keyserver." +msgstr "" +"????????? ???, ??? ???????? ?????????? ?? ????????????? ??????? ?????? X509." + +#: src/mail.cpp:2859 +msgid "GpgOL: Encryption not possible!" +msgstr "GpgOL: ?????????? ?????????!" + +#: src/mail.cpp:2861 +msgid "" +"Outlook returned an error when trying to send the encrypted mail.\n" +"\n" +"Please restart Outlook and try again.\n" +"\n" +"If it still fails consider using an encrypted attachment or\n" +"switching to PGP/Inline in GpgOL's options." +msgstr "" +"???????? Outlook ????????? ??????? ??? ??? ?????? ????????? ??????????? " +"????????????.\n" +"\n" +"???? ?????, ????????????? Outlook ? ????????? ??????.\n" +"\n" +"???? ?? ???????????? ???? ???????? ?????, ????????? ???????????? " +"????????????\n" +"?????????? ????? ??? ???????????? ?? PGP/Inline ? ?????????? GpgOL." + +#: src/mailitem-events.cpp:315 src/mailitem-events.cpp:850 +msgid "Sorry, that's not possible, yet" +msgstr "???????, ?? ?? ?????????" + +#: src/mailitem-events.cpp:317 +#, c-format +msgid "" +"GpgOL has prevented the change to the \"%s\" property.\n" +"Property changes are not yet handled for crypto messages.\n" +"\n" +"To workaround this limitation please change the property when the message is " +"not open in any window and not selected in the messagelist.\n" +"\n" +"For example by right clicking but not selecting the message.\n" +msgstr "" +"???????? GpgOL ????????? ????? ??????????? ?%s?.\n" +"??? ??????????????? ??????????? ??????? ????? ???????????? ?? ?? " +"???????????.\n" +"\n" +"??? ?????? ?? ?????????, ???? ?????, ??????? ???????????, ???? ???????????? " +"?? ???? ???????? ? ??????? ????? ? ?? ???? ????????? ? ?????? ???????????.\n" +"\n" +"?????????, ????? ???????? ?????? ??????? ???? ?? ????????????, ?? ?????????? " +"????.\n" + +#: src/mailitem-events.cpp:779 +msgid "Dangerous reply" +msgstr "?????????? ?????????" + +#: src/mailitem-events.cpp:780 +msgid "Dangerous forward" +msgstr "?????????? ?????????????????" + +#: src/mailitem-events.cpp:781 +msgid "Unsigned S/MIME mails are not integrity protected." +msgstr "?????????? ??????????? S/MIME ??? ??????? ?? ????????." + +#: src/mailitem-events.cpp:787 +msgid "For security reasons no decrypted contents are included in this reply." +msgstr "" +"? ????????? ???????, ?? ???? ????????? ?? ???????? ????????????? ?????." + +#: src/mailitem-events.cpp:792 +msgid "" +"For security reasons no decrypted contents are included in the forwarded " +"mail." +msgstr "" +"? ????????? ???????, ?? ????? ???????????????? ???????????? ?? ???????? " +"????????????? ?????." + +#: src/mailitem-events.cpp:847 +msgid "" +"Attachments are part of the crypto message.\n" +"They can't be permanently removed and will be shown again the next time this " +"message is opened." +msgstr "" +"????????? ? ???????? ???????????????? ????????????.\n" +"?? ?? ????? ????????? ???????? ? ?? ????? ???? ???????? ??? ??? ?????????? " +"????????? ????????????." + +#: src/main.c:370 +#, c-format +msgid "Note: Using compatibility flags: %s" +msgstr "??????????: ?????????????? ???????? ??????????: %s" + +#: src/mapihelp.cpp:1917 src/mapihelp.cpp:1925 src/mapihelp.cpp:1933 +msgid "[no subject]" +msgstr "[??? ????]" + +#: src/mapihelp.cpp:3366 +msgid "" +"[The content of this message is not visible due to an processing error in " +"GpgOL.]" +msgstr "" +"[????? ????? ???????????? ?? ????????, ???????? ??? ??? ???? ??????? ? GpgOL " +"??????? ???????.]" + +#: src/parsecontroller.cpp:164 +msgid "Unknown Key:" +msgstr "????????? ????:" + +#: src/parsecontroller.cpp:179 +msgid "Decryption canceled or timed out." +msgstr "" +"??????????????? ????????? ??? ?????????? ??? ?????????? ?? ???????????????." + +#: src/parsecontroller.cpp:193 +msgid "" +"No secret key found to decrypt the message. It is encrypted to the following " +"keys:" +msgstr "" +"?? ???????? ????????? ????? ??? ??????????????? ????????????. ???????????? " +"??????????? ??? ????? ??????:" + +#: src/parsecontroller.cpp:199 +msgid "Could not decrypt the data: " +msgstr "?? ??????? ???????????? ????: " + +#: src/parsecontroller.cpp:203 +msgid "Failed to parse the mail." +msgstr "?? ??????? ???????? ????????????." + +#: src/parsecontroller.cpp:207 +msgid "" +"Data is not integrity protected. Decrypting it could be a security problem. " +"(no MDC)" +msgstr "" +"?????????? ????? ?? ????????. ??????????????? ??? ????? ???? ????????? " +"??????? ??????? ???????. (????? MDC)" + +#: src/parsecontroller.cpp:219 src/parsecontroller.cpp:295 +msgid "Encrypted message (decryption not possible)" +msgstr "??????????? ???????????? (????????????? ?????????)" + +#: src/parsecontroller.cpp:296 +msgid "" +"Failed to find GnuPG please ensure that GnuPG or Gpg4win is properly " +"installed." +msgstr "" +"?? ??????? ?????? GnuPG. ???? ?????, ?????????????, ?? GnuPG ??? Gpg4win " +"??????????? ???????? ?????." + +#: src/ribbon-callbacks.cpp:544 +msgid "No message selected" +msgstr "?? ????????? ??????? ????????????" + +#: src/ribbon-callbacks.cpp:601 +#, c-format +msgid "" +"The message was not cryptographically signed.\n" +"There is no additional information available if it was actually sent by '%s' " +"or if someone faked the sender address." +msgstr "" +"???????????? ?? ???? ?????????????? ?????????.\n" +"????? ?????? ?????????? ?????, ??? ?????????????? ? ???? ?????????? ?%s?. " +"???????, ????? ?????????? ?????? ???????????." + +#: src/ribbon-callbacks.cpp:612 +msgid "" +"There was an error verifying the signature.\n" +"Full details:\n" +msgstr "" +"??? ??? ?????? ?????????? ?????? ??????? ???????.\n" +"?????????:\n" + +#: src/wks-helper.cpp:404 +msgid "" +"A Pubkey directory is available for your domain.\n" +"\n" +"Register your Pubkey in that directory to make\n" +"it easy for others to send you encrypted mail.\n" +"\n" +"It's secure and free!\n" +"\n" +"Register automatically?" +msgstr "" +"??? ?????? ?????? ????????? ??????? ????????? ??????.\n" +"\n" +"???????????? ??? ????????? ???? ? ????? ????????, ???\n" +"????????? ?????????? ??? ???????????? ???????????\n" +"?????? ?????????????.\n" +"\n" +"?? ???????? ? ???????????!\n" +"\n" +"??????????????? ????????????" + +#: src/wks-helper.cpp:409 +msgid "GpgOL: Pubkey directory available!" +msgstr "GpgOL: ????????? ??????? ????????? ??????!" + +#: src/wks-helper.cpp:491 +msgid "GpgOL: Directory request failed" +msgstr "GpgOL: ??????? ??? ??? ?????? ???? ????????" + +#: src/wks-helper.cpp:504 +msgid "" +"You might receive a confirmation challenge from\n" +"your provider to finish the registration." +msgstr "" +"????????, ?? ????????? ???????? ???? ????????????? ???\n" +"?????? ???????? ?????? ??? ?????????? ??????????." + +#: src/wks-helper.cpp:506 +msgid "GpgOL: Registration request sent!" +msgstr "GpgOL: ????????? ????? ???? ??????????!" + +#: src/wks-helper.cpp:693 +msgid "Confirm registration?" +msgstr "??????????? ???????????" + +#: src/wks-helper.cpp:694 +msgid "GpgOL: Pubkey directory confirmation" +msgstr "GpgOL: ????????????? ???????? ????????? ??????" + +#: src/wks-helper.cpp:747 +msgid "GpgOL: Confirmation failed" +msgstr "GpgOL: ??????? ??? ??? ?????? ?????????????" + +#: src/wks-helper.cpp:759 +msgid "Your Pubkey can soon be retrieved from your domain." +msgstr "???????? ??? ????????? ???? ????? ???? ???????? ? ?????? ??????." + +#: src/wks-helper.cpp:760 +msgid "GpgOL: Request confirmed!" +msgstr "GpgOL: ????? ????????????!" + +#: src/cryptcontroller.cpp:298 +msgid "No recipients for encryption selected." +msgstr "?? ??????? ??????? ?????????? ??? ??????????." + +#: src/cryptcontroller.cpp:407 +msgid "Resolving recipients..." +msgstr "?????????? ????????????" + +#: src/cryptcontroller.cpp:411 +msgid "Resolving signers..." +msgstr "?????????? ????????????" + +#: src/cryptcontroller.cpp:1063 +msgid "Encrypting..." +msgstr "?????????????" + +#: src/cryptcontroller.cpp:1067 +msgid "Signing..." +msgstr "???????????" ----------------------------------------------------------------------- Summary of changes: po/LINGUAS | 1 + po/de.po | 8 +- po/pt.po | 12 +- po/uk.po | 760 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 771 insertions(+), 10 deletions(-) create mode 100644 po/uk.po hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 06:39:21 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 17 Jun 2018 06:39:21 +0200 Subject: [git] GPGME - branch, gsoc/jacob-key-import, created. gpgme-1.11.1-60-g5a80e75 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, gsoc/jacob-key-import has been created at 5a80e755008bbb3f4c7f91ffccd38f26cd8b3960 (commit) - Log ----------------------------------------------------------------- commit 5a80e755008bbb3f4c7f91ffccd38f26cd8b3960 Author: Ben McGinnes Date: Sun Jun 17 14:35:20 2018 +1000 python bindings: core - key import * Wrapped the key import function in the try/exception statements needed to catch at least the most likely unsuccessful import attempt errors. * Mostly draws on the file error and no data import statuses for errors, with a couple of exceptions. Signed-off-by: Ben McGinnes diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 1b83a5d..06be7f7 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -515,18 +515,46 @@ class Context(GpgmeWrapper): Imports the given data into the Context. Returns: - result -- information about the imported data + -- an object describing the results of imported or updated + keys Raises: - GPGMEError -- as signaled by the underlying library - ValueError -- Raised if no keys are present in the data - + TypeError -- Very rarely. + GPGMEError -- as signaled by the underlying library: + + Import status errors, when they occur, will usually + be of NODATA. NO_PUBKEY indicates something + managed to run the function without any + arguments, while an argument of None triggers + the first NODATA of errors.GPGME in the + exception. """ - self.op_import(data) - result = self.op_import_result() - if result.considered == 0: - raise ValueError - return result + try: + self.op_import(data) + result = self.op_import_result() + if result.considered == 0: + status = constants.STATUS_IMPORT_PROBLEM + else: + status = constants.STATUS_KEY_CONSIDERED + except Exception as e: + if e == errors.GPGMEError: + if e.code_str == "No data": + status = constants.STATUS_NODATA + else: + status = constants.STATUS_FILE_ERROR + elif e == TypeError and hasattr(data, "decode") is True: + status = constants.STATUS_NO_PUBKEY + elif e == TypeError and hasattr(data, "encode") is True: + status = constants.STATUS_FILE_ERROR + else: + status = constants.STATUS_ERROR + + if status == constants.STATUS_KEY_CONSIDERED: + import_result = result + else: + import_result = status + + return import_result def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, commit 0e762608ef5a598030b8d0e56261a830e1b7b724 Author: Ben McGinnes Date: Sun Jun 17 09:28:30 2018 +1000 python bindings: core key import * The foundation of a pythonic key import function authored by Jacob Adams. * A unit testing script for the same function originally authored by Tobias Mueller * Added DCO reference for Jacob Adams to the GPGME AUTHORS file. * Additional details regarding this patch are available here: https://dev.gnupg.org/T4001 Signed-off-by: Ben McGinnes diff --git a/AUTHORS b/AUTHORS index 1bd3209..e0136ff 100644 --- a/AUTHORS +++ b/AUTHORS @@ -62,6 +62,9 @@ Tobias Mueller Ben McGinnes 2017-12-16:20171216002102.l6aejk5xdp6xhtfi at adversary.org: +Jacob Adams +2018-06-03:ad5141df-b6cc-6c2a-59df-b2f18f7160fd at gmail.com: + Copyright 2001, 2002, 2012, 2013 g10 Code GmbH diff --git a/lang/python/src/core.py b/lang/python/src/core.py index bd95d23..1b83a5d 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -509,6 +509,25 @@ class Context(GpgmeWrapper): return results + def key_import(self, data): + """Import data + + Imports the given data into the Context. + + Returns: + result -- information about the imported data + + Raises: + GPGMEError -- as signaled by the underlying library + ValueError -- Raised if no keys are present in the data + + """ + self.op_import(data) + result = self.op_import_result() + if result.considered == 0: + raise ValueError + return result + def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, source=None): diff --git a/lang/python/tests/t-import.py b/lang/python/tests/t-import.py index e2edf5a..44dc360 100755 --- a/lang/python/tests/t-import.py +++ b/lang/python/tests/t-import.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (C) 2016 g10 Code GmbH +# Copyright (C) 2016 Tobias Mueller # # This file is part of GPGME. # @@ -69,10 +69,14 @@ def check_result(result, fpr, secret): c = gpg.Context() -c.op_import(gpg.Data(file=support.make_filename("pubkey-1.asc"))) -result = c.op_import_result() +result = c.key_import(open(support.make_filename("pubkey-1.asc"), 'rb').read()) check_result(result, "ADAB7FCC1F4DE2616ECFA402AF82244F9CD9FD55", False) -c.op_import(gpg.Data(file=support.make_filename("seckey-1.asc"))) -result = c.op_import_result() +result = c.key_import(open(support.make_filename("seckey-1.asc"), 'rb').read()) check_result(result, "ADAB7FCC1F4DE2616ECFA402AF82244F9CD9FD55", True) + +try: + result = c.key_import(b"thisisnotakey") +except ValueError: + pass +assert result.considered == 0 ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 08:01:29 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 17 Jun 2018 08:01:29 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-61-ga5b24ae Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via a5b24ae46c81d3abd3bb18bf0390cab6ebb2bd77 (commit) via 5a80e755008bbb3f4c7f91ffccd38f26cd8b3960 (commit) via 0e762608ef5a598030b8d0e56261a830e1b7b724 (commit) from 92cd060f5e2f4fdbfbe4812ebe8ef57e82e1609f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a5b24ae46c81d3abd3bb18bf0390cab6ebb2bd77 Author: Ben McGinnes Date: Sun Jun 17 15:58:44 2018 +1000 python bindings: core ? PEP8 compliance * Fixed most of the PEP8 errors in core.py * Those remaining may need more than little edits and are a bit strange (too clearly the result of a programmer who has spent far too much time dealing with Lisp so that for Python it looks ... strange). diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 06be7f7..33a1c70 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -1,3 +1,19 @@ +# -*- coding: utf-8 -*- + +import re +import os +import warnings +import weakref + +from . import gpgme +from .errors import errorcheck, GPGMEError +from . import constants +from . import errors +from . import util + +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + # Copyright (C) 2016-2017 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # Copyright (C) 2002 John Goerzen @@ -24,18 +40,6 @@ and the 'Data' class describing buffers of data. """ -from __future__ import absolute_import, print_function, unicode_literals -del absolute_import, print_function, unicode_literals - -import re -import os -import warnings -import weakref -from . import gpgme -from .errors import errorcheck, GPGMEError -from . import constants -from . import errors -from . import util class GpgmeWrapper(object): """Base wrapper class @@ -64,7 +68,7 @@ class GpgmeWrapper(object): return hash(repr(self.wrapped)) def __eq__(self, other): - if other == None: + if other is None: return False else: return repr(self.wrapped) == repr(other.wrapped) @@ -102,8 +106,10 @@ class GpgmeWrapper(object): "{}get_{}".format(self._cprefix, key)) set_func = getattr(gpgme, "{}set_{}".format(self._cprefix, key)) + def get(slf): return bool(get_func(slf.wrapped)) + def set_(slf, value): set_func(slf.wrapped, bool(value)) @@ -116,9 +122,10 @@ class GpgmeWrapper(object): return get(self) _munge_docstring = re.compile(r'gpgme_([^(]*)\(([^,]*), (.*\) -> .*)') + def __getattr__(self, key): """On-the-fly generation of wrapper methods and properties""" - if key[0] == '_' or self._cprefix == None: + if key[0] == '_' or self._cprefix is None: return None if key in self._boolean_properties: @@ -160,6 +167,7 @@ class GpgmeWrapper(object): else: super(GpgmeWrapper, self).__setattr__(key, value) + class Context(GpgmeWrapper): """Context for cryptographic operations @@ -212,7 +220,7 @@ class Context(GpgmeWrapper): Helper function to retrieve the results of an operation, or None if SINK is given. """ - if sink or data == None: + if sink or data is None: return None data.seek(0, os.SEEK_SET) return data.read() @@ -267,10 +275,11 @@ class Context(GpgmeWrapper): flags |= expect_sign * constants.ENCRYPT_EXPECT_SIGN flags |= (not compress) * constants.ENCRYPT_NO_COMPRESS - if passphrase != None: + if passphrase is not None: old_pinentry_mode = self.pinentry_mode old_passphrase_cb = getattr(self, '_passphrase_cb', None) self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK + def passphrase_cb(hint, desc, prev_bad, hook=None): return passphrase self.set_passphrase_cb(passphrase_cb) @@ -301,7 +310,7 @@ class Context(GpgmeWrapper): e.results = results raise e finally: - if passphrase != None: + if passphrase is not None: self.pinentry_mode = old_pinentry_mode if old_passphrase_cb: self.set_passphrase_cb(*old_passphrase_cb[1:]) @@ -344,10 +353,11 @@ class Context(GpgmeWrapper): """ plaintext = sink if sink else Data() - if passphrase != None: + if passphrase is not None: old_pinentry_mode = self.pinentry_mode old_passphrase_cb = getattr(self, '_passphrase_cb', None) self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK + def passphrase_cb(hint, desc, prev_bad, hook=None): return passphrase self.set_passphrase_cb(passphrase_cb) @@ -365,7 +375,7 @@ class Context(GpgmeWrapper): result, verify_result) raise e finally: - if passphrase != None: + if passphrase is not None: self.pinentry_mode = old_pinentry_mode if old_passphrase_cb: self.set_passphrase_cb(*old_passphrase_cb[1:]) @@ -382,7 +392,7 @@ class Context(GpgmeWrapper): for s in verify_result.signatures): raise errors.BadSignatures(verify_result, results=results) - if verify and verify != True: + if not verify: # was: if verify and verify != True: missing = list() for key in verify: ok = False @@ -515,14 +525,14 @@ class Context(GpgmeWrapper): Imports the given data into the Context. Returns: - -- an object describing the results of imported or updated + -- an object describing the results of imported or updated keys Raises: TypeError -- Very rarely. GPGMEError -- as signaled by the underlying library: - Import status errors, when they occur, will usually + Import status errors, when they occur, will usually be of NODATA. NO_PUBKEY indicates something managed to run the function without any arguments, while an argument of None triggers @@ -592,8 +602,8 @@ class Context(GpgmeWrapper): self.op_keylist_end() def create_key(self, userid, algorithm=None, expires_in=0, expires=True, - sign=False, encrypt=False, certify=False, authenticate=False, - passphrase=None, force=False): + sign=False, encrypt=False, certify=False, + authenticate=False, passphrase=None, force=False): """Create a primary key Create a primary key for the user id USERID. @@ -630,9 +640,10 @@ class Context(GpgmeWrapper): encrypt -- request the encryption capability (see above) certify -- request the certification capability (see above) authenticate -- request the authentication capability (see above) - passphrase -- protect the key with a passphrase (default: no passphrase) - force -- force key creation even if a key with the same userid exists - (default: False) + passphrase -- protect the key with a passphrase (default: no + passphrase) + force -- force key creation even if a key with the same userid + exists (default: False) Returns: -- an object describing the result of the key creation @@ -645,20 +656,21 @@ class Context(GpgmeWrapper): old_pinentry_mode = self.pinentry_mode old_passphrase_cb = getattr(self, '_passphrase_cb', None) self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK + def passphrase_cb(hint, desc, prev_bad, hook=None): return passphrase self.set_passphrase_cb(passphrase_cb) try: self.op_createkey(userid, algorithm, - 0, # reserved + 0, # reserved expires_in, - None, # extrakey + None, # extrakey ((constants.create.SIGN if sign else 0) | (constants.create.ENCR if encrypt else 0) | (constants.create.CERT if certify else 0) | (constants.create.AUTH if authenticate else 0) - | (constants.create.NOPASSWD if passphrase == None else 0) + | (constants.create.NOPASSWD if passphrase is None else 0) | (0 if expires else constants.create.NOEXPIRE) | (constants.create.FORCE if force else 0))) finally: @@ -670,7 +682,8 @@ class Context(GpgmeWrapper): return self.op_genkey_result() def create_subkey(self, key, algorithm=None, expires_in=0, expires=True, - sign=False, encrypt=False, authenticate=False, passphrase=None): + sign=False, encrypt=False, authenticate=False, + passphrase=None): """Create a subkey Create a subkey for the given KEY. As subkeys are a concept @@ -706,7 +719,8 @@ class Context(GpgmeWrapper): sign -- request the signing capability (see above) encrypt -- request the encryption capability (see above) authenticate -- request the authentication capability (see above) - passphrase -- protect the subkey with a passphrase (default: no passphrase) + passphrase -- protect the subkey with a passphrase (default: no + passphrase) Returns: -- an object describing the result of the subkey creation @@ -719,19 +733,20 @@ class Context(GpgmeWrapper): old_pinentry_mode = self.pinentry_mode old_passphrase_cb = getattr(self, '_passphrase_cb', None) self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK + def passphrase_cb(hint, desc, prev_bad, hook=None): return passphrase self.set_passphrase_cb(passphrase_cb) try: self.op_createsubkey(key, algorithm, - 0, # reserved + 0, # reserved expires_in, ((constants.create.SIGN if sign else 0) | (constants.create.ENCR if encrypt else 0) | (constants.create.AUTH if authenticate else 0) | (constants.create.NOPASSWD - if passphrase == None else 0) + if passphrase is None else 0) | (0 if expires else constants.create.NOEXPIRE))) finally: if util.is_a_string(passphrase): @@ -792,8 +807,8 @@ class Context(GpgmeWrapper): """ flags = 0 - if uids == None or util.is_a_string(uids): - pass#through unchanged + if uids is None or util.is_a_string(uids): + pass # through unchanged else: flags |= constants.keysign.LFSEP uids = "\n".join(uids) @@ -883,10 +898,10 @@ class Context(GpgmeWrapper): GPGMEError -- as signaled by the underlying library """ - if key == None: + if key is None: raise ValueError("First argument cannot be None") - if sink == None: + if sink is None: sink = Data() if fnc_value: @@ -904,6 +919,7 @@ class Context(GpgmeWrapper): def signers(self): """Keys used for signing""" return [self.signers_enum(i) for i in range(self.signers_count())] + @signers.setter def signers(self, signers): old = self.signers @@ -919,6 +935,7 @@ class Context(GpgmeWrapper): def pinentry_mode(self): """Pinentry mode""" return self.get_pinentry_mode() + @pinentry_mode.setter def pinentry_mode(self, value): self.set_pinentry_mode(value) @@ -927,6 +944,7 @@ class Context(GpgmeWrapper): def protocol(self): """Protocol to use""" return self.get_protocol() + @protocol.setter def protocol(self, value): errorcheck(gpgme.gpgme_engine_check_version(value)) @@ -936,6 +954,7 @@ class Context(GpgmeWrapper): def home_dir(self): """Engine's home directory""" return self.engine_info.home_dir + @home_dir.setter def home_dir(self, value): self.set_engine_info(self.protocol, home_dir=value) @@ -948,25 +967,15 @@ class Context(GpgmeWrapper): # The list of functions is created using: # # $ grep '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \ - # | grep -v _op_ | awk "/\(gpgme_ctx/ { printf (\"'%s',\\n\", \$2) } " - return ((name.startswith('gpgme_op_') - and not name.endswith('_result')) - or name in { - 'gpgme_new', - 'gpgme_set_ctx_flag', - 'gpgme_set_protocol', - 'gpgme_set_sub_protocol', - 'gpgme_set_keylist_mode', - 'gpgme_set_pinentry_mode', - 'gpgme_set_locale', - 'gpgme_ctx_set_engine_info', - 'gpgme_signers_add', - 'gpgme_sig_notation_add', - 'gpgme_set_sender', - 'gpgme_cancel', - 'gpgme_cancel_async', - 'gpgme_get_key', - }) + # | grep -v _op_ | awk "/\(gpgme_ctx/ { printf (\"'%s',\\n\", \$2) } " + return ((name.startswith('gpgme_op_') and not + name.endswith('_result')) or name in {'gpgme_new', + 'gpgme_set_ctx_flag', 'gpgme_set_protocol', + 'gpgme_set_sub_protocol', 'gpgme_set_keylist_mode', + 'gpgme_set_pinentry_mode', 'gpgme_set_locale', + 'gpgme_ctx_set_engine_info', 'gpgme_signers_add', + 'gpgme_sig_notation_add', 'gpgme_set_sender', 'gpgme_cancel', + 'gpgme_cancel_async', 'gpgme_get_key'}) _boolean_properties = {'armor', 'textmode', 'offline'} @@ -985,6 +994,7 @@ class Context(GpgmeWrapper): # Implement the context manager protocol. def __enter__(self): return self + def __exit__(self, type, value, tb): self.__del__() @@ -1079,10 +1089,10 @@ class Context(GpgmeWrapper): Please see the GPGME manual for more information. """ - if func == None: + if func is None: hookdata = None else: - if hook == None: + if hook is None: hookdata = (weakref.ref(self), func) else: hookdata = (weakref.ref(self), func, hook) @@ -1104,10 +1114,10 @@ class Context(GpgmeWrapper): Please see the GPGME manual for more information. """ - if func == None: + if func is None: hookdata = None else: - if hook == None: + if hook is None: hookdata = (weakref.ref(self), func) else: hookdata = (weakref.ref(self), func, hook) @@ -1128,10 +1138,10 @@ class Context(GpgmeWrapper): Please see the GPGME manual for more information. """ - if func == None: + if func is None: hookdata = None else: - if hook == None: + if hook is None: hookdata = (weakref.ref(self), func) else: hookdata = (weakref.ref(self), func, hook) @@ -1229,7 +1239,8 @@ class Data(GpgmeWrapper): # This list is compiled using # # $ grep -v '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \ - # | awk "/\(gpgme_data_t/ { printf (\"'%s',\\n\", \$2) } " | sed "s/'\\*/'/" + # | awk "/\(gpgme_data_t/ { printf (\"'%s',\\n\", \$2) } " \ + # | sed "s/'\\*/'/" return name not in { 'gpgme_data_read', 'gpgme_data_write', @@ -1286,13 +1297,13 @@ class Data(GpgmeWrapper): super(Data, self).__init__(None) self.data_cbs = None - if cbs != None: + if cbs is not None: self.new_from_cbs(*cbs) - elif string != None: + elif string is not None: self.new_from_mem(string, copy) - elif file != None and offset != None and length != None: + elif file is not None and offset is not None and length is not None: self.new_from_filepart(file, offset, length) - elif file != None: + elif file is not None: if util.is_a_string(file): self.new_from_file(file, copy) else: @@ -1305,7 +1316,7 @@ class Data(GpgmeWrapper): # At interpreter shutdown, gpgme is set to NONE. return - if self.wrapped != None and gpgme.gpgme_data_release: + if self.wrapped is not None and gpgme.gpgme_data_release: gpgme.gpgme_data_release(self.wrapped) if self._callback_excinfo: gpgme.gpg_raise_callback_exception(self) @@ -1315,6 +1326,7 @@ class Data(GpgmeWrapper): # Implement the context manager protocol. def __enter__(self): return self + def __exit__(self, type, value, tb): self.__del__() @@ -1329,7 +1341,8 @@ class Data(GpgmeWrapper): def new_from_mem(self, string, copy=True): tmp = gpgme.new_gpgme_data_t_p() - errorcheck(gpgme.gpgme_data_new_from_mem(tmp,string,len(string),copy)) + errorcheck(gpgme.gpgme_data_new_from_mem(tmp, string, len(string), + copy)) self.wrapped = gpgme.gpgme_data_t_p_value(tmp) gpgme.delete_gpgme_data_t_p(tmp) @@ -1347,7 +1360,7 @@ class Data(GpgmeWrapper): def new_from_cbs(self, read_cb, write_cb, seek_cb, release_cb, hook=None): tmp = gpgme.new_gpgme_data_t_p() - if hook != None: + if hook is not None: hookdata = (weakref.ref(self), read_cb, write_cb, seek_cb, release_cb, hook) else: @@ -1374,9 +1387,9 @@ class Data(GpgmeWrapper): filename = file else: fp = gpgme.fdopen(file.fileno(), file.mode) - if fp == None: - raise ValueError("Failed to open file from %s arg %s" % \ - (str(type(file)), str(file))) + if fp is None: + raise ValueError("Failed to open file from %s arg %s" % + (str(type(file)), str(file))) errorcheck(gpgme.gpgme_data_new_from_filepart(tmp, filename, fp, offset, length)) @@ -1412,7 +1425,7 @@ class Data(GpgmeWrapper): raise GPGMEError.fromSyserror() return written - def read(self, size = -1): + def read(self, size=-1): """Read at most size bytes, returned as bytes. If the size argument is negative or omitted, read until EOF is reached. @@ -1447,6 +1460,7 @@ class Data(GpgmeWrapper): chunks.append(result) return b''.join(chunks) + def pubkey_algo_string(subkey): """Return short algorithm string @@ -1459,6 +1473,7 @@ def pubkey_algo_string(subkey): """ return gpgme.gpgme_pubkey_algo_string(subkey) + def pubkey_algo_name(algo): """Return name of public key algorithm @@ -1471,6 +1486,7 @@ def pubkey_algo_name(algo): """ return gpgme.gpgme_pubkey_algo_name(algo) + def hash_algo_name(algo): """Return name of hash algorithm @@ -1483,6 +1499,7 @@ def hash_algo_name(algo): """ return gpgme.gpgme_hash_algo_name(algo) + def get_protocol_name(proto): """Get protocol description @@ -1494,6 +1511,7 @@ def get_protocol_name(proto): """ return gpgme.gpgme_get_protocol_name(proto) + def addrspec_from_uid(uid): """Return the address spec @@ -1505,6 +1523,7 @@ def addrspec_from_uid(uid): """ return gpgme.gpgme_addrspec_from_uid(uid) + def check_version(version=None): return gpgme.gpgme_check_version(version) @@ -1514,13 +1533,15 @@ def check_version(version=None): # it unless she really wants to check for a certain version. check_version() -def engine_check_version (proto): + +def engine_check_version(proto): try: errorcheck(gpgme.gpgme_engine_check_version(proto)) return True except errors.GPGMEError: return False + def get_engine_info(): ptr = gpgme.new_gpgme_engine_info_t_p() try: @@ -1531,6 +1552,7 @@ def get_engine_info(): gpgme.delete_gpgme_engine_info_t_p(ptr) return info + def set_engine_info(proto, file_name, home_dir=None): """Changes the default configuration of the crypto engine implementing the protocol 'proto'. 'file_name' is the file name of @@ -1539,10 +1561,12 @@ def set_engine_info(proto, file_name, home_dir=None): used if omitted).""" errorcheck(gpgme.gpgme_set_engine_info(proto, file_name, home_dir)) + def set_locale(category, value): """Sets the default locale used by contexts""" errorcheck(gpgme.gpgme_set_locale(None, category, value)) + def wait(hang): """Wait for asynchronous call on any Context to finish. Wait forever if hang is True. @@ -1556,7 +1580,7 @@ def wait(hang): context = gpgme.gpgme_wait(None, ptr, hang) status = gpgme.gpgme_error_t_p_value(ptr) gpgme.delete_gpgme_error_t_p(ptr) - if context == None: + if context is None: errorcheck(status) else: context = Context(context) ----------------------------------------------------------------------- Summary of changes: AUTHORS | 3 + lang/python/src/core.py | 221 ++++++++++++++++++++++++++++-------------- lang/python/tests/t-import.py | 14 ++- 3 files changed, 158 insertions(+), 80 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 12:12:37 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Sun, 17 Jun 2018 12:12:37 +0200 Subject: [git] GpgOL - branch, master, updated. outlook-2007-removal-27-gd83ca87 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via d83ca87bae5da6adcd1bd9fc2f81225f3c65ea02 (commit) from 39ab613bc5fa359ab3039ec3c84aed734c1d9f29 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d83ca87bae5da6adcd1bd9fc2f81225f3c65ea02 Author: Andre Heinecke Date: Sun Jun 17 12:08:08 2018 +0200 Update NEWS for todays release -- diff --git a/NEWS b/NEWS index 13b59af..d4250af 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,15 @@ -Noteworthy changes for version 2.1.2 (unreleased) +Noteworthy changes for version 2.2.0 (2018-06-15) ================================================= + * Removed support for Outlook 2003 and 2007. + + * Fixed reply handling of PGP/Inline mails. (T3964) + + * Fixed a seemingly random crash. (T3946) + + * Added dutch and ukrainian translation. + + * Fixed encoding for some PGP/Inline mails. (T3986) Noteworthy changes for version 2.1.1 (2018-04-24) ================================================= diff --git a/configure.ac b/configure.ac index c94f968..ee381b7 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ min_automake_version="1.14" # (git tag -s gpgol-k.n.m) and run "./autogen.sh --force". Please # bump the version number immediately *after* the release and do # another commit and push so that the git magic is able to work. -m4_define([mym4_version], [2.1.2]) +m4_define([mym4_version], [2.2.0]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a ----------------------------------------------------------------------- Summary of changes: NEWS | 11 ++++++++++- configure.ac | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 12:14:10 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Sun, 17 Jun 2018 12:14:10 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-1-g8e5fac3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 8e5fac3a1c74a4c863eae6b25b45b7c43e4c2421 (commit) from d83ca87bae5da6adcd1bd9fc2f81225f3c65ea02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8e5fac3a1c74a4c863eae6b25b45b7c43e4c2421 Author: Andre Heinecke Date: Sun Jun 17 12:13:37 2018 +0200 Post release version bump -- diff --git a/NEWS b/NEWS index d4250af..2825cc7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +Noteworthy changes for version 2.2.1 (unreleased) +================================================= + Noteworthy changes for version 2.2.0 (2018-06-15) ================================================= diff --git a/configure.ac b/configure.ac index ee381b7..b4f92ee 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ min_automake_version="1.14" # (git tag -s gpgol-k.n.m) and run "./autogen.sh --force". Please # bump the version number immediately *after* the release and do # another commit and push so that the git magic is able to work. -m4_define([mym4_version], [2.2.0]) +m4_define([mym4_version], [2.2.1]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +++ configure.ac | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 12:16:52 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Sun, 17 Jun 2018 12:16:52 +0200 Subject: [git] gnupg-doc - branch, master, updated. 1ff77021507d0ab25cb4dccaab89bf941a0f9bbb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 1ff77021507d0ab25cb4dccaab89bf941a0f9bbb (commit) from 73c278e7b09fa18bc35fce117a9e05e37d791fe1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1ff77021507d0ab25cb4dccaab89bf941a0f9bbb Author: Andre Heinecke Date: Sun Jun 17 12:16:11 2018 +0200 swdb: Update gpgol to 2.2.0 -- diff --git a/web/swdb.mac b/web/swdb.mac index 6b9f46b..a1a7c47 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -181,11 +181,11 @@ # # GpgOL # -#+macro: gpgol_ver 2.1.1 -#+macro: gpgol_date 2018-04-24 -#+macro: gpgol_size 778k -#+macro: gpgol_sha1 d6851487baefec52ab97c3ecfcf9653c392e949f -#+macro: gpgol_sha2 406e97f14f332b501b05e2589495b65358e2b70c777324b63587d4507155ed98 +#+macro: gpgol_ver 2.2.0 +#+macro: gpgol_date 2018-06-17 +#+macro: gpgol_size 720k +#+macro: gpgol_sha1 0f79bb3a6ba6f34ecf85c3bac7a102fbd8abb739 +#+macro: gpgol_sha2 0e5ac1a4e270cb3afc2ecf0de801f208a10bb851f64ee46447f125186c70a2f4 # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 14:09:44 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Sun, 17 Jun 2018 14:09:44 +0200 Subject: [git] gnupg-doc - branch, master, updated. 08b7be30f76e65fdb742950eacffde2e09973ade Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 08b7be30f76e65fdb742950eacffde2e09973ade (commit) from 1ff77021507d0ab25cb4dccaab89bf941a0f9bbb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 08b7be30f76e65fdb742950eacffde2e09973ade Author: Andre Heinecke Date: Sun Jun 17 14:03:55 2018 +0200 swdb: Gpg4win 3.1.2 released -- diff --git a/web/swdb.mac b/web/swdb.mac index a1a7c47..2765631 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -51,17 +51,17 @@ # # Gpg4win # -#+macro: gpg4win_ver 3.1.1 -#+macro: gpg4win_date 2018-05-03 -#+macro: gpg4win_src_size 5300k -#+macro: gpg4win_src_sha1 dc0bc06c7d57be522177ee05200f704e8103bc59 -#+macro: gpg4win_src_sha2 3a98b015cbcaa5faa24a564bfbb52ac08a653bcbcd869c6e42f36b9152145b6b -#+macro: gpg4win_exe_size 27680k -#+macro: gpg4win_exe_sha1 369040c292358d68d8328d5a9b97d71f80cdf3d7 -#+macro: gpg4win_exe_sha2 b2144904f103dad48328fe125eb182c4dcfbe8093d48b74691613e0d2ed26033 -#+macro: gpg4win_isrc_size 222860k -#+macro: gpg4win_isrc_sha1 b3e4e57ecb05308aeff8e30876c0c4ce956b0234 -#+macro: gpg4win_isrc_sha2 bd2219638a2c0856f28c2c415c5a89a263885a31c4e141552348d9ae7bf3bbac +#+macro: gpg4win_ver 3.1.2 +#+macro: gpg4win_date 2018-06-17 +#+macro: gpg4win_src_size 5302k +#+macro: gpg4win_src_sha1 e875d1ab4d8c3c960fdbdb00236d8da0a14ed07e +#+macro: gpg4win_src_sha2 bb82b45fb33e399da9ae0c0883c8933c8fb3a1f952c16766b35a13d65e4ad839 +#+macro: gpg4win_exe_size 27558k +#+macro: gpg4win_exe_sha1 01597cb2a0ff4a914717d603547906e3862b6382 +#+macro: gpg4win_exe_sha2 6c7bbb36c89c83b2432edc9a7fe64c73b26711ca0d3d6a0d55c71aef66ec70f1 +#+macro: gpg4win_isrc_size 222822k +#+macro: gpg4win_isrc_sha1 0445037c401357ca463da39771c3bda7a79782d6 +#+macro: gpg4win_isrc_sha2 c8c80554149c6dad410461cc17447aa8115525ee003aafe6ace034da5a40970c # ----------------------------------------------------------------------- Summary of changes: web/swdb.mac | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jun 17 14:44:18 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 17 Jun 2018 14:44:18 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-62-g19c5267 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 19c5267f868aa41e73752ac1c76ec7ae1efe07b8 (commit) from a5b24ae46c81d3abd3bb18bf0390cab6ebb2bd77 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 19c5267f868aa41e73752ac1c76ec7ae1efe07b8 Author: Ben McGinnes Date: Sun Jun 17 22:42:43 2018 +1000 python bindings: core import statements * Fixed the bit I broke while fixing the PEP8 compliance issues. diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 33a1c70..8f2e9d8 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import, print_function, unicode_literals +del absolute_import, print_function, unicode_literals + import re import os import warnings @@ -11,9 +14,6 @@ from . import constants from . import errors from . import util -from __future__ import absolute_import, print_function, unicode_literals -del absolute_import, print_function, unicode_literals - # Copyright (C) 2016-2017 g10 Code GmbH # Copyright (C) 2004,2008 Igor Belyi # Copyright (C) 2002 John Goerzen ----------------------------------------------------------------------- Summary of changes: lang/python/src/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 18 03:15:14 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 18 Jun 2018 03:15:14 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-156-ga4a054b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via a4a054bf14fa855715faee01a152755c4e2a74f7 (commit) from bcdbf8b8ebe9d61160e0b007dabe1b6462ffbc93 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a4a054bf14fa855715faee01a152755c4e2a74f7 Author: NIIBE Yutaka Date: Mon Jun 18 10:13:35 2018 +0900 libdns: Fix for non-FQDN hostname. * dirmngr/dns.c (dns_resconf_open): Clear search[0] for non-FQDN hostname. -- GnuPG-bug-id: T3803 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index d2445a0..908bf15 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -5371,13 +5371,16 @@ struct dns_resolv_conf *dns_resconf_open(int *error) { if (0 != gethostname(resconf->search[0], sizeof resconf->search[0])) goto syerr; - dns_d_anchor(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); - dns_d_cleave(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); - /* - * XXX: If gethostname() returned a string without any label - * separator, then search[0][0] should be NUL. + * If gethostname() returned a string without any label + * separator, then search[0][0] should be NUL. */ + if (strchr (resconf->search[0], '.')) { + dns_d_anchor(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); + dns_d_cleave(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); + } else { + memset (resconf->search[0], 0, sizeof resconf->search[0]); + } dns_resconf_acquire(resconf); ----------------------------------------------------------------------- Summary of changes: dirmngr/dns.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jun 18 10:28:02 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 18 Jun 2018 10:28:02 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-11-g87d0ecf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 87d0ecf8a1b80139a6cab2a79f1ca6e287207999 (commit) via 699fe4b36f62b0f4d4e21a85ee7c9ae13377d6cb (commit) via 0c05b08e8b5c1f120fe5f3ed5c061f034f7496a0 (commit) via 20c289606f89803929948ddd18910acff2acc9eb (commit) via 13320db678675246f4bb5a3fb6ece143f37c34a4 (commit) from e8f439e0547463c24f3c10008fee73e6c4259f52 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 87d0ecf8a1b80139a6cab2a79f1ca6e287207999 Author: NIIBE Yutaka Date: Mon Jun 18 10:13:35 2018 +0900 libdns: Fix for non-FQDN hostname. * dirmngr/dns.c (dns_resconf_open): Clear search[0] for non-FQDN hostname. -- Cherry pick from master commit: a4a054bf14fa855715faee01a152755c4e2a74f7 GnuPG-bug-id: T3803 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index d2445a0..908bf15 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -5371,13 +5371,16 @@ struct dns_resolv_conf *dns_resconf_open(int *error) { if (0 != gethostname(resconf->search[0], sizeof resconf->search[0])) goto syerr; - dns_d_anchor(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); - dns_d_cleave(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); - /* - * XXX: If gethostname() returned a string without any label - * separator, then search[0][0] should be NUL. + * If gethostname() returned a string without any label + * separator, then search[0][0] should be NUL. */ + if (strchr (resconf->search[0], '.')) { + dns_d_anchor(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); + dns_d_cleave(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); + } else { + memset (resconf->search[0], 0, sizeof resconf->search[0]); + } dns_resconf_acquire(resconf); commit 699fe4b36f62b0f4d4e21a85ee7c9ae13377d6cb Author: NIIBE Yutaka Date: Fri Jun 15 12:58:29 2018 +0900 libdns: Fix connect and try next nameserver when ECONNREFUSED. * dirmngr/dns.c (dns_so_check): When EINVAL, release the association by connect with AF_UNSPEC and try again. Also try again for ECONNREFUSED. (dns_res_exec): Try next nameserver when ECONNREFUSED. -- Cherry pick from master commit: bcdbf8b8ebe9d61160e0b007dabe1b6462ffbc93 GnuPG-bug-id: T3374 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 178070a..d2445a0 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -7614,8 +7614,23 @@ retry: so->state++; /* FALL THROUGH */ case DNS_SO_UDP_CONN: + udp_connect_retry: error = dns_connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote)); dns_trace_sys_connect(so->trace, so->udp, SOCK_DGRAM, (struct sockaddr *)&so->remote, error); + + /* Linux returns EINVAL when address was bound to + localhost and it's external IP address now. */ + if (error == EINVAL) { + struct sockaddr unspec_addr; + memset (&unspec_addr, 0, sizeof unspec_addr); + unspec_addr.sa_family = AF_UNSPEC; + connect(so->udp, &unspec_addr, sizeof unspec_addr); + goto udp_connect_retry; + } else if (error == ECONNREFUSED) + /* Error for previous socket operation may + be reserverd asynchronously. */ + goto udp_connect_retry; + if (error) goto error; @@ -8824,7 +8839,10 @@ exec: if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf)) dgoto(R->sp, DNS_R_FOREACH_A); - if ((error = dns_so_check(&R->so))) + error = dns_so_check(&R->so); + if (error == ECONNREFUSED) + dgoto(R->sp, DNS_R_FOREACH_A); + else if (error) goto error; if (!dns_p_setptr(&F->answer, dns_so_fetch(&R->so, &error))) @@ -8957,7 +8975,10 @@ exec: if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf)) dgoto(R->sp, DNS_R_FOREACH_AAAA); - if ((error = dns_so_check(&R->so))) + error = dns_so_check(&R->so); + if (error == ECONNREFUSED) + dgoto(R->sp, DNS_R_FOREACH_AAAA); + else if (error) goto error; if (!dns_p_setptr(&F->answer, dns_so_fetch(&R->so, &error))) commit 0c05b08e8b5c1f120fe5f3ed5c061f034f7496a0 Author: NIIBE Yutaka Date: Fri Jun 15 10:38:22 2018 +0900 libdns: Clear struct sockaddr_storage by zero. * dirmngr/dns.c (dns_resconf_pton): Clear SS. (dns_resconf_setiface): Clear ->IFACE. (dns_hints_root, send_query): Clear SS. -- Cherry pick from master commit: 1c0b6681e4f322b88ac35d1f21c03d3cfc35fc23 POSIX requires clear the structure of struct sockaddr_in6. On macOS, in some case like bind, it is better to clear even for struct sockaddr_in. Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 13ef4b8..178070a 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -5549,6 +5549,7 @@ int dns_resconf_pton(struct sockaddr_storage *ss, const char *src) { unsigned short port = 0; int ch, af = AF_INET, error; + memset(ss, 0, sizeof *ss); while ((ch = *src++)) { switch (ch) { case ' ': @@ -6311,6 +6312,7 @@ int dns_resconf_setiface(struct dns_resolv_conf *resconf, const char *addr, unsi int af = (strchr(addr, ':'))? AF_INET6 : AF_INET; int error; + memset(&resconf->iface, 0, sizeof (struct sockaddr_storage)); if ((error = dns_pton(af, addr, dns_sa_addr(af, &resconf->iface, NULL)))) return error; @@ -6622,6 +6624,7 @@ struct dns_hints *dns_hints_root(struct dns_resolv_conf *resconf, int *error_) { for (i = 0; i < lengthof(root_hints); i++) { af = root_hints[i].af; + memset(&ss, 0, sizeof ss); if ((error = dns_pton(af, root_hints[i].addr, dns_sa_addr(af, &ss, NULL)))) goto error; @@ -10866,6 +10869,7 @@ static int send_query(int argc, char *argv[]) { struct dns_socket *so; int error, type; + memset(&ss, 0, sizeof ss); if (argc > 1) { ss.ss_family = (strchr(argv[1], ':'))? AF_INET6 : AF_INET; commit 20c289606f89803929948ddd18910acff2acc9eb Author: NIIBE Yutaka Date: Thu Jun 14 13:10:57 2018 +0900 libdns: Sync to upstream. * dirmngr/dns.c (dns_nssconf_loadfile): Handle exclamation mark. -- Cherry pick from master commit: 3e6ad302eaf3a4a9f3e60379133b3dfdbe0e1b2d Reverting local change, merge upstream's debug-tracing branch. (commit 21281fc1b63bb74d51762b8e363c49b1a258783d) Fixes-commit: d4c0187dd93163f12e9f953366adef81ecf526a6 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 8e8b6db..13ef4b8 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -6096,17 +6096,9 @@ int dns_nssconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) { dns_anyconf_skip(" \t", fp); if ('[' == dns_anyconf_peek(fp)) { - dns_anyconf_skip("[ \t", fp); + dns_anyconf_skip("[! \t", fp); - for (;;) { - if ('!' == dns_anyconf_peek(fp)) { - dns_anyconf_skip("! \t", fp); - /* FIXME: negating statuses; currently not implemented */ - dns_anyconf_skip("^#;]\n", fp); /* skip to end of criteria */ - break; - } - - if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) break; + while (dns_anyconf_scan(&cf, "%w_", fp, &error)) { dns_anyconf_skip("= \t", fp); if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) { dns_anyconf_pop(&cf); /* discard status */ commit 13320db678675246f4bb5a3fb6ece143f37c34a4 Author: NIIBE Yutaka Date: Thu Jun 14 13:01:45 2018 +0900 dirmngr: Fix recursive resolver mode. * dirmngr/dns-stuff.c (libdns_init): Initialize options.recurse. -- Cherry pick from master commit: 5b40338f12762cd74238c2d2b3101c33dd2d0ed3 To reproduce an error, run: ./t-dns-stuff --debug --recursive-resolver www.gnupg.org Then, it returns "No name" error. That's because there was only setup for root servers, and no setup for recursive query in fact. Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 7324aae..ffac816 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -612,6 +612,8 @@ libdns_init (void) } } + ld.resolv_conf->options.recurse = recursive_resolver_p (); + /* dns_hints_local for stub mode, dns_hints_root for recursive. */ ld.hints = (recursive_resolver ? dns_hints_root (ld.resolv_conf, &derr) ----------------------------------------------------------------------- Summary of changes: dirmngr/dns-stuff.c | 2 ++ dirmngr/dns.c | 54 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 05:16:45 2018 From: cvs at cvs.gnupg.org (by Will Dietz) Date: Tue, 19 Jun 2018 05:16:45 +0200 Subject: [git] GCRYPT - branch, LIBGCRYPT-1.8-BRANCH, updated. libgcrypt-1.8.3-2-g20c0348 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1.8-BRANCH has been updated via 20c034865f2dd15ce2871385b6e29c15d1570539 (commit) from 6ca6344429e5ee1657e164509c6b50a717ebec68 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 20c034865f2dd15ce2871385b6e29c15d1570539 Author: Will Dietz Date: Sun Jun 17 18:53:58 2018 -0500 random: Fix hang of _gcry_rndjent_get_version. * random/rndjent.c (_gcry_rndjent_get_version): Move locking. -- cherry-picked from master commit: 355f5b7f69075c010fe33aa5b10ac60c08fae0c7 While the protection for jent_rng_collector is needed, _gcry_rndjent_poll is also acquiring the lock for the variable. Thus, it hangs. This change is sub-optimal, the lock is once released after the call of _gcry_rndjent_poll. It might be good to modify the API of _gcry_rndjent_poll to explicitly allow this use case of forcing initialization keeping the lock. Comments and change log entry by gniibe. GnuPG-bug-id: 4034 Fixes-commit: 0de2a22fcf6607d0aecb550feefa414cee3731b2 diff --git a/random/rndjent.c b/random/rndjent.c index 0c5a820..3740ddd 100644 --- a/random/rndjent.c +++ b/random/rndjent.c @@ -334,9 +334,10 @@ _gcry_rndjent_get_version (int *r_active) { if (r_active) { - lock_rng (); /* Make sure the RNG is initialized. */ _gcry_rndjent_poll (NULL, 0, 0); + + lock_rng (); /* To ease debugging we store 2 for a clock_gettime based * implementation and 1 for a rdtsc based code. */ *r_active = jent_rng_collector? is_rng_available () : 0; ----------------------------------------------------------------------- Summary of changes: random/rndjent.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 05:17:04 2018 From: cvs at cvs.gnupg.org (by Will Dietz) Date: Tue, 19 Jun 2018 05:17:04 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-73-g355f5b7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 355f5b7f69075c010fe33aa5b10ac60c08fae0c7 (commit) from 0d51ea9b88b618368a7b916f26ebfe61bdf70503 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 355f5b7f69075c010fe33aa5b10ac60c08fae0c7 Author: Will Dietz Date: Sun Jun 17 18:53:58 2018 -0500 random: Fix hang of _gcry_rndjent_get_version. * random/rndjent.c (_gcry_rndjent_get_version): Move locking. -- While the protection for jent_rng_collector is needed, _gcry_rndjent_poll is also acquiring the lock for the variable. Thus, it hangs. This change is sub-optimal, the lock is once released after the call of _gcry_rndjent_poll. It might be good to modify the API of _gcry_rndjent_poll to explicitly allow this use case of forcing initialization keeping the lock. Comments and change log entry by gniibe. GnuPG-bug-id: 4034 Fixes-commit: 0de2a22fcf6607d0aecb550feefa414cee3731b2 diff --git a/random/rndjent.c b/random/rndjent.c index 0c5a820..3740ddd 100644 --- a/random/rndjent.c +++ b/random/rndjent.c @@ -334,9 +334,10 @@ _gcry_rndjent_get_version (int *r_active) { if (r_active) { - lock_rng (); /* Make sure the RNG is initialized. */ _gcry_rndjent_poll (NULL, 0, 0); + + lock_rng (); /* To ease debugging we store 2 for a clock_gettime based * implementation and 1 for a rdtsc based code. */ *r_active = jent_rng_collector? is_rng_available () : 0; ----------------------------------------------------------------------- Summary of changes: random/rndjent.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 08:07:53 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 19 Jun 2018 08:07:53 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-157-g08147f8 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 08147f8bbdca40c98c2a094fa48fab15b8339c80 (commit) from a4a054bf14fa855715faee01a152755c4e2a74f7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 08147f8bbdca40c98c2a094fa48fab15b8339c80 Author: Werner Koch Date: Tue Jun 19 08:06:50 2018 +0200 wks: Take name of sendmail from configure. * configure.ac (NAME_OF_SENDMAIL): New ac_define. * tools/send-mail.c (run_sendmail): Use it. -- We used to ac_subst the SENDMAIL in the old keyserver via mail script. We cab reuse this to avoid a fixed name for sendmail in the send-mail.c helper. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 0d270a4..60ec941 100644 --- a/configure.ac +++ b/configure.ac @@ -1219,6 +1219,8 @@ elif test x"$with_mailprog" != xno ; then AC_SUBST(SENDMAIL,$with_mailprog) AC_MSG_RESULT($with_mailprog) fi +AC_DEFINE_UNQUOTED(NAME_OF_SENDMAIL,"$SENDMAIL", + [Tool with sendmail -t interface]) # diff --git a/tools/send-mail.c b/tools/send-mail.c index 9f07c7a..6492c43 100644 --- a/tools/send-mail.c +++ b/tools/send-mail.c @@ -33,7 +33,7 @@ static gpg_error_t run_sendmail (estream_t data) { gpg_error_t err; - const char pgmname[] = "/usr/lib/sendmail"; + const char pgmname[] = NAME_OF_SENDMAIL; const char *argv[3]; argv[0] = "-oi"; ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 ++ tools/send-mail.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 09:30:10 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Tue, 19 Jun 2018 09:30:10 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-63-g780f788 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via 780f7880c6598d4532354b348d7bd74026d162f4 (commit) from 3cd428ba442f43e470b977e27e18ff52567baba5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 780f7880c6598d4532354b348d7bd74026d162f4 Author: Maximilian Krambach Date: Tue Jun 19 09:26:01 2018 +0200 js: getDefaultKey and GenerateKey improvements -- * src/Keyring.js: added more options for key generation. * src/Key.js: GetDefaultKey now relies on the info associated with the key, as the approach of relying on a secret subkey did not work as intended * DemoExtension: Added a button for retrieval of the subkey, to test this functionality. diff --git a/lang/js/DemoExtension/maindemo.js b/lang/js/DemoExtension/maindemo.js index 67b811f..6230c3f 100644 --- a/lang/js/DemoExtension/maindemo.js +++ b/lang/js/DemoExtension/maindemo.js @@ -57,7 +57,7 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('getdefaultkey').addEventListener('click', function(){ gpgmejs.Keyring.getDefaultKey().then(function(answer){ - document.getElementById('defaultkey').innerHtml = + document.getElementById('defaultkey').textContent = answer.fingerprint; }, function(errormsg){ alert(errormsg.message); diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index 3e4f1c7..88c2b92 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -218,7 +218,6 @@ export class GPGME_Key { * * @async */ - // TODO: Does not work yet, result is always false getHasSecret(){ let me = this; return new Promise(function(resolve, reject) { @@ -230,31 +229,17 @@ export class GPGME_Key { msg.setParameter('secret', true); msg.post().then(function(result){ me._data.hasSecret = null; - if (result.keys === undefined || result.keys.length < 1) { + if ( + result.keys && + result.keys.length === 1 && + result.keys[0].secret === true + ) { + me._data.hasSecret = true; + resolve(true); + } else { me._data.hasSecret = false; resolve(false); } - else if (result.keys.length === 1){ - let key = result.keys[0]; - if (!key.subkeys){ - me._data.hasSecret = false; - resolve(false); - } else { - for (let i=0; i < key.subkeys.length; i++) { - if (key.subkeys[i].secret === true) { - me._data.hasSecret = true; - resolve(true); - break; - } - if (i === (key.subkeys.length -1)) { - me._data.hasSecret = false; - resolve(false); - } - } - } - } else { - reject(gpgme_error('CONN_UNEXPECTED_ANSWER')); - } }, function(error){ reject(error); }); diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index 43d257d..8bec1ce 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -273,21 +273,18 @@ export class GPGME_Keyring { * Keys can not be _deleted_ from inside gpgmejs. * * @param {String} userId The user Id, e.g. "Foo Bar " - * @param {*} algo (optional) algorithm to be used. See - * {@link supportedKeyAlgos } below for supported values. - * @param {Number} keyLength (optional) TODO + * @param {*} algo (optional) algorithm (and optionally key size to be + * used. See {@link supportedKeyAlgos } below for supported values. * @param {Date} expires (optional) Expiration date. If not set, expiration * will be set to 'never' * * @returns{Promise} */ - generateKey(userId, algo = 'default', keyLength, expires){ + generateKey(userId, algo = 'default', expires){ if ( typeof(userId) !== 'string' || supportedKeyAlgos.indexOf(algo) < 0 || (expires && !(expires instanceof Date)) - // TODO keylength - // TODO check for completeness of algos ){ return Promise.reject(gpgme_error('PARAM_WRONG')); } @@ -295,12 +292,11 @@ export class GPGME_Keyring { return new Promise(function(resolve, reject){ let msg = createMessage('createkey'); msg.setParameter('userid', userId); - msg.setParameter('algo', algo); + msg.setParameter('algo', algo ); if (expires){ msg.setParameter('expires', Math.floor(expires.valueOf()/1000)); } - // TODO append keylength to algo msg.post().then(function(response){ me.getKeys(response.fingerprint, true).then( // TODO make prepare_sync (second parameter) optional here. @@ -321,9 +317,11 @@ export class GPGME_Keyring { */ const supportedKeyAlgos = [ 'default', - 'rsa', - 'dsa', - 'elg', + 'rsa', 'rsa2048', 'rsa3072', 'rsa4096', + 'dsa', 'dsa2048', 'dsa3072', 'dsa4096', + 'elg', 'elg2048', 'elg3072', 'elg4096', 'ed25519', - 'cv25519' + 'cv25519', + 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1', + 'NIST P-256', 'NIST P-384', 'NIST P-521' ]; \ No newline at end of file ----------------------------------------------------------------------- Summary of changes: lang/js/DemoExtension/maindemo.js | 2 +- lang/js/src/Key.js | 31 ++++++++----------------------- lang/js/src/Keyring.js | 22 ++++++++++------------ 3 files changed, 19 insertions(+), 36 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 09:33:43 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 19 Jun 2018 09:33:43 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-2-g3ba39a0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 3ba39a0f442956ec4a6c8d0fa0e62fe696795980 (commit) from 8e5fac3a1c74a4c863eae6b25b45b7c43e4c2421 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3ba39a0f442956ec4a6c8d0fa0e62fe696795980 Author: Andre Heinecke Date: Tue Jun 19 09:29:11 2018 +0200 Fix crash when adding attachment without fileext * src/mimemaker.cpp (infer_content_type): Check if a suffix was found and check for the size of the suffix before using it. -- The crash was introduced with 94c354a0 GnuPG-Bug-Id: T4032 diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index d8d3684..e4bd4aa 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -679,10 +679,19 @@ infer_content_type (const char * /*data*/, size_t /*datalen*/, *force_b64 = 0; if (filename) - suffix = strrchr (filename, '.'); + { + const char *dot = strrchr (filename, '.'); + + if (dot) + { + suffix = dot; + } + } - if (!suffix.empty()) + /* Check for at least one char after the dot. */ + if (suffix.size() > 1) { + /* Erase the dot */ suffix.erase(0, 1); std::transform(suffix.begin(), suffix.end(), suffix.begin(), ::tolower); for (i=0; suffix_table[i].suffix; i++) ----------------------------------------------------------------------- Summary of changes: src/mimemaker.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 15:39:45 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 19 Jun 2018 15:39:45 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-3-g8576131 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 8576131bc84d41b8b68ae92461c063774d3064fc (commit) from 3ba39a0f442956ec4a6c8d0fa0e62fe696795980 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8576131bc84d41b8b68ae92461c063774d3064fc Author: Andre Heinecke Date: Tue Jun 19 15:36:39 2018 +0200 Cppinize keycache a bit more * src/keycache.cpp (setSmimeKeySecret, setSmimeKey, setPgpKey), (setPgpKeySecret): Use std::string. (do_locate, locate_secret): Smart pointer for ctx. std::string for addr. * src/keycache.h: Update accordingly. -- This avoids free / delete errors and here also reduces std::string allocations. diff --git a/src/keycache.cpp b/src/keycache.cpp index a3c4e29..3239e33 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -43,16 +43,14 @@ public: } - void setPgpKey(const char *mbox, const GpgME::Key &key) + void setPgpKey(const std::string &mbox, const GpgME::Key &key) { - const std::string sMbox(mbox); - gpgrt_lock_lock (&keycache_lock); - auto it = m_pgp_key_map.find (sMbox); + auto it = m_pgp_key_map.find (mbox); if (it == m_pgp_key_map.end ()) { - m_pgp_key_map.insert (std::pair (sMbox, key)); + m_pgp_key_map.insert (std::pair (mbox, key)); } else { @@ -61,16 +59,14 @@ public: gpgrt_lock_unlock (&keycache_lock); } - void setSmimeKey(const char *mbox, const GpgME::Key &key) + void setSmimeKey(const std::string &mbox, const GpgME::Key &key) { - const std::string sMbox(mbox); - gpgrt_lock_lock (&keycache_lock); - auto it = m_smime_key_map.find (sMbox); + auto it = m_smime_key_map.find (mbox); if (it == m_smime_key_map.end ()) { - m_smime_key_map.insert (std::pair (sMbox, key)); + m_smime_key_map.insert (std::pair (mbox, key)); } else { @@ -79,16 +75,14 @@ public: gpgrt_lock_unlock (&keycache_lock); } - void setPgpKeySecret(const char *mbox, const GpgME::Key &key) + void setPgpKeySecret(const std::string &mbox, const GpgME::Key &key) { - const std::string sMbox(mbox); - gpgrt_lock_lock (&keycache_lock); - auto it = m_pgp_skey_map.find (sMbox); + auto it = m_pgp_skey_map.find (mbox); if (it == m_pgp_skey_map.end ()) { - m_pgp_skey_map.insert (std::pair (sMbox, key)); + m_pgp_skey_map.insert (std::pair (mbox, key)); } else { @@ -97,16 +91,14 @@ public: gpgrt_lock_unlock (&keycache_lock); } - void setSmimeKeySecret(const char *mbox, const GpgME::Key &key) + void setSmimeKeySecret(const std::string &mbox, const GpgME::Key &key) { - const std::string sMbox(mbox); - gpgrt_lock_lock (&keycache_lock); - auto it = m_smime_skey_map.find (sMbox); + auto it = m_smime_skey_map.find (mbox); if (it == m_smime_skey_map.end ()) { - m_smime_skey_map.insert (std::pair (sMbox, key)); + m_smime_skey_map.insert (std::pair (mbox, key)); } else { @@ -318,37 +310,42 @@ KeyCache::getEncryptionKeys (const std::vector &recipients, GpgME:: static DWORD WINAPI do_locate (LPVOID arg) { - char *addr = (char*) arg; + if (!arg) + { + return 0; + } + std::string addr = (char*) arg; + xfree (arg); log_mime_parser ("%s:%s searching key for addr: \"%s\"", - SRCNAME, __func__, addr); + SRCNAME, __func__, addr.c_str()); - const auto k = GpgME::Key::locate (addr); + const auto k = GpgME::Key::locate (addr.c_str()); if (!k.isNull ()) { log_mime_parser ("%s:%s found key for addr: \"%s\":%s", - SRCNAME, __func__, addr, k.primaryFingerprint()); + SRCNAME, __func__, addr.c_str(), + k.primaryFingerprint()); KeyCache::instance ()->setPgpKey (addr, k); } if (opt.enable_smime) { - auto ctx = GpgME::Context::createForProtocol (GpgME::CMS); + auto ctx = std::unique_ptr ( + GpgME::Context::createForProtocol (GpgME::CMS)); if (!ctx) { TRACEPOINT; - xfree (addr); return 0; } // We need to validate here to fetch CRL's ctx->setKeyListMode (GpgME::KeyListMode::Local | GpgME::KeyListMode::Validate); - GpgME::Error e = ctx->startKeyListing (addr); + GpgME::Error e = ctx->startKeyListing (addr.c_str()); if (e) { TRACEPOINT; - xfree (addr); return 0; } @@ -358,7 +355,6 @@ do_locate (LPVOID arg) keys.push_back(ctx->nextKey(err)); } while (!err); keys.pop_back(); - delete ctx; GpgME::Key candidate; for (const auto &key: keys) @@ -382,12 +378,11 @@ do_locate (LPVOID arg) if (!candidate.isNull()) { log_mime_parser ("%s:%s found SMIME key for addr: \"%s\":%s", - SRCNAME, __func__, addr, candidate.primaryFingerprint()); + SRCNAME, __func__, addr.c_str(), + candidate.primaryFingerprint()); KeyCache::instance()->setSmimeKey (addr, candidate); } } - xfree (addr); - log_debug ("%s:%s locator thread done", SRCNAME, __func__); return 0; @@ -396,20 +391,27 @@ do_locate (LPVOID arg) static void locate_secret (char *addr, GpgME::Protocol proto) { - auto ctx = GpgME::Context::createForProtocol (proto); + auto ctx = std::unique_ptr ( + GpgME::Context::createForProtocol (proto)); if (!ctx) { TRACEPOINT; return; } + if (!addr) + { + TRACEPOINT; + return; + } + const auto mbox = GpgME::UserID::addrSpecFromString (addr); + // We need to validate here to fetch CRL's ctx->setKeyListMode (GpgME::KeyListMode::Local | GpgME::KeyListMode::Validate); - GpgME::Error e = ctx->startKeyListing (addr, true); + GpgME::Error e = ctx->startKeyListing (mbox.c_str(), true); if (e) { TRACEPOINT; - xfree (addr); return; } @@ -432,21 +434,20 @@ locate_secret (char *addr, GpgME::Protocol proto) if (proto == GpgME::OpenPGP) { log_mime_parser ("%s:%s found pgp skey for addr: \"%s\":%s", - SRCNAME, __func__, addr, key.primaryFingerprint()); - KeyCache::instance()->setPgpKeySecret (addr, key); - delete ctx; + SRCNAME, __func__, mbox.c_str(), + key.primaryFingerprint()); + KeyCache::instance()->setPgpKeySecret (mbox, key); return; } if (proto == GpgME::CMS) { log_mime_parser ("%s:%s found cms skey for addr: \"%s\":%s", - SRCNAME, __func__, addr, key.primaryFingerprint()); - KeyCache::instance()->setSmimeKeySecret (addr, key); - delete ctx; + SRCNAME, __func__, mbox.c_str (), + key.primaryFingerprint()); + KeyCache::instance()->setSmimeKeySecret (mbox, key); return; } } while (!err); - delete ctx; return; } @@ -543,25 +544,25 @@ KeyCache::startLocateSecret (const char *addr) const void -KeyCache::setSmimeKey(const char *mbox, const GpgME::Key &key) +KeyCache::setSmimeKey(const std::string &mbox, const GpgME::Key &key) { d->setSmimeKey(mbox, key); } void -KeyCache::setPgpKey(const char *mbox, const GpgME::Key &key) +KeyCache::setPgpKey(const std::string &mbox, const GpgME::Key &key) { d->setPgpKey(mbox, key); } void -KeyCache::setSmimeKeySecret(const char *mbox, const GpgME::Key &key) +KeyCache::setSmimeKeySecret(const std::string &mbox, const GpgME::Key &key) { d->setSmimeKeySecret(mbox, key); } void -KeyCache::setPgpKeySecret(const char *mbox, const GpgME::Key &key) +KeyCache::setPgpKeySecret(const std::string &mbox, const GpgME::Key &key) { d->setPgpKeySecret(mbox, key); } diff --git a/src/keycache.h b/src/keycache.h index 41e7255..6bda0b9 100644 --- a/src/keycache.h +++ b/src/keycache.h @@ -69,10 +69,10 @@ public: void startLocate (const char *addr) const; // Internal for thread - void setSmimeKey(const char *mbox, const GpgME::Key &key); - void setPgpKey(const char *mbox, const GpgME::Key &key); - void setSmimeKeySecret(const char *mbox, const GpgME::Key &key); - void setPgpKeySecret(const char *mbox, const GpgME::Key &key); + void setSmimeKey(const std::string &mbox, const GpgME::Key &key); + void setPgpKey(const std::string &mbox, const GpgME::Key &key); + void setSmimeKeySecret(const std::string &mbox, const GpgME::Key &key); + void setPgpKeySecret(const std::string &mbox, const GpgME::Key &key); private: ----------------------------------------------------------------------- Summary of changes: src/keycache.cpp | 93 ++++++++++++++++++++++++++++---------------------------- src/keycache.h | 8 ++--- 2 files changed, 51 insertions(+), 50 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 19 16:42:51 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 19 Jun 2018 16:42:51 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-64-gd27703e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via d27703ea4f0eed950cddf0157dc78bcb5d8d1c65 (commit) from 780f7880c6598d4532354b348d7bd74026d162f4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d27703ea4f0eed950cddf0157dc78bcb5d8d1c65 Author: Andre Heinecke Date: Tue Jun 19 16:40:40 2018 +0200 Prepare build system for gpgme-js and dist it * configure.ac: Add js as language. * lang/Makefile.am: Add js as dist language. * lang/js/BrowserTestExtension/Makefile.am, lang/js/DemoExtension/Makefile.am, lang/js/Makefile.am, lang/js/src/Makefile.am: Populate EXTRA_DIST variables. -- There is no actual build done yet as there seems to be no way to build it with debian stable tools. This needs clarification. diff --git a/configure.ac b/configure.ac index a1da1e3..69d7132 100644 --- a/configure.ac +++ b/configure.ac @@ -187,7 +187,7 @@ have_w64_system=no have_macos_system=no build_w32_glib=no build_w32_qt=no -available_languages="cl cpp python python2 python3 qt" +available_languages="cl cpp python python2 python3 qt js" default_languages="cl cpp python qt" case "${host}" in x86_64-*mingw32*) @@ -479,6 +479,28 @@ fi AC_SUBST(ENABLED_LANGUAGES, $enabled_languages) +# The javascript bindings +LIST_MEMBER("js", $enabled_languages) +if test "$found" = "1"; then + AC_CHECK_PROGS([NPX], [npx]) + if test -z "$NPX"; then + if test "$explicit_languages" = "1"; then + AC_MSG_ERROR([[ +*** +*** Node.js (npx) is required for the JavaScript binding. +***]]) + else + AC_MSG_WARN([ +*** +*** Node.js (npx) not found - JavaScript binding will not be built. +***]) + enabled_languages=$(echo $enabled_languages | sed 's/js//') + fi + fi +fi +AM_CONDITIONAL([BUILD_JS_BINDINGS], + [test -n "$NPX"]) + # # Provide information about the build. # @@ -899,6 +921,9 @@ AC_CONFIG_FILES(lang/qt/tests/Makefile) AC_CONFIG_FILES(lang/qt/src/qgpgme_version.h) AC_CONFIG_FILES([lang/Makefile lang/cl/Makefile lang/cl/gpgme.asd]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([lang/qt/doc/Doxyfile])]) +AC_CONFIG_FILES([lang/js/Makefile lang/js/src/Makefile + lang/js/BrowserTestExtension/Makefile + lang/js/DemoExtension/Makefile]) AC_CONFIG_FILES(lang/qt/doc/Makefile) AC_CONFIG_FILES([lang/python/Makefile lang/python/version.py diff --git a/lang/Makefile.am b/lang/Makefile.am index fd3ce4e..1bf7331 100644 --- a/lang/Makefile.am +++ b/lang/Makefile.am @@ -18,6 +18,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA SUBDIRS = $(ENABLED_LANGUAGES) -DIST_SUBDIRS = cl cpp qt python +DIST_SUBDIRS = cl cpp qt python js EXTRA_DIST = README diff --git a/lang/js/BrowserTestExtension/Makefile.am b/lang/js/BrowserTestExtension/Makefile.am new file mode 100644 index 0000000..340d7ad --- /dev/null +++ b/lang/js/BrowserTestExtension/Makefile.am @@ -0,0 +1,42 @@ +# Makefile.am for GPGME-JS. +# Copyright (C) 2018 Intevation GmbH +# +# This file is part of GPGME. +# +# GPGME-CL is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME-CL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA + +EXTRA_DIST = browsertest.html \ + index.html \ + longTests.html \ + Makefile.am \ + manifest.json \ + popup.html \ + popup.js \ + runbrowsertest.js \ + rununittests.js \ + setup_testing.js \ + testicon.png \ + testkey2.pub \ + testkey.pub \ + testkey.sec \ + tests/encryptDecryptTest.js \ + tests/encryptTest.js \ + tests/inputvalues.js \ + tests/KeyImportExport.js \ + tests/longRunningTests.js \ + tests/signTest.js \ + tests/startup.js \ + unittests.html diff --git a/lang/js/DemoExtension/Makefile.am b/lang/js/DemoExtension/Makefile.am new file mode 100644 index 0000000..e93d0f6 --- /dev/null +++ b/lang/js/DemoExtension/Makefile.am @@ -0,0 +1,27 @@ +# Makefile.am for GPGME-JS. +# Copyright (C) 2018 Intevation GmbH +# +# This file is part of GPGME-CL. +# +# GPGME-CL is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME-CL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA + +EXTRA_DIST = manifest.json \ + popup.html \ + entry.js \ + maindemo.js \ + mainui.html \ + testicon.png \ + ui.css diff --git a/lang/js/Makefile.am b/lang/js/Makefile.am new file mode 100644 index 0000000..4b5c717 --- /dev/null +++ b/lang/js/Makefile.am @@ -0,0 +1,34 @@ +# Makefile.am for GPGME-JS. +# Copyright (C) 2018 2018 Bundesamt f?r Sicherheit in der Informationstechnik +# +# This file is part of GPGME-JS. +# +# GPGME-JS is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME-JS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA + +SUBDIRS = src BrowserTestExtension DemoExtension + +EXTRA_DIST = build_extensions.sh \ + CHECKLIST \ + CHECKLIST_build \ + .eslintrc.json \ + Makefile.am \ + package.json \ + README \ + README_testing \ + unittest_inputvalues.js \ + unittests.js \ + webpack.conf.js \ + webpack.conf_unittests.js diff --git a/lang/js/src/Makefile.am b/lang/js/src/Makefile.am new file mode 100644 index 0000000..dd330d5 --- /dev/null +++ b/lang/js/src/Makefile.am @@ -0,0 +1,30 @@ +# Makefile.am for GPGME-JS. +# Copyright (C) 2018 Intevation GmbH +# +# This file is part of GPGME. +# +# GPGME-CL is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME-CL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA + +EXTRA_DIST = Connection.js \ + Errors.js \ + gpgmejs.js \ + Helpers.js \ + index.js \ + Key.js \ + Keyring.js \ + Message.js \ + permittedOperations.js \ + Signature.js ----------------------------------------------------------------------- Summary of changes: configure.ac | 27 +++++++++++++++++++- lang/Makefile.am | 2 +- lang/js/BrowserTestExtension/Makefile.am | 42 +++++++++++++++++++++++++++++++ lang/{cl => js/DemoExtension}/Makefile.am | 18 ++++++------- lang/js/Makefile.am | 34 +++++++++++++++++++++++++ lang/{cpp => js/src}/Makefile.am | 20 +++++++++------ 6 files changed, 125 insertions(+), 18 deletions(-) create mode 100644 lang/js/BrowserTestExtension/Makefile.am copy lang/{cl => js/DemoExtension}/Makefile.am (73%) create mode 100644 lang/js/Makefile.am copy lang/{cpp => js/src}/Makefile.am (66%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 20 02:13:33 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 20 Jun 2018 02:13:33 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-158-g861f1da Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 861f1da0731bf29dcb9221c4f22c76b40ec15a78 (commit) from 08147f8bbdca40c98c2a094fa48fab15b8339c80 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 861f1da0731bf29dcb9221c4f22c76b40ec15a78 Author: NIIBE Yutaka Date: Wed Jun 20 08:59:05 2018 +0900 libdns: Let kernel to decide the local port. * dirmngr/dns.c (LEAVE_SELECTION_OF_PORT_TO_KERNEL): New. (dns_socket): Don't select ephemeral port in user space. -- There is no good reason to bind local port aggressively. It might be some reason to do so, then, a user can specify it in /etc/resolv.conf by the second argument of "interface" directive. At least, it causes a problem on Windows. Binding a specified port in user space can trigger the Firewall dialog on Windows. Since it can be considered valid question, it is better not to bind with an ephemeral port which is selected in user space, by default. GnuPG-bug-id: 3610 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 908bf15..f82ed26 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -7121,6 +7121,8 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) { if (type != SOCK_DGRAM) return fd; +#define LEAVE_SELECTION_OF_PORT_TO_KERNEL +#if !defined(LEAVE_SELECTION_OF_PORT_TO_KERNEL) /* * FreeBSD, Linux, OpenBSD, OS X, and Solaris use random ports by * default. Though the ephemeral range is quite small on OS X @@ -7146,6 +7148,7 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) { /* NB: continue to next bind statement */ } +#endif if (0 == bind(fd, local, dns_sa_len(local))) return fd; ----------------------------------------------------------------------- Summary of changes: dirmngr/dns.c | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 20 02:14:52 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 20 Jun 2018 02:14:52 +0200 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.8-12-g72a35ff Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-2 has been updated via 72a35ffee022f1bf180d02250c5be6a4edb599e7 (commit) from 87d0ecf8a1b80139a6cab2a79f1ca6e287207999 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 72a35ffee022f1bf180d02250c5be6a4edb599e7 Author: NIIBE Yutaka Date: Wed Jun 20 08:59:05 2018 +0900 libdns: Let kernel to decide the local port. * dirmngr/dns.c (LEAVE_SELECTION_OF_PORT_TO_KERNEL): New. (dns_socket): Don't select ephemeral port in user space. -- Cherry picked from master commit: 861f1da0731bf29dcb9221c4f22c76b40ec15a78 There is no good reason to bind local port aggressively. It might be some reason to do so, then, a user can specify it in /etc/resolv.conf by the second argument of "interface" directive. At least, it causes a problem on Windows. Binding a specified port in user space can trigger the Firewall dialog on Windows. Since it can be considered valid question, it is better not to bind with an ephemeral port which is selected in user space, by default. GnuPG-bug-id: 3610 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 908bf15..f82ed26 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -7121,6 +7121,8 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) { if (type != SOCK_DGRAM) return fd; +#define LEAVE_SELECTION_OF_PORT_TO_KERNEL +#if !defined(LEAVE_SELECTION_OF_PORT_TO_KERNEL) /* * FreeBSD, Linux, OpenBSD, OS X, and Solaris use random ports by * default. Though the ephemeral range is quite small on OS X @@ -7146,6 +7148,7 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) { /* NB: continue to next bind statement */ } +#endif if (0 == bind(fd, local, dns_sa_len(local))) return fd; ----------------------------------------------------------------------- Summary of changes: dirmngr/dns.c | 3 +++ 1 file changed, 3 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 20 10:52:00 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 20 Jun 2018 10:52:00 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-63-gd8beab3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via d8beab30c44482fb7a3e445b92cec482792b2ca0 (commit) from 19c5267f868aa41e73752ac1c76ec7ae1efe07b8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d8beab30c44482fb7a3e445b92cec482792b2ca0 Author: Andre Heinecke Date: Wed Jun 20 09:43:19 2018 +0200 json: Add file handling for debug output * src/gpgme-json.c (main): Add possibilty to set log file. -- This is similar to how GPGME_DEBUG works. It takes ; on Windows as seperator and : on linux. Followed by a file name. For Linux it might make sense to use a different seperator to allow setting a socket explicitly. But this is better in line with the current GPGME_DEBUG behavior. The change helps on Windows where we don't have a log socket. diff --git a/src/gpgme-json.c b/src/gpgme-json.c index ae878bd..d7e1cbc 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -3617,6 +3617,8 @@ main (int argc, char *argv[]) }; gpgrt_argparse_t pargs = { &argc, &argv}; + int log_file_set = 0; + gpgrt_set_strusage (my_strusage); #ifdef HAVE_SETLOCALE @@ -3653,12 +3655,24 @@ main (int argc, char *argv[]) if (!opt_debug) { + /* Handling is similar to GPGME_DEBUG */ const char *s = getenv ("GPGME_JSON_DEBUG"); + const char *s1; + if (s && atoi (s) > 0) - opt_debug = 1; + { + opt_debug = 1; + s1 = strchr (s, PATHSEP_C); + if (s1 && strlen (s1) > 2) + { + s1++; + log_set_file (s1); + log_file_set = 1; + } + } } - if (opt_debug) + if (opt_debug && !log_file_set) { const char *home = getenv ("HOME"); char *file = xstrconcat ("socket://", ----------------------------------------------------------------------- Summary of changes: src/gpgme-json.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 20 13:45:48 2018 From: cvs at cvs.gnupg.org (by Maximilian Krambach) Date: Wed, 20 Jun 2018 13:45:48 +0200 Subject: [git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-65-g88e7f8e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, javascript-binding has been updated via 88e7f8ec2ef3d90ca014b0bdb246f4d99f82abc8 (commit) from d27703ea4f0eed950cddf0157dc78bcb5d8d1c65 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 88e7f8ec2ef3d90ca014b0bdb246f4d99f82abc8 Author: Maximilian Krambach Date: Wed Jun 20 13:42:19 2018 +0200 js: Demoextension update -- * src/Signature: typo * src/gpgmejs.js: fixed wrong scope in verification * right now verify does not succeed in the DemoExtension. This is probably a problem in conversion or line ending. diff --git a/lang/js/DemoExtension/maindemo.js b/lang/js/DemoExtension/maindemo.js index 6230c3f..d0127c7 100644 --- a/lang/js/DemoExtension/maindemo.js +++ b/lang/js/DemoExtension/maindemo.js @@ -27,7 +27,7 @@ document.addEventListener('DOMContentLoaded', function() { Gpgmejs.init().then(function(gpgmejs){ document.getElementById('buttonencrypt').addEventListener('click', function(){ - let data = document.getElementById('cleartext').value; + let data = document.getElementById('inputtext').value; let keyId = document.getElementById('pubkey').value; gpgmejs.encrypt(data, keyId).then( function(answer){ @@ -42,7 +42,7 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('buttondecrypt').addEventListener('click', function(){ - let data = document.getElementById('ciphertext').value; + let data = document.getElementById('inputtext').value; gpgmejs.decrypt(data).then( function(answer){ if (answer.data){ @@ -57,11 +57,46 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('getdefaultkey').addEventListener('click', function(){ gpgmejs.Keyring.getDefaultKey().then(function(answer){ - document.getElementById('defaultkey').textContent = + document.getElementById('pubkey').value = answer.fingerprint; }, function(errormsg){ alert(errormsg.message); }); }); + + document.getElementById('signtext').addEventListener('click', + function(){ + let data = document.getElementById('inputtext').value; + let keyId = document.getElementById('pubkey').value; + gpgmejs.sign(data, keyId).then( + function(answer){ + if (answer.data){ + document.getElementById( + 'answer').value = answer.data; + } + }, function(errormsg){ + alert( errormsg.message); + }); + }); + + document.getElementById('verifytext').addEventListener('click', + function(){ + let data = document.getElementById('inputtext').value; + gpgmejs.verify(data).then( + function(answer){ + let vals = ''; + if (answer.all_valid === true){ + vals = 'Success! '; + } else { + vals = 'Failure! '; + } + vals = vals + (answer.count - answer.failures) + 'of ' + + answer.count + ' signature(s) were successfully ' + + 'verified.\n\n' + answer.data; + document.getElementById('answer').value = vals; + }, function(errormsg){ + alert( errormsg.message); + }); + }); }); }); diff --git a/lang/js/DemoExtension/mainui.html b/lang/js/DemoExtension/mainui.html index 91be7bb..b639036 100644 --- a/lang/js/DemoExtension/mainui.html +++ b/lang/js/DemoExtension/mainui.html @@ -7,38 +7,37 @@ -
    -
  • - Text: - -
  • -
  • - Public key ID: - -
  • -
-
-
-
    -
  • - Encrypted armored Text: - -
  • -
-
-
-

Result data:

- +
-
-
    -
  • - Default Key: -
    - -
  • +
    +
      +
    • + Input + +
    • +
    • + Fingerprint of Key to use: +
    • +
      + + +
    +
    +
    +
      +
    • + Result + +
    • +
    +
    +
+
+
+
+
+
- - - +
+ diff --git a/lang/js/DemoExtension/ui.css b/lang/js/DemoExtension/ui.css index 9c88698..16dfb5a 100644 --- a/lang/js/DemoExtension/ui.css +++ b/lang/js/DemoExtension/ui.css @@ -8,3 +8,26 @@ ul li span { width: 120px; margin-top: 6px; } + +div .left { + float: left; + align-items: stretch; + width: 40%; +} +div .center { + width: 50%; + align-content: space-between; +} + +div .center button { + align-self: stretch; +} +div .right { + float: right; + align-items: stretch; + width: 40%; +} + +div .bottom { + clear:both; +} \ No newline at end of file diff --git a/lang/js/src/Signature.js b/lang/js/src/Signature.js index d7d0598..a07fc4d 100644 --- a/lang/js/src/Signature.js +++ b/lang/js/src/Signature.js @@ -35,7 +35,7 @@ export function createSignature(sigObject){ if ( typeof(sigObject) !=='object' || !sigObject.hasOwnProperty('summary') || - !sigObject.hasOwnProperty('fingerpprint') || + !sigObject.hasOwnProperty('fingerprint') || !sigObject.hasOwnProperty('timestamp') //TODO check if timestamp is mandatory in specification ){ @@ -67,6 +67,7 @@ export function createSignature(sigObject){ } } } + console.log('sig created'); return new GPGME_Signature(sigObject); } @@ -178,7 +179,8 @@ const expSum = { 'crl-missing': 'boolean', 'crl-too-old': 'boolean', 'bad-policy': 'boolean', - 'sys-error': 'boolean' + 'sys-error': 'boolean', + 'sigsum': 'object' }; /** diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index a0f7e96..c2a6b8b 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -168,7 +168,7 @@ export class GpgME { /** * Sign a Message - * @param {String|Object} data text/data to be decrypted. Accepts Strings + * @param {String|Object} data text/data to be signed. Accepts Strings * and Objects with a gettext methos * @param {GPGME_Key|String|Array|Array} keys The * key/keys to use for signing @@ -238,7 +238,7 @@ export class GpgME { */ verify(data, signature, base64 = false){ let msg = createMessage('verify'); - let dt = this.putData(msg, data); + let dt = putData(msg, data); if (dt instanceof Error){ return Promise.reject(dt); } @@ -317,7 +317,7 @@ function collectSignatures(sigs){ for (let i=0; i< sigs.length; i++){ let sigObj = createSignature(sigs[i]); if (sigObj instanceof Error){ - return gpgme_error('SIG_WRONG'); + return gpgme_error(sigObj); } if (sigObj.valid !== true){ summary.failures += 1; ----------------------------------------------------------------------- Summary of changes: lang/js/DemoExtension/maindemo.js | 41 +++++++++++++++++++++++-- lang/js/DemoExtension/mainui.html | 63 +++++++++++++++++++-------------------- lang/js/DemoExtension/ui.css | 23 ++++++++++++++ lang/js/src/Signature.js | 6 ++-- lang/js/src/gpgmejs.js | 6 ++-- 5 files changed, 99 insertions(+), 40 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 20 14:03:36 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 20 Jun 2018 14:03:36 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-5-g9f132ff Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 9f132ff7cbc2f2484ce234f7d4bb163bb743f703 (commit) via e26e6b58b48e45c5e5ce9a1ac3d2e0e28a4cb277 (commit) from 8576131bc84d41b8b68ae92461c063774d3064fc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9f132ff7cbc2f2484ce234f7d4bb163bb743f703 Author: Andre Heinecke Date: Wed Jun 20 13:56:19 2018 +0200 Prepare keycache for autoencryption * src/keycache.cpp, * src/mail.cpp, src/mail.h (set_crypto_selected_manually), (increment_locate_count, decrement_locate_count): New stateholders. * src/keycache.cpp (LocateArgs): Argument helper to carry mail. (startLocate, startLocateSecret): Add mail argument and use it. * src/keycache.h: Update accordingly. -- This keeps track of how many locate threads are running on a mail. So that we can handle the state where all locates for a mail are done. This prepares: GnuPG-Bug-Id: T3999 diff --git a/src/keycache.cpp b/src/keycache.cpp index 3239e33..277f461 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -23,6 +23,7 @@ #include "common.h" #include "cpphelp.h" +#include "mail.h" #include #include @@ -35,6 +36,53 @@ GPGRT_LOCK_DEFINE (keycache_lock); static KeyCache* singleton = nullptr; +/** At some point we need to set a limit. There + seems to be no limit on how many recipients a mail + can have in outlook. + + We would run out of resources or block. + + 50 Threads already seems a bit excessive but + it should really cover most legit use cases. +*/ + +#define MAX_LOCATOR_THREADS 50 +static int s_thread_cnt; + +namespace +{ + class LocateArgs + { + public: + LocateArgs (const std::string& mbox, Mail *mail = nullptr): + m_mbox (mbox), + m_mail (mail) + { + s_thread_cnt++; + Mail::delete_lock (); + if (Mail::is_valid_ptr (m_mail)) + { + m_mail->increment_locate_count (); + } + Mail::delete_unlock (); + }; + + ~LocateArgs() + { + s_thread_cnt--; + Mail::delete_lock (); + if (Mail::is_valid_ptr (m_mail)) + { + m_mail->decrement_locate_count (); + } + Mail::delete_unlock (); + } + + std::string m_mbox; + Mail *m_mail; + }; +} // namespace + class KeyCache::Private { public: @@ -471,7 +519,7 @@ do_locate_secret (LPVOID arg) } void -KeyCache::startLocate (char **recipients) const +KeyCache::startLocate (char **recipients, Mail *mail) const { if (!recipients) { @@ -480,12 +528,12 @@ KeyCache::startLocate (char **recipients) const } for (int i = 0; recipients[i]; i++) { - startLocate (recipients[i]); + startLocate (recipients[i], mail); } } void -KeyCache::startLocate (const char *addr) const +KeyCache::startLocate (const char *addr, Mail *mail) const { if (!addr) { @@ -505,8 +553,9 @@ KeyCache::startLocate (const char *addr) const d->m_pgp_key_map.insert (std::pair (recp, GpgME::Key())); log_debug ("%s:%s Creating a locator thread", SRCNAME, __func__); + const auto args = new LocateArgs(recp, mail); HANDLE thread = CreateThread (NULL, 0, do_locate, - (LPVOID) strdup (recp.c_str ()), 0, + args, 0, NULL); CloseHandle (thread); } @@ -514,7 +563,7 @@ KeyCache::startLocate (const char *addr) const } void -KeyCache::startLocateSecret (const char *addr) const +KeyCache::startLocateSecret (const char *addr, Mail *mail) const { if (!addr) { @@ -534,8 +583,10 @@ KeyCache::startLocateSecret (const char *addr) const d->m_pgp_skey_map.insert (std::pair (recp, GpgME::Key())); log_debug ("%s:%s Creating a locator thread", SRCNAME, __func__); + const auto args = new LocateArgs(recp, mail); + HANDLE thread = CreateThread (NULL, 0, do_locate_secret, - (LPVOID) strdup (recp.c_str ()), 0, + (LPVOID) args, 0, NULL); CloseHandle (thread); } diff --git a/src/keycache.h b/src/keycache.h index 6bda0b9..0364ab1 100644 --- a/src/keycache.h +++ b/src/keycache.h @@ -34,6 +34,8 @@ namespace GpgME class Key; }; +class Mail; + class KeyCache { protected: @@ -58,15 +60,19 @@ public: /* Start a key location in a background thread filling the key cache. cArray is a null terminated array - of address strings. */ - void startLocate (char **cArray) const; + of address strings. + + The mail argument is used to add / remove the + locator thread counter. + */ + void startLocate (char **cArray, Mail *mail) const; /* Look for a secret key for the addr. */ - void startLocateSecret (const char *addr) const; + void startLocateSecret (const char *addr, Mail *mail) const; /* Start a key location in a background thread filling the key cache. */ - void startLocate (const char *addr) const; + void startLocate (const char *addr, Mail *mail) const; // Internal for thread void setSmimeKey(const std::string &mbox, const GpgME::Key &key); diff --git a/src/mail.cpp b/src/mail.cpp index 64d14e5..d61d22b 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -97,7 +97,9 @@ Mail::Mail (LPDISPATCH mailitem) : m_is_forwarded_crypto_mail(false), m_is_reply_crypto_mail(false), m_is_send_again(false), - m_disable_att_remove_warning(false) + m_disable_att_remove_warning(false), + m_manual_crypto_opts(false), + m_locate_count(0) { if (get_mail_for_item (mailitem)) { @@ -2674,9 +2676,9 @@ Mail::locate_keys() // First update oom data to have recipients and sender updated. update_oom_data (); char ** recipients = take_cached_recipients (); - KeyCache::instance()->startLocateSecret (get_sender ().c_str ()); - KeyCache::instance()->startLocate (get_sender ().c_str ()); - KeyCache::instance()->startLocate (recipients); + KeyCache::instance()->startLocateSecret (get_sender ().c_str (), this); + KeyCache::instance()->startLocate (get_sender ().c_str (), this); + KeyCache::instance()->startLocate (recipients, this); release_cArray (recipients); locate_in_progress = false; } @@ -3219,3 +3221,15 @@ Mail::set_block_html(bool value) { m_block_html = value; } + +void +Mail::increment_locate_count() +{ + m_locate_count++; +} + +void +Mail::decrement_locate_count() +{ + m_locate_count--; +} diff --git a/src/mail.h b/src/mail.h index 83483f2..7e6ea21 100644 --- a/src/mail.h +++ b/src/mail.h @@ -530,6 +530,18 @@ public: /* Remove automatic loading of HTML references setting. */ void set_block_status (); + /* Crypto options (sign/encrypt) have been set manually. */ + void set_crypto_selected_manually (bool v) { m_manual_crypto_opts = v; } + // bool is_crypto_selected_manually () const { return m_manual_crypto_opts; } + + /* Reference that a resolver thread is running for this mail. */ + void increment_locate_count (); + + /* To be called when a resolver thread is done. If there are no running + resolver threads we can check the recipients to see if we should + toggle / untoggle the secure state. */ + void decrement_locate_count (); + private: void update_categories (); void update_sigstate (); @@ -574,5 +586,7 @@ private: bool m_is_send_again; /* Is this a send again of a crypto mail */ bool m_disable_att_remove_warning; /* Should not warn about attachment removal. */ bool m_block_html; /* Force blocking of html content. e.g for unsigned S/MIME mails. */ + bool m_manual_crypto_opts; /* Crypto options (sign/encrypt) have been set manually. */ + int m_locate_count; /* The number of key locates pending for this mail. */ }; #endif // MAIL_H commit e26e6b58b48e45c5e5ce9a1ac3d2e0e28a4cb277 Author: Andre Heinecke Date: Wed Jun 20 13:33:28 2018 +0200 Locks and more locks * src/mail.cpp (mail_map_lock, uid_map_lock): New locks. (Mail::Mail, Mail::~Mail, Mail::get_mail_for_item), (Mail::get_mail_for_uuid, Mail::is_valid_ptr), (Mail::close_all_mails, Mail::revert_all_mails), (Mail::revert_all_mails, Mail::wipe_all_mails), (Mail::set_uuid, Mail::locate_all_crypto_recipients) (Mail::delete_lock, Mail::delete_unlock): New helpers to ensure a mail pointer stays valid. * src/mail.h: Update accordingly. -- As the mail object is used from more and more threads and will soon be used even more for autoencryption we have to be _very_ careful to minimize / remove race conditions which could lead to a crash. For autoencryption we will have async code working on every new mail. Prepares: GnuPG-Bug-Id: T3999 diff --git a/src/mail.cpp b/src/mail.cpp index 47d7367..64d14e5 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -63,6 +63,9 @@ static std::map s_mail_map; static std::map s_uid_map; static std::set uids_searched; +GPGRT_LOCK_DEFINE (mail_map_lock); +GPGRT_LOCK_DEFINE (uid_map_lock); + static Mail *s_last_mail; #define COPYBUFSIZE (8 * 1024) @@ -113,12 +116,28 @@ Mail::Mail (LPDISPATCH mailitem) : gpgol_release(mailitem); return; } + gpgrt_lock_lock (&mail_map_lock); s_mail_map.insert (std::pair (mailitem, this)); + gpgrt_lock_unlock (&mail_map_lock); s_last_mail = this; } GPGRT_LOCK_DEFINE(dtor_lock); +// static +void +Mail::delete_lock () +{ + gpgrt_lock_lock (&dtor_lock); +} + +// static +void +Mail::delete_unlock () +{ + gpgrt_lock_unlock (&dtor_lock); +} + Mail::~Mail() { /* This should fix a race condition where the mail is @@ -138,19 +157,23 @@ Mail::~Mail() log_oom_extra ("%s:%s: Erasing mail", SRCNAME, __func__); + gpgrt_lock_lock (&mail_map_lock); it = s_mail_map.find(m_mailitem); if (it != s_mail_map.end()) { s_mail_map.erase (it); } + gpgrt_lock_unlock (&mail_map_lock); if (!m_uuid.empty()) { + gpgrt_lock_lock (&uid_map_lock); auto it2 = s_uid_map.find(m_uuid); if (it2 != s_uid_map.end()) { s_uid_map.erase (it2); } + gpgrt_lock_unlock (&uid_map_lock); } log_oom_extra ("%s:%s: releasing mailitem", @@ -186,7 +209,9 @@ Mail::get_mail_for_item (LPDISPATCH mailitem) return NULL; } std::map::iterator it; + gpgrt_lock_lock (&mail_map_lock); it = s_mail_map.find(mailitem); + gpgrt_lock_unlock (&mail_map_lock); if (it == s_mail_map.end()) { return NULL; @@ -201,7 +226,9 @@ Mail::get_mail_for_uuid (const char *uuid) { return NULL; } + gpgrt_lock_lock (&uid_map_lock); auto it = s_uid_map.find(std::string(uuid)); + gpgrt_lock_unlock (&uid_map_lock); if (it == s_uid_map.end()) { return NULL; @@ -212,13 +239,18 @@ Mail::get_mail_for_uuid (const char *uuid) bool Mail::is_valid_ptr (const Mail *mail) { + gpgrt_lock_lock (&mail_map_lock); auto it = s_mail_map.begin(); while (it != s_mail_map.end()) { if (it->second == mail) - return true; + { + gpgrt_lock_unlock (&mail_map_lock); + return true; + } ++it; } + gpgrt_lock_unlock (&mail_map_lock); return false; } @@ -1553,7 +1585,9 @@ Mail::close_all_mails () int err = 0; std::map::iterator it; TRACEPOINT; + gpgrt_lock_lock (&mail_map_lock); std::map mail_map_copy = s_mail_map; + gpgrt_lock_unlock (&mail_map_lock); for (it = mail_map_copy.begin(); it != mail_map_copy.end(); ++it) { /* XXX For non racy code the is_valid_ptr check should not @@ -1587,6 +1621,7 @@ Mail::revert_all_mails () { int err = 0; std::map::iterator it; + gpgrt_lock_lock (&mail_map_lock); for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { if (it->second->revert ()) @@ -1604,6 +1639,7 @@ Mail::revert_all_mails () continue; } } + gpgrt_lock_unlock (&mail_map_lock); return err; } @@ -1612,6 +1648,7 @@ Mail::wipe_all_mails () { int err = 0; std::map::iterator it; + gpgrt_lock_lock (&mail_map_lock); for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { if (it->second->wipe ()) @@ -1620,6 +1657,7 @@ Mail::wipe_all_mails () err++; } } + gpgrt_lock_unlock (&mail_map_lock); return err; } @@ -2094,7 +2132,10 @@ Mail::set_uuid() SRCNAME, __func__, m_mailitem, uuid); delete other; } + + gpgrt_lock_lock (&uid_map_lock); s_uid_map.insert (std::pair (m_uuid, this)); + gpgrt_lock_unlock (&uid_map_lock); log_debug ("%s:%s: uuid for %p is now %s", SRCNAME, __func__, this, m_uuid.c_str()); @@ -2966,6 +3007,7 @@ Mail::locate_all_crypto_recipients() return; } + gpgrt_lock_lock (&mail_map_lock); std::map::iterator it; for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { @@ -2974,6 +3016,7 @@ Mail::locate_all_crypto_recipients() it->second->locate_keys (); } } + gpgrt_lock_unlock (&mail_map_lock); } int diff --git a/src/mail.h b/src/mail.h index 7f4ed7b..83483f2 100644 --- a/src/mail.h +++ b/src/mail.h @@ -92,8 +92,34 @@ public: */ static Mail* get_last_mail (); + /** @brief voids the last mail variable. */ static void invalidate_last_mail (); + /** @brief Lock mail deletion. + + Mails are heavily accessed multi threaded. E.g. when locating + keys. Due to bad timing it would be possible that between + a check for "is_valid_ptr" to see if a map is still valid + and the usage of the mail a delete would happen. + + This lock can be used to prevent that. Changes made to the + mail will of course have no effect as the mail is already in + the process of beeing unloaded. And calls that access MAPI + or OOM still might crash. But this at least gurantees that + the member variables of the mail exist while the lock is taken. + + Use it in your thread like: + + Mail::delete_lock (); + Mail::is_valid_ptr (mail); + mail->set_or_check_something (); + Mail::delete_unlock (); + + Still be carefull when it is a mapi or oom function. + */ + static void delete_lock (); + static void delete_unlock (); + /** @brief looks for existing Mail objects. @returns A reference to an existing mailitem or NULL in case none ----------------------------------------------------------------------- Summary of changes: src/keycache.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++----- src/keycache.h | 14 ++++++++---- src/mail.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++----- src/mail.h | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 15 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 20 15:00:48 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Wed, 20 Jun 2018 15:00:48 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-7-g630844d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 630844dc453ac59cbd73beb225548b40d7d1b239 (commit) via 027fca10518a088467be8b0507603d25c6c50a8e (commit) from 9f132ff7cbc2f2484ce234f7d4bb163bb743f703 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 630844dc453ac59cbd73beb225548b40d7d1b239 Author: Andre Heinecke Date: Wed Jun 20 14:58:16 2018 +0200 Handle always sign/encrypt for inline reply/fw * src/mailitem-events.cpp (reply, forward, replyall): Handle the always sign/encrypt options. -- If the option reply_crypt is set and the reply is to a crypto mail the settings from that mail will override the always options. Previously this only worked in the Open command so only if a new message composer window was opened. This fixes a problem noticed in: GnuPG-Bug-Id: T4037 diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 4805f5f..b499966 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -734,11 +734,52 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: %s : %p", SRCNAME, __func__, is_reply ? "reply" : "forward", m_mail); - if (!m_mail->is_crypto_mail ()) + int draft_flags = 0; + if (opt.encrypt_default) + { + draft_flags = 1; + } + if (opt.sign_default) { - /* Non crypto mails do not interest us.*/ + draft_flags += 2; + } + bool is_crypto_mail = m_mail->is_crypto_mail(); + + /* If it is a crypto mail and the settings should not be taken + * from the crypto mail and always encrypt / sign is on. Or + * If it is not a crypto mail and we have automaticalls sign_encrypt. */ + if ((is_crypto_mail && !opt.reply_crypt && draft_flags) || + (!is_crypto_mail && draft_flags)) + { + /* Check if we can use the dispval */ + if (parms->cArgs == 2 && parms->rgvarg[1].vt == (VT_DISPATCH) && + parms->rgvarg[0].vt == (VT_BOOL | VT_BYREF)) + { + LPMESSAGE msg = get_oom_base_message (parms->rgvarg[1].pdispVal); + if (msg) + { + set_gpgol_draft_info_flags (msg, draft_flags); + gpgol_release (msg); + } + else + { + log_error ("%s:%s: Failed to get base message.", + SRCNAME, __func__); + } + } + else + { + log_error ("%s:%s: Unexpected parameters.", + SRCNAME, __func__); + } + } + + if (!is_crypto_mail) + { + /* Replys to non crypto mails do not interest us anymore. */ break; } + Mail *last_mail = Mail::get_last_mail (); if (Mail::is_valid_ptr (last_mail)) { commit 027fca10518a088467be8b0507603d25c6c50a8e Author: Andre Heinecke Date: Wed Jun 20 14:21:02 2018 +0200 Add clarifying comment about forward reply detect -- I just looked at it and at first could not remember why I didn't just use the pdispVal. diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 9effeb1..4805f5f 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -745,6 +745,10 @@ EVENT_SINK_INVOKE(MailItemEvents) /* We want to identify here if there was a mail created that should receive the contents of this mail. For this we check for a forward in the same loop as a mail creation. + + We need to do it this complicated and can't just use + get_mail_for_item because the mailitem pointer we get here + is a different one then the one with which the mail was loaded. */ char *lastEntryID = get_oom_string (last_mail->item (), "EntryID"); int lastSize = get_oom_int (last_mail->item (), "Size"); ----------------------------------------------------------------------- Summary of changes: src/mailitem-events.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 21 11:17:45 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Jun 2018 11:17:45 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-8-gc8f4655 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via c8f46557da704d863052709d5b627970450a0d1d (commit) from 630844dc453ac59cbd73beb225548b40d7d1b239 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c8f46557da704d863052709d5b627970450a0d1d Author: Andre Heinecke Date: Thu Jun 21 10:40:39 2018 +0200 Implement auto secure feature * src/common_indep.h (opt): Add autosecure. * src/cryptcontroller.cpp (CryptController::CryptController): Adopt new API. * src/keycache.cpp (do_locate, do_locate_secret): Fix broken handling of args. (locate_secret): Add check for empty mbox. Otherwise it could select the first secret key if the sender address could not be resolved. (KeyCache::startLocate): Take recipients as vector. (KeyCache::isMailResolvable): New. Check if all keys are found in the cache. * src/keycache.h: Update accordingly. * src/mail.cpp (m_cached_recipients): Use a vector instead of a carray. (m_first_autoresolve_check): Track state of autoresolve. (Mail::~Mail): No need to free cached recipients. (Mail::update_oom_data): Use vector for cached recipients. (Mail::locate_keys): Adapt to new recipients API. Do autoresolve_check. (Mail::take_cached_recipients): Removed. (Mail::get_cached_recipents): New. Get a copy of the recipients. (Mail::decrement_locate_count): Trigger autoresolve check. (Mail::autoresolve_check_s): New. Check if mail is resolvable. * src/mail.h: Update accordingly. * src/mailitem-events.cpp (RecipientAdded): Handle opt.autosecure. * src/main.c (read_options): Read autosecure. * src/ribbon-callbacks.cpp (mark_mime_action): Use more modern style. Mark if crypto state was set manually. * src/windowmessages.cpp (DO_AUTO_SECURE, DONT_AUTO_SECURE): New messages to set state. -- This is a first implementation of opportunistic encryption in GpgOL. If we have enough keys with marginal validity or if the keys come from WKD we can select "secure" automatically. GnuPG-Bug-Id: T3999 diff --git a/src/common_indep.h b/src/common_indep.h index f1805a9..285ab42 100644 --- a/src/common_indep.h +++ b/src/common_indep.h @@ -192,6 +192,7 @@ struct int prefer_html; /* Prefer html in html/text alternatives. */ int inline_pgp; /* Only for Addin. Use Inline PGP by default. */ int autoresolve; /* Autresolve keys with --locate-keys. */ + int autosecure; /* Autmatically encrypt if locate returns enough validity. */ int reply_crypt; /* Only for Addin. Encrypt / Sign based on cryptostatus. */ int smime_html_warn_shown; /* Flag to save if unsigned smime warning was shown */ diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 7f701b2..df5366c 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -70,7 +70,7 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign, { log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", SRCNAME, __func__, mail, encrypt, sign, mail->do_pgp_inline ()); - m_recipient_addrs = mail->take_cached_recipients (); + m_recipient_addrs = vector_to_cArray (mail->get_cached_recipients ()); } CryptController::~CryptController() diff --git a/src/keycache.cpp b/src/keycache.cpp index 277f461..742046f 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -362,8 +362,10 @@ do_locate (LPVOID arg) { return 0; } - std::string addr = (char*) arg; - xfree (arg); + + auto args = std::unique_ptr ((LocateArgs *) arg); + + const auto addr = args->m_mbox; log_mime_parser ("%s:%s searching key for addr: \"%s\"", SRCNAME, __func__, addr.c_str()); @@ -437,7 +439,7 @@ do_locate (LPVOID arg) } static void -locate_secret (char *addr, GpgME::Protocol proto) +locate_secret (const char *addr, GpgME::Protocol proto) { auto ctx = std::unique_ptr ( GpgME::Context::createForProtocol (proto)); @@ -453,6 +455,13 @@ locate_secret (char *addr, GpgME::Protocol proto) } const auto mbox = GpgME::UserID::addrSpecFromString (addr); + if (mbox.empty()) + { + log_debug ("%s:%s: Empty mbox for addr %s", + SRCNAME, __func__, addr); + return; + } + // We need to validate here to fetch CRL's ctx->setKeyListMode (GpgME::KeyListMode::Local | GpgME::KeyListMode::Validate); @@ -502,33 +511,27 @@ locate_secret (char *addr, GpgME::Protocol proto) static DWORD WINAPI do_locate_secret (LPVOID arg) { - char *addr = (char*) arg; + auto args = std::unique_ptr ((LocateArgs *) arg); log_mime_parser ("%s:%s searching secret key for addr: \"%s\"", - SRCNAME, __func__, addr); + SRCNAME, __func__, args->m_mbox.c_str ()); - locate_secret (addr, GpgME::OpenPGP); + locate_secret (args->m_mbox.c_str(), GpgME::OpenPGP); if (opt.enable_smime) { - locate_secret (addr, GpgME::CMS); + locate_secret (args->m_mbox.c_str(), GpgME::CMS); } - xfree (addr); log_debug ("%s:%s locator sthread thread done", SRCNAME, __func__); return 0; } void -KeyCache::startLocate (char **recipients, Mail *mail) const +KeyCache::startLocate (const std::vector &addrs, Mail *mail) const { - if (!recipients) - { - TRACEPOINT; - return; - } - for (int i = 0; recipients[i]; i++) + for (const auto &addr: addrs) { - startLocate (recipients[i], mail); + startLocate (addr.c_str(), mail); } } @@ -617,3 +620,56 @@ KeyCache::setPgpKeySecret(const std::string &mbox, const GpgME::Key &key) { d->setPgpKeySecret(mbox, key); } + +int +KeyCache::isMailResolvable(Mail *mail) +{ + /* Get the data from the mail. */ + const auto sender = mail->get_cached_sender(); + auto recps = mail->get_cached_recipients(); + + if (sender.empty() || recps.empty()) + { + log_debug ("%s:%s: Mail has no sender or no recipients.", + SRCNAME, __func__); + return 0; + } + + /* Include sender for encryption */ + recps.push_back (sender); + + GpgME::Key sigKey = getSigningKey (sender.c_str(), GpgME::OpenPGP); + std::vector encKeys = getEncryptionKeys (recps, + GpgME::OpenPGP); + + int pgpState = 0; + if (!encKeys.empty()) + { + pgpState = 1; + } + if (!sigKey.isNull()) + { + pgpState += 2; + } + + if (pgpState == 3 /* all good */ || !opt.enable_smime) + { + return pgpState; + } + + /* Check S/MIME instead */ + sigKey = getSigningKey (sender.c_str(), GpgME::CMS); + encKeys = getEncryptionKeys (recps, GpgME::CMS); + + int cmsState = 0; + if (!encKeys.empty()) + { + cmsState = 1; + } + if (!sigKey.isNull()) + { + cmsState += 2; + } + + return (cmsState > pgpState) ? cmsState : pgpState; +} diff --git a/src/keycache.h b/src/keycache.h index 0364ab1..7c4b4be 100644 --- a/src/keycache.h +++ b/src/keycache.h @@ -59,13 +59,12 @@ public: GpgME::Protocol proto) const; /* Start a key location in a background thread filling - the key cache. cArray is a null terminated array - of address strings. + the key cache. The mail argument is used to add / remove the locator thread counter. */ - void startLocate (char **cArray, Mail *mail) const; + void startLocate (const std::vector &addrs, Mail *mail) const; /* Look for a secret key for the addr. */ void startLocateSecret (const char *addr, Mail *mail) const; @@ -74,6 +73,12 @@ public: the key cache. */ void startLocate (const char *addr, Mail *mail) const; + /* Check that a mail is resolvable through the keycache. + * + * Returns the usual int with sign = 2 and encrypt = 1 + **/ + int isMailResolvable (Mail *mail); + // Internal for thread void setSmimeKey(const std::string &mbox, const GpgME::Key &key); void setPgpKey(const std::string &mbox, const GpgME::Key &key); diff --git a/src/mail.cpp b/src/mail.cpp index d61d22b..f02f127 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -87,7 +87,6 @@ Mail::Mail (LPDISPATCH mailitem) : m_crypto_flags(0), m_cached_html_body(nullptr), m_cached_plain_body(nullptr), - m_cached_recipients(nullptr), m_type(MSGTYPE_UNKNOWN), m_do_inline(false), m_is_gsuite(false), @@ -99,6 +98,7 @@ Mail::Mail (LPDISPATCH mailitem) : m_is_send_again(false), m_disable_att_remove_warning(false), m_manual_crypto_opts(false), + m_first_autosecure_check(true), m_locate_count(0) { if (get_mail_for_item (mailitem)) @@ -183,7 +183,6 @@ Mail::~Mail() gpgol_release(m_mailitem); xfree (m_cached_html_body); xfree (m_cached_plain_body); - release_cArray (m_cached_recipients); if (!m_uuid.empty()) { log_oom_extra ("%s:%s: destroyed: %p uuid: %s", @@ -1519,8 +1518,9 @@ Mail::update_oom_data () xfree (m_cached_plain_body); m_cached_plain_body = get_oom_string (m_mailitem, "Body"); - release_cArray (m_cached_recipients); - m_cached_recipients = get_recipients (); + char **recipients = get_recipients (); + m_cached_recipients = cArray_to_vector ((const char **)recipients); + xfree (recipients); } /* For some reason outlook may store the recipient address in the send using account field. If we have SMTP we prefer @@ -2675,11 +2675,11 @@ Mail::locate_keys() // First update oom data to have recipients and sender updated. update_oom_data (); - char ** recipients = take_cached_recipients (); KeyCache::instance()->startLocateSecret (get_sender ().c_str (), this); KeyCache::instance()->startLocate (get_sender ().c_str (), this); - KeyCache::instance()->startLocate (recipients, this); - release_cArray (recipients); + KeyCache::instance()->startLocate (get_cached_recipients (), this); + autoresolve_check_s (); + locate_in_progress = false; } @@ -2723,12 +2723,10 @@ Mail::needs_encrypt() const return m_needs_encrypt; } -char ** -Mail::take_cached_recipients() +std::vector +Mail::get_cached_recipients() { - char **ret = m_cached_recipients; - m_cached_recipients = nullptr; - return ret; + return m_cached_recipients; } void @@ -3232,4 +3230,70 @@ void Mail::decrement_locate_count() { m_locate_count--; + + if (m_locate_count < 0) + { + log_error ("%s:%s: locate count mismatch.", + SRCNAME, __func__); + m_locate_count = 0; + } + if (!m_locate_count) + { + autoresolve_check_s (); + } +} + +void +Mail::autoresolve_check_s() +{ + if (!opt.autoresolve || m_manual_crypto_opts) + { + return; + } + int ret = KeyCache::instance()->isMailResolvable (this); + + log_debug ("%s:%s: status %i", + SRCNAME, __func__, ret); + + /* As we are safe to call at any time, because we need + * to be triggered by the locator threads finishing we + * need to actually set the draft info flags in + * the ui thread. */ + if (ret == 3) + { + do_in_ui_thread (DO_AUTO_SECURE, this); + } + else + { + do_in_ui_thread (DONT_AUTO_SECURE, this); + } + return; +} + +void +Mail::set_do_autosecure_mapi(bool value) +{ + TRACEPOINT; + LPMESSAGE msg = get_oom_base_message (m_mailitem); + + if (!msg) + { + TRACEPOINT; + } + int old_flags = get_gpgol_draft_info_flags (msg); + if (old_flags && m_first_autosecure_check) + { + /* They were set explicily before us. This can be + * because they were a draft (which is bad) or + * because they are a reply/forward to a crypto mail + * or because there are conflicting settings. */ + log_debug ("%s:%s: Mail %p had already flags set.", + SRCNAME, __func__, m_mailitem); + m_first_autosecure_check = false; + m_manual_crypto_opts = true; + return; + } + m_first_autosecure_check = false; + set_gpgol_draft_info_flags (msg, value ? 3 : 0); + gpgoladdin_invalidate_ui(); } diff --git a/src/mail.h b/src/mail.h index 7e6ea21..afd8d09 100644 --- a/src/mail.h +++ b/src/mail.h @@ -384,10 +384,8 @@ public: */ char *take_cached_plain_body (); - /** Get the cached recipients. It is updated in update_oom_data. - Caller takes ownership of the list and has to free it. - */ - char **take_cached_recipients (); + /** Get the cached recipients. It is updated in update_oom_data.*/ + std::vector get_cached_recipients (); /** Returns 1 if the mail was encrypted, 2 if signed, 3 if both. Only valid after decrypt_verify. @@ -539,9 +537,21 @@ public: /* To be called when a resolver thread is done. If there are no running resolver threads we can check the recipients to see if we should - toggle / untoggle the secure state. */ + toggle / untoggle the secure state. + */ void decrement_locate_count (); + /* Check if the keys can be resolved automatically and trigger + * setting the crypto flags accordingly. + */ + void autoresolve_check_s (); + + /* Set if a mail should be secured (encrypted and signed) + * + * Only save to call from a place that may access mapi. + */ + void set_do_autosecure_mapi (bool value); + private: void update_categories (); void update_sigstate (); @@ -564,7 +574,7 @@ private: std::string m_sender; char *m_cached_html_body; /* Cached html body. */ char *m_cached_plain_body; /* Cached plain body. */ - char **m_cached_recipients; + std::vector m_cached_recipients; msgtype_t m_type; /* Our messagetype as set in mapi */ std::shared_ptr m_parser; std::shared_ptr m_crypter; @@ -587,6 +597,7 @@ private: bool m_disable_att_remove_warning; /* Should not warn about attachment removal. */ bool m_block_html; /* Force blocking of html content. e.g for unsigned S/MIME mails. */ bool m_manual_crypto_opts; /* Crypto options (sign/encrypt) have been set manually. */ + bool m_first_autosecure_check; /* This is the first autoresolve check */ int m_locate_count; /* The number of key locates pending for this mail. */ }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index b499966..51006f6 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -248,7 +248,7 @@ EVENT_SINK_INVOKE(MailItemEvents) Testing shows that Outlook always sends these three in a row */) { - if ((m_mail->needs_crypto() & 1)) + if (opt.autosecure || (m_mail->needs_crypto() & 1)) { /* XXX Racy race. This is a fix for crashes that happend if a resolved recipient is copied an pasted. diff --git a/src/main.c b/src/main.c index 02c53df..2d3590e 100644 --- a/src/main.c +++ b/src/main.c @@ -331,6 +331,9 @@ read_options (void) load_extension_value ("smimeHtmlWarnShown", &val); opt.smime_html_warn_shown = val == NULL || *val != '1'? 0 : 1; xfree (val); val = NULL; + load_extension_value ("autosecure", &val); + opt.autosecure = val == NULL ? 1 : *val != '1' ? 0 : 1; + xfree (val); val = NULL; /* Note, that on purpose these flags are only Registry changeable. The format of the entry is a string of of "0" and "1" digits; see the switch below for a description. */ diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 450bc02..87ceab6 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -170,40 +170,71 @@ getIcon (int id, VARIANT* result) HRESULT mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) { - HRESULT hr; - HRESULT rc = E_FAIL; - LPDISPATCH context = NULL, - mailitem = NULL; LPMESSAGE message = NULL; int oldflags, newflags; log_debug ("%s:%s: enter", SRCNAME, __func__); - hr = getContext (ctrl, &context); - if (FAILED(hr)) - return hr; + LPDISPATCH context = NULL; + if (FAILED(getContext (ctrl, &context))) + { + TRACEPOINT; + return E_FAIL; + } - mailitem = get_oom_object (context, is_explorer ? "ActiveInlineResponse" : - "CurrentItem"); + LPDISPATCH mailitem = get_oom_object (context, + is_explorer ? "ActiveInlineResponse" : + "CurrentItem"); + gpgol_release (context); if (!mailitem) { log_error ("%s:%s: Failed to get mailitem.", SRCNAME, __func__); - goto done; + return E_FAIL; + } + + /* Get the uid of this item. */ + char *uid = get_unique_id (mailitem, 0, nullptr); + if (!uid) + { + LPMESSAGE msg = get_oom_base_message (mailitem); + uid = mapi_get_uid (msg); + gpgol_release (msg); + if (!uid) + { + log_debug ("%s:%s: Failed to get uid for %p", + SRCNAME, __func__, mailitem); + } + } + Mail *mail = nullptr; + if (uid) + { + mail = Mail::get_mail_for_uuid (uid); + xfree (uid); + } + + if (mail) + { + mail->set_crypto_selected_manually (true); + } + else + { + log_debug ("%s:%s: Failed to get mail object.", + SRCNAME, __func__); } message = get_oom_base_message (mailitem); + gpgol_release (mailitem); if (!message) { log_error ("%s:%s: Failed to get message.", SRCNAME, __func__); - goto done; + return S_OK; } oldflags = get_gpgol_draft_info_flags (message); - if (flags == 3 && oldflags != 3) { // If only one sub button is active activate @@ -220,8 +251,7 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) log_error ("%s:%s: Failed to set draft flags.", SRCNAME, __func__); } - - rc = S_OK; + gpgol_release (message); /* We need to invalidate the UI to update the toggle states of the subbuttons and the top button. Yeah, @@ -233,12 +263,7 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) Mail::locate_all_crypto_recipients (); } -done: - gpgol_release (context); - gpgol_release (mailitem); - gpgol_release (message); - - return rc; + return S_OK; } /* Get the state of encrypt / sign toggle buttons. diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 36c0631..082dfa8 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -195,6 +195,30 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) mail->remove_all_attachments (); break; } + case (DO_AUTO_SECURE): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: DO_AUTO_SECURE for mail which is gone.", + SRCNAME, __func__); + break; + } + mail->set_do_autosecure_mapi (true); + break; + } + case (DONT_AUTO_SECURE): + { + auto mail = (Mail*) ctx->data; + if (!Mail::is_valid_ptr (mail)) + { + log_debug ("%s:%s: DO_AUTO_SECURE for mail which is gone.", + SRCNAME, __func__); + break; + } + mail->set_do_autosecure_mapi (false); + break; + } default: log_debug ("%s:%s: Unknown msg %x", SRCNAME, __func__, ctx->wmsg_type); diff --git a/src/windowmessages.h b/src/windowmessages.h index dcc372c..6a96a13 100644 --- a/src/windowmessages.h +++ b/src/windowmessages.h @@ -53,6 +53,8 @@ typedef enum _gpgol_wmsg_type INVALIDATE_LAST_MAIL, REVERT_MAIL, CLEAR_REPLY_FORWARD, + DO_AUTO_SECURE, + DONT_AUTO_SECURE, } gpgol_wmsg_type; typedef struct ----------------------------------------------------------------------- Summary of changes: src/common_indep.h | 1 + src/cryptcontroller.cpp | 2 +- src/keycache.cpp | 88 +++++++++++++++++++++++++++++++++++++++--------- src/keycache.h | 11 ++++-- src/mail.cpp | 88 +++++++++++++++++++++++++++++++++++++++++------- src/mail.h | 23 +++++++++---- src/mailitem-events.cpp | 2 +- src/main.c | 3 ++ src/ribbon-callbacks.cpp | 65 ++++++++++++++++++++++++----------- src/windowmessages.cpp | 24 +++++++++++++ src/windowmessages.h | 2 ++ 11 files changed, 250 insertions(+), 59 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 21 13:07:15 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Jun 2018 13:07:15 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-159-g7e9aa30 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 7e9aa307f76cdf2f624d43a35a8266e8b4e473f9 (commit) from 861f1da0731bf29dcb9221c4f22c76b40ec15a78 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7e9aa307f76cdf2f624d43a35a8266e8b4e473f9 Author: Werner Koch Date: Thu Jun 21 12:56:40 2018 +0200 build: Remove duplicates from AC_CHECK_FUNCS * configure.ac (AC_CHECK_FUNCS): Fold most calls into one. -- A few functions were tested two times which slightly increases the size of the configure script. Also put the functions in sorted order into the macro. Signed-off-by: Werner Koch diff --git a/common/name-value.h b/common/name-value.h index db9270a..5c24b8d 100644 --- a/common/name-value.h +++ b/common/name-value.h @@ -102,7 +102,7 @@ gpg_error_t nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp); /* Parsing and serialization. */ -/* Parse STREAM and return a newly allocated private key container +/* Parse STREAM and return a newly allocated name-value container structure in RESULT. If ERRLINEP is given, the line number the parser was last considering is stored there. */ gpg_error_t nvc_parse (nvc_t *result, int *errlinep, estream_t stream); diff --git a/configure.ac b/configure.ac index 60ec941..78a03c4 100644 --- a/configure.ac +++ b/configure.ac @@ -1392,18 +1392,17 @@ AC_CHECK_DECLS(getpagesize) AC_FUNC_FSEEKO AC_FUNC_VPRINTF AC_FUNC_FORK -AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap canonicalize_file_name]) -AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r strtoull]) -AC_CHECK_FUNCS([setenv unsetenv fcntl ftruncate inet_ntop]) -AC_CHECK_FUNCS([canonicalize_file_name]) -AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime]) -AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale]) -AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe getaddrinfo]) -AC_CHECK_FUNCS([ttyname rand ftello fsync stat lstat]) -AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \ - memrchr isascii timegm getrusage setrlimit stat setlocale \ - flockfile funlockfile getpwnam getpwuid \ - getenv inet_pton strpbrk]) +AC_CHECK_FUNCS([atexit canonicalize_file_name clock_gettime ctermid \ + fcntl flockfile fsync ftello ftruncate funlockfile \ + getaddrinfo getenv getpagesize getpwnam getpwuid \ + getrlimit getrusage gettimeofday gmtime_r \ + inet_ntop inet_pton isascii lstat \ + memicmp memmove memrchr mmap nl_langinfo pipe \ + raise rand setenv setlocale setrlimit sigaction \ + sigprocmask stat stpcpy strcasecmp strerror strftime \ + stricmp strlwr strncasecmp strpbrk strsep \ + strtol strtoul strtoull tcgetattr timegm times \ + ttyname unsetenv wait4 waitpid ]) # On some systems (e.g. Solaris) nanosleep requires linking to librl. # Given that we use nanosleep only as an optimization over a select ----------------------------------------------------------------------- Summary of changes: common/name-value.h | 2 +- configure.ac | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 21 13:13:54 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Jun 2018 13:13:54 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-11-g4213ac0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 4213ac0986d7058307a733d4a853a9b790a9c971 (commit) via 3774434014b9fbb4d7d1b705941b2827d7b2fb65 (commit) via 60b331568188a774cb519e2df752baf4c1e9a5d3 (commit) from c8f46557da704d863052709d5b627970450a0d1d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4213ac0986d7058307a733d4a853a9b790a9c971 Author: Andre Heinecke Date: Thu Jun 21 13:11:11 2018 +0200 Set UUID when auto toggling secure * src/mail.cpp (Mail::set_do_autosecure_mapi): set uuid. -- Setting the UUID is neccessary to find the Mail object from the toggle button to mark that the state was manually set. GnuPG-Bug-Id: T3999 diff --git a/src/mail.cpp b/src/mail.cpp index fb835d8..f2be77c 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -3275,6 +3275,10 @@ Mail::set_do_autosecure_mapi(bool value) { TRACEPOINT; } + /* We need to set a uuid so that autosecure can + be disabled manually */ + set_uuid (); + int old_flags = get_gpgol_draft_info_flags (msg); if (old_flags && m_first_autosecure_check) { commit 3774434014b9fbb4d7d1b705941b2827d7b2fb65 Author: Andre Heinecke Date: Thu Jun 21 13:10:40 2018 +0200 Fix flicker when locate threads are running * src/mail.cpp (Mail::autoresolve_s): Check locate thread count. -- GnuPG-Bug-Id: T3999 diff --git a/src/mail.cpp b/src/mail.cpp index 274f121..fb835d8 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -3246,7 +3246,8 @@ Mail::decrement_locate_count() void Mail::autoresolve_check_s() { - if (!opt.autoresolve || m_manual_crypto_opts) + if (!opt.autoresolve || m_manual_crypto_opts || + m_locate_count) { return; } commit 60b331568188a774cb519e2df752baf4c1e9a5d3 Author: Andre Heinecke Date: Thu Jun 21 11:22:47 2018 +0200 Simplify isMailResolvable and accept keygen * src/keycache.cpp (isMailResolvable): Return bool. Accept potential keygen. * src/keycache.h: Update accordingly. * src/mail.cpp (Mail::autoresolve_check_s): Update for new API. -- This inly check for a self key for SMIME. For OpenPGP we can generate a key. GnuPG-Bug-Id: T3999 diff --git a/src/keycache.cpp b/src/keycache.cpp index 742046f..75d971b 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -621,7 +621,7 @@ KeyCache::setPgpKeySecret(const std::string &mbox, const GpgME::Key &key) d->setPgpKeySecret(mbox, key); } -int +bool KeyCache::isMailResolvable(Mail *mail) { /* Get the data from the mail. */ @@ -632,44 +632,28 @@ KeyCache::isMailResolvable(Mail *mail) { log_debug ("%s:%s: Mail has no sender or no recipients.", SRCNAME, __func__); - return 0; + return false; } - /* Include sender for encryption */ - recps.push_back (sender); - GpgME::Key sigKey = getSigningKey (sender.c_str(), GpgME::OpenPGP); std::vector encKeys = getEncryptionKeys (recps, GpgME::OpenPGP); - int pgpState = 0; if (!encKeys.empty()) { - pgpState = 1; - } - if (!sigKey.isNull()) - { - pgpState += 2; + return true; } - if (pgpState == 3 /* all good */ || !opt.enable_smime) + if (!opt.enable_smime) { - return pgpState; + return false; } - /* Check S/MIME instead */ - sigKey = getSigningKey (sender.c_str(), GpgME::CMS); + /* Check S/MIME instead here we need to include the sender + as we can't just generate a key. */ + recps.push_back (sender); + GpgME::Key sigKey= getSigningKey (sender.c_str(), GpgME::CMS); encKeys = getEncryptionKeys (recps, GpgME::CMS); - int cmsState = 0; - if (!encKeys.empty()) - { - cmsState = 1; - } - if (!sigKey.isNull()) - { - cmsState += 2; - } - - return (cmsState > pgpState) ? cmsState : pgpState; + return !encKeys.empty() && !sigKey.isNull(); } diff --git a/src/keycache.h b/src/keycache.h index 7c4b4be..9cdf499 100644 --- a/src/keycache.h +++ b/src/keycache.h @@ -75,9 +75,10 @@ public: /* Check that a mail is resolvable through the keycache. * - * Returns the usual int with sign = 2 and encrypt = 1 + * For OpenPGP only the recipients are checked as we can + * generate a new key for the sender. **/ - int isMailResolvable (Mail *mail); + bool isMailResolvable (Mail *mail); // Internal for thread void setSmimeKey(const std::string &mbox, const GpgME::Key &key); diff --git a/src/mail.cpp b/src/mail.cpp index f02f127..274f121 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -3250,7 +3250,7 @@ Mail::autoresolve_check_s() { return; } - int ret = KeyCache::instance()->isMailResolvable (this); + bool ret = KeyCache::instance()->isMailResolvable (this); log_debug ("%s:%s: status %i", SRCNAME, __func__, ret); @@ -3259,14 +3259,8 @@ Mail::autoresolve_check_s() * to be triggered by the locator threads finishing we * need to actually set the draft info flags in * the ui thread. */ - if (ret == 3) - { - do_in_ui_thread (DO_AUTO_SECURE, this); - } - else - { - do_in_ui_thread (DONT_AUTO_SECURE, this); - } + do_in_ui_thread (ret ? DO_AUTO_SECURE : DONT_AUTO_SECURE, + this); return; } ----------------------------------------------------------------------- Summary of changes: src/keycache.cpp | 36 ++++++++++-------------------------- src/keycache.h | 5 +++-- src/mail.cpp | 19 +++++++++---------- 3 files changed, 22 insertions(+), 38 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 21 15:20:23 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Jun 2018 15:20:23 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-160-g386b9c4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 386b9c4f25b28fd769d7563f2d86ac3a19cc3011 (commit) from 7e9aa307f76cdf2f624d43a35a8266e8b4e473f9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 386b9c4f25b28fd769d7563f2d86ac3a19cc3011 Author: Werner Koch Date: Thu Jun 21 15:06:30 2018 +0200 gpg: Let --show-keys print revocation certificates. * g10/import.c (list_standalone_revocation): New. (import_revoke_cert): Call new function. -- GnuPG-bug-id: 4018 Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index e7567f7..1bfc04d 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -59,6 +59,7 @@ described here. - uat :: User attribute (same as user id except for field 10). - sig :: Signature - rev :: Revocation signature + - rvs :: Recocation signature (standalone) [since 2.2.9] - fpr :: Fingerprint (fingerprint is in field 10) - pkd :: Public key data [*] - grp :: Keygrip @@ -207,12 +208,13 @@ described here. For "uid" records this field lists the preferences in the same way gpg's --edit-key menu does. - For "sig" records, this is the fingerprint of the key that issued - the signature. Note that this may only be filled if the signature - verified correctly. Note also that for various technical reasons, - this fingerprint is only available if --no-sig-cache is used. - Since 2.2.7 this field will also be set if the key is missing but - the signature carries an issuer fingerprint as meta data. + For "sig", "rev" and "rvs" records, this is the fingerprint of the + key that issued the signature. Note that this may only be filled + if the signature verified correctly. Note also that for various + technical reasons, this fingerprint is only available if + --no-sig-cache is used. Since 2.2.7 this field will also be set + if the key is missing but the signature carries an issuer + fingerprint as meta data. *** Field 14 - Flag field diff --git a/g10/import.c b/g10/import.c index 9b693e9..022f077 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2632,6 +2632,95 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, } + +/* List the recocation signature as a "rvs" record. SIGRC shows the + * character from the signature verification or 0 if no public key was + * found. */ +static void +list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) +{ + char *siguid = NULL; + size_t siguidlen = 0; + char *issuer_fpr = NULL; + + if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode) + { + int nouid; + siguid = get_user_id (ctrl, sig->keyid, &siguidlen, &nouid); + if (nouid) + sigrc = '?'; + } + + if (opt.with_colons) + { + es_fputs ("rvs:", es_stdout); + if (sigrc) + es_putc (sigrc, es_stdout); + es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:::", + sig->pubkey_algo, + (ulong) sig->keyid[0], (ulong) sig->keyid[1], + colon_datestr_from_sig (sig), + colon_expirestr_from_sig (sig)); + + if (siguid) + es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL); + + es_fprintf (es_stdout, ":%02x%c::", sig->sig_class, + sig->flags.exportable ? 'x' : 'l'); + + if ((issuer_fpr = issuer_fpr_string (sig))) + es_fputs (issuer_fpr, es_stdout); + + es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo); + + if (opt.show_subpackets) + print_subpackets_colon (sig); + } + else /* Human readable. */ + { + es_fputs ("rvs", es_stdout); + es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s", + sigrc, (sig->sig_class - 0x10 > 0 && + sig->sig_class - 0x10 < + 4) ? '0' + sig->sig_class - 0x10 : ' ', + sig->flags.exportable ? ' ' : 'L', + sig->flags.revocable ? ' ' : 'R', + sig->flags.policy_url ? 'P' : ' ', + sig->flags.notation ? 'N' : ' ', + sig->flags.expired ? 'X' : ' ', + (sig->trust_depth > 9) ? 'T' : (sig->trust_depth > + 0) ? '0' + + sig->trust_depth : ' ', keystr (sig->keyid), + datestr_from_sig (sig)); + if (siguid) + { + es_fprintf (es_stdout, " "); + print_utf8_buffer (es_stdout, siguid, siguidlen); + } + es_putc ('\n', es_stdout); + + if (sig->flags.policy_url + && (opt.list_options & LIST_SHOW_POLICY_URLS)) + show_policy_url (sig, 3, 0); + + if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS)) + show_notation (sig, 3, 0, + ((opt.list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + + + ((opt.list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0)); + + if (sig->flags.pref_ks + && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) + show_keyserver_url (sig, 3, 0); + } + + es_fflush (es_stdout); + + xfree (siguid); + xfree (issuer_fpr); +} + + /**************** * Import a revocation certificate; this is a single signature packet. */ @@ -2645,6 +2734,11 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, KEYDB_HANDLE hd = NULL; u32 keyid[2]; int rc = 0; + int sigrc = 0; + int silent; + + /* No error output for --show-keys. */ + silent = (options & (IMPORT_SHOW | IMPORT_DRY_RUN)); log_assert (!node->next ); log_assert (node->pkt->pkttype == PKT_SIGNATURE ); @@ -2657,15 +2751,16 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, rc = get_pubkey (ctrl, pk, keyid ); if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) { - log_error(_("key %s: no public key -" - " can't apply revocation certificate\n"), keystr(keyid)); + if (!silent) + log_error (_("key %s: no public key -" + " can't apply revocation certificate\n"), keystr(keyid)); rc = 0; goto leave; } else if (rc ) { - log_error(_("key %s: public key not found: %s\n"), - keystr(keyid), gpg_strerror (rc)); + log_error (_("key %s: public key not found: %s\n"), + keystr(keyid), gpg_strerror (rc)); goto leave; } @@ -2702,12 +2797,21 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, /* it is okay, that node is not in keyblock because * check_key_signature works fine for sig_class 0x20 (KEY_REV) in - * this special case. */ + * this special case. SIGRC is only used for IMPORT_SHOW. */ rc = check_key_signature (ctrl, keyblock, node, NULL); + switch (gpg_err_code (rc)) + { + case 0: sigrc = '!'; break; + case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break; + case GPG_ERR_NO_PUBKEY: sigrc = '?'; break; + case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break; + default: sigrc = '%'; break; + } if (rc ) { - log_error( _("key %s: invalid revocation certificate" - ": %s - rejected\n"), keystr(keyid), gpg_strerror (rc)); + if (!silent) + log_error (_("key %s: invalid revocation certificate" + ": %s - rejected\n"), keystr(keyid), gpg_strerror (rc)); goto leave; } @@ -2757,6 +2861,9 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, stats->n_revoc++; leave: + if ((options & IMPORT_SHOW)) + list_standalone_revocation (ctrl, node->pkt->pkt.signature, sigrc); + keydb_release (hd); release_kbnode( keyblock ); free_public_key( pk ); ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 14 ++++--- g10/import.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 122 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 21 16:33:10 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Jun 2018 16:33:10 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-14-gb4b5960 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via b4b5960c7397ce65d0c105f3538270157fd40e5e (commit) via b0d80b45053d6c705377f26a5eff95e34f4070ff (commit) via f8a13fcbfcbf2b04f9763621d0917b4f402b5670 (commit) from 4213ac0986d7058307a733d4a853a9b790a9c971 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b4b5960c7397ce65d0c105f3538270157fd40e5e Author: Andre Heinecke Date: Thu Jun 21 16:31:57 2018 +0200 Use convention for MAPI/OOM active functs -- This should make it easier to see if a function accesses MAPI or OOM somewhere internally. For now this is only done for our main Mail class. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index df5366c..dd36831 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -69,8 +69,8 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign, m_proto (proto) { log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.", - SRCNAME, __func__, mail, encrypt, sign, mail->do_pgp_inline ()); - m_recipient_addrs = vector_to_cArray (mail->get_cached_recipients ()); + SRCNAME, __func__, mail, encrypt, sign, mail->getDoPGPInline ()); + m_recipient_addrs = vector_to_cArray (mail->getRecipients ()); } CryptController::~CryptController() @@ -94,7 +94,7 @@ CryptController::collect_data () /* Take the Body from the mail if possible. This is a fix for GnuPG-Bug-ID: T3614 because the body is not always properly updated in MAPI when sending. */ - char *body = m_mail->take_cached_plain_body (); + char *body = m_mail->takeCachedPlainBody (); if (body && !*body) { xfree (body); @@ -112,7 +112,7 @@ CryptController::collect_data () int n_att_usable = count_usable_attachments (att_table); if (!n_att_usable && !body) { - gpgol_message_box (m_mail->get_window(), + gpgol_message_box (m_mail->getWindow (), utf8_gettext ("Can't encrypt / sign an empty message."), utf8_gettext ("GpgOL"), MB_OK); gpgol_release (message); @@ -120,7 +120,7 @@ CryptController::collect_data () return -1; } - bool do_inline = m_mail->do_pgp_inline (); + bool do_inline = m_mail->getDoPGPInline (); if (n_att_usable && do_inline) { @@ -128,7 +128,7 @@ CryptController::collect_data () " Using PGP MIME", SRCNAME, __func__); do_inline = false; - m_mail->set_do_pgp_inline (false); + m_mail->setDoPGPInline (false); } else if (do_inline) { @@ -295,7 +295,7 @@ CryptController::parse_output (GpgME::Data &resolverOutput) { log_error ("%s:%s: Encrypt requested but no recipient fingerprints", SRCNAME, __func__); - gpgol_message_box (m_mail->get_window(), _("No recipients for encryption selected."), + gpgol_message_box (m_mail->getWindow (), _("No recipients for encryption selected."), _("GpgOL"), MB_OK); return -2; } @@ -312,7 +312,7 @@ CryptController::resolve_keys_cached() if (m_encrypt) { - const auto cached_sender = m_mail->get_cached_sender (); + const auto cached_sender = m_mail->getSender (); auto recps = cArray_to_vector ((const char**) m_recipient_addrs); recps.push_back (cached_sender); @@ -338,13 +338,13 @@ CryptController::resolve_keys_cached() { if (!fallbackToSMIME) { - m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (), + m_signer_key = cache->getSigningKey (m_mail->getSender ().c_str (), GpgME::OpenPGP); m_proto = GpgME::OpenPGP; } if (m_signer_key.isNull() && opt.enable_smime) { - m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (), + m_signer_key = cache->getSigningKey (m_mail->getSender ().c_str (), GpgME::CMS); m_proto = GpgME::CMS; } @@ -392,7 +392,7 @@ CryptController::resolve_keys () args.push_back (std::string ("--debug")); // Yes passing it as int is ok. - auto wnd = m_mail->get_window (); + auto wnd = m_mail->getWindow (); if (wnd) { // Pass the handle of the active window for raise / overlay. @@ -421,7 +421,7 @@ CryptController::resolve_keys () { args.push_back (std::string ("--sign")); } - const auto cached_sender = m_mail->get_cached_sender (); + const auto cached_sender = m_mail->getSender (); if (cached_sender.empty()) { log_error ("%s:%s: resolve keys without sender.", @@ -520,7 +520,7 @@ CryptController::do_crypto (GpgME::Error &err) SRCNAME, __func__); /* Start a WKS check if necessary. */ - WKSHelper::instance()->start_check (m_mail->get_cached_sender ()); + WKSHelper::instance()->start_check (m_mail->getSender ()); int ret = resolve_keys (); if (ret == -1) @@ -535,14 +535,14 @@ CryptController::do_crypto (GpgME::Error &err) // Cancel return -2; } - bool do_inline = m_mail->do_pgp_inline (); + bool do_inline = m_mail->getDoPGPInline (); if (m_proto == GpgME::CMS && do_inline) { log_debug ("%s:%s: Inline for S/MIME not supported. Switching to mime.", SRCNAME, __func__); do_inline = false; - m_mail->set_do_pgp_inline (false); + m_mail->setDoPGPInline (false); m_bodyInput = GpgME::Data(GpgME::Data::null); } @@ -552,7 +552,7 @@ CryptController::do_crypto (GpgME::Error &err) { log_error ("%s:%s: Failure to create context.", SRCNAME, __func__); - gpgol_message_box (m_mail->get_window (), + gpgol_message_box (m_mail->getWindow (), "Failure to create context.", utf8_gettext ("GpgOL"), MB_OK); return -1; @@ -892,7 +892,7 @@ CryptController::update_mail_mapi () return -1; } - if (m_mail->do_pgp_inline ()) + if (m_mail->getDoPGPInline ()) { // Nothing to do for inline. log_debug ("%s:%s: Inline mail. Setting encoding.", @@ -926,7 +926,7 @@ CryptController::update_mail_mapi () // This means that the conversion / build of the mime structure also // happens differently. int exchange_major_version = get_ex_major_version_for_addr ( - m_mail->get_cached_sender ().c_str ()); + m_mail->getSender ().c_str ()); std::string overrideMimeTag; if (m_proto == GpgME::CMS && m_encrypt && exchange_major_version >= 15) @@ -1002,7 +1002,7 @@ std::string CryptController::get_inline_data () { std::string ret; - if (!m_mail->do_pgp_inline ()) + if (!m_mail->getDoPGPInline ()) { return ret; } @@ -1054,7 +1054,7 @@ CryptController::parse_micalg (const GpgME::SigningResult &result) void CryptController::start_crypto_overlay () { - auto wid = m_mail->get_window (); + auto wid = m_mail->getWindow (); std::string text; diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp index 38ed039..95ec7c7 100644 --- a/src/gpgoladdin.cpp +++ b/src/gpgoladdin.cpp @@ -365,7 +365,7 @@ GpgolAddin::OnDisconnection (ext_DisconnectMode RemoveMode, does not allow us any OOM calls then and only returns "Unexpected error" in that case. Weird. */ - if (Mail::close_all_mails ()) + if (Mail::closeAllMails_o ()) { MessageBox (NULL, "Failed to remove plaintext from at least one message.\n\n" diff --git a/src/keycache.cpp b/src/keycache.cpp index 75d971b..0e53c2d 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -59,23 +59,23 @@ namespace m_mail (mail) { s_thread_cnt++; - Mail::delete_lock (); - if (Mail::is_valid_ptr (m_mail)) + Mail::lockDelete (); + if (Mail::isValidPtr (m_mail)) { - m_mail->increment_locate_count (); + m_mail->incrementLocateCount (); } - Mail::delete_unlock (); + Mail::unlockDelete (); }; ~LocateArgs() { s_thread_cnt--; - Mail::delete_lock (); - if (Mail::is_valid_ptr (m_mail)) + Mail::lockDelete (); + if (Mail::isValidPtr (m_mail)) { - m_mail->decrement_locate_count (); + m_mail->decrementLocateCount (); } - Mail::delete_unlock (); + Mail::unlockDelete (); } std::string m_mbox; @@ -625,8 +625,8 @@ bool KeyCache::isMailResolvable(Mail *mail) { /* Get the data from the mail. */ - const auto sender = mail->get_cached_sender(); - auto recps = mail->get_cached_recipients(); + const auto sender = mail->getSender (); + auto recps = mail->getRecipients (); if (sender.empty() || recps.empty()) { diff --git a/src/mail.cpp b/src/mail.cpp index e817b1e..783ccd3 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -101,7 +101,7 @@ Mail::Mail (LPDISPATCH mailitem) : m_first_autosecure_check(true), m_locate_count(0) { - if (get_mail_for_item (mailitem)) + if (getMailForItem (mailitem)) { log_error ("Mail object for item: %p already exists. Bug.", mailitem); @@ -128,14 +128,14 @@ GPGRT_LOCK_DEFINE(dtor_lock); // static void -Mail::delete_lock () +Mail::lockDelete () { gpgrt_lock_lock (&dtor_lock); } // static void -Mail::delete_unlock () +Mail::unlockDelete () { gpgrt_lock_unlock (&dtor_lock); } @@ -203,7 +203,7 @@ Mail::~Mail() } Mail * -Mail::get_mail_for_item (LPDISPATCH mailitem) +Mail::getMailForItem (LPDISPATCH mailitem) { if (!mailitem) { @@ -221,7 +221,7 @@ Mail::get_mail_for_item (LPDISPATCH mailitem) } Mail * -Mail::get_mail_for_uuid (const char *uuid) +Mail::getMailForUUID (const char *uuid) { if (!uuid) { @@ -238,7 +238,7 @@ Mail::get_mail_for_uuid (const char *uuid) } bool -Mail::is_valid_ptr (const Mail *mail) +Mail::isValidPtr (const Mail *mail) { gpgrt_lock_lock (&mail_map_lock); auto it = s_mail_map.begin(); @@ -256,7 +256,7 @@ Mail::is_valid_ptr (const Mail *mail) } int -Mail::pre_process_message () +Mail::preProcessMessage_m () { LPMESSAGE message = get_oom_base_message (m_mailitem); if (!message) @@ -334,7 +334,7 @@ get_attachment (LPDISPATCH mailitem, int pos) /** Helper to check that all attachments are hidden, to be called before crypto. */ int -Mail::check_attachments () const +Mail::checkAttachments_o () const { LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments"); if (!attachments) @@ -352,17 +352,17 @@ Mail::check_attachments () const std::string message; - if (is_encrypted () && is_signed ()) + if (isEncrypted () && isSigned ()) { message += _("Not all attachments were encrypted or signed.\n" "The unsigned / unencrypted attachments are:\n\n"); } - else if (is_signed ()) + else if (isSigned ()) { message += _("Not all attachments were signed.\n" "The unsigned attachments are:\n\n"); } - else if (is_encrypted ()) + else if (isEncrypted ()) { message += _("Not all attachments were encrypted.\n" "The unencrypted attachments are:\n\n"); @@ -689,7 +689,7 @@ do_parsing (LPVOID arg) /* We lock with mail dtors so we can be sure the mail->parser call is valid. */ Mail *mail = (Mail *)arg; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: canceling parsing for: %p already deleted", SRCNAME, __func__, arg); @@ -698,7 +698,7 @@ do_parsing (LPVOID arg) } /* This takes a shared ptr of parser. So the parser is still valid when the mail is deleted. */ - auto parser = mail->parser(); + auto parser = mail->parser (); gpgrt_lock_unlock (&dtor_lock); gpgrt_lock_lock (&parser_lock); @@ -712,7 +712,7 @@ do_parsing (LPVOID arg) log_debug ("%s:%s: preparing the parser for: %p", SRCNAME, __func__, arg); - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: cancel for: %p already deleted", SRCNAME, __func__, arg); @@ -814,25 +814,25 @@ do_crypt (LPVOID arg) /* We lock with mail dtors so we can be sure the mail->parser call is valid. */ Mail *mail = (Mail *)arg; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: canceling crypt for: %p already deleted", SRCNAME, __func__, arg); gpgrt_lock_unlock (&dtor_lock); return 0; } - if (mail->crypt_state() != Mail::NeedsActualCrypt) + if (mail->cryptState () != Mail::NeedsActualCrypt) { log_debug ("%s:%s: invalid state %i", - SRCNAME, __func__, mail->crypt_state ()); - mail->set_window_enabled (true); + SRCNAME, __func__, mail->cryptState ()); + mail->setWindowEnabled_o (true); gpgrt_lock_unlock (&dtor_lock); return -1; } /* This takes a shared ptr of crypter. So the crypter is still valid when the mail is deleted. */ - auto crypter = mail->crypter(); + auto crypter = mail->cryper (); gpgrt_lock_unlock (&dtor_lock); if (!crypter) @@ -840,7 +840,7 @@ do_crypt (LPVOID arg) log_error ("%s:%s: no crypter found for mail: %p", SRCNAME, __func__, arg); gpgrt_lock_unlock (&parser_lock); - mail->set_window_enabled (true); + mail->setWindowEnabled_o (true); return -1; } @@ -848,7 +848,7 @@ do_crypt (LPVOID arg) int rc = crypter->do_crypto(err); gpgrt_lock_lock (&dtor_lock); - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: aborting crypt for: %p already deleted", SRCNAME, __func__, arg); @@ -856,23 +856,23 @@ do_crypt (LPVOID arg) return 0; } - mail->set_window_enabled (true); + mail->setWindowEnabled_o (true); if (rc == -1 || err) { - mail->reset_crypter (); + mail->resetCrypter (); crypter = nullptr; if (err) { char *buf = nullptr; gpgrt_asprintf (&buf, _("Crypto operation failed:\n%s"), err.asString()); - gpgol_message_box (mail->get_window(), buf, _("GpgOL"), MB_OK); + gpgol_message_box (mail->getWindow (), buf, _("GpgOL"), MB_OK); xfree (buf); } else { - gpgol_bug (mail->get_window (), + gpgol_bug (mail->getWindow (), ERR_CRYPT_RESOLVER_FAILED); } } @@ -881,16 +881,16 @@ do_crypt (LPVOID arg) { log_debug ("%s:%s: crypto failed for: %p with: %i err: %i", SRCNAME, __func__, arg, rc, err.code()); - mail->set_crypt_state (Mail::NoCryptMail); - mail->reset_crypter (); + mail->setCryptState (Mail::NoCryptMail); + mail->resetCrypter (); crypter = nullptr; gpgrt_lock_unlock (&dtor_lock); return rc; } - if (!mail->async_crypt_disabled ()) + if (!mail->isAsyncCryptDisabled ()) { - mail->set_crypt_state (Mail::NeedsUpdateInOOM); + mail->setCryptState (Mail::NeedsUpdateInOOM); gpgrt_lock_unlock (&dtor_lock); // This deletes the Mail in Outlook 2010 do_in_ui_thread (CRYPTO_DONE, arg); @@ -899,12 +899,12 @@ do_crypt (LPVOID arg) } else { - mail->set_crypt_state (Mail::NeedsUpdateInMAPI); - mail->update_crypt_mapi (); - if (mail->crypt_state () == Mail::WantsSendMIME) + mail->setCryptState (Mail::NeedsUpdateInMAPI); + mail->updateCryptMAPI_m (); + if (mail->cryptState () == Mail::WantsSendMIME) { // For sync crypto we need to switch this. - mail->set_crypt_state (Mail::NeedsUpdateInOOM); + mail->setCryptState (Mail::NeedsUpdateInOOM); } else { @@ -912,7 +912,7 @@ do_crypt (LPVOID arg) log_debug ("%s:%s: Resetting crypter because of state mismatch. %p", SRCNAME, __func__, arg); crypter = nullptr; - mail->reset_crypter (); + mail->resetCrypter (); } gpgrt_lock_unlock (&dtor_lock); } @@ -929,7 +929,7 @@ do_crypt (LPVOID arg) } bool -Mail::is_crypto_mail() const +Mail::isCryptoMail () const { if (m_type == MSGTYPE_UNKNOWN || m_type == MSGTYPE_GPGOL || m_type == MSGTYPE_SMIME) @@ -941,9 +941,9 @@ Mail::is_crypto_mail() const } int -Mail::decrypt_verify() +Mail::decryptVerify_o () { - if (!is_crypto_mail()) + if (!isCryptoMail ()) { log_debug ("%s:%s: Decrypt Verify for non crypto mail: %p.", SRCNAME, __func__, m_mailitem); @@ -955,7 +955,7 @@ Mail::decrypt_verify() SRCNAME, __func__, m_mailitem); return 1; } - set_uuid (); + setUUID_o (); m_processed = true; @@ -974,7 +974,7 @@ Mail::decrypt_verify() } else if (gpgrt_asprintf (&placeholder_buf, opt.prefer_html ? decrypt_template_html : decrypt_template, - is_smime() ? "S/MIME" : "OpenPGP", + isSMIME_m () ? "S/MIME" : "OpenPGP", _("message"), _("Please wait while the message is being decrypted / verified...")) == -1) { @@ -1020,9 +1020,9 @@ Mail::decrypt_verify() } m_parser = std::shared_ptr (new ParseController (cipherstream, m_type)); - m_parser->setSender(GpgME::UserID::addrSpecFromString(get_sender().c_str())); + m_parser->setSender(GpgME::UserID::addrSpecFromString(getSender_o ().c_str())); log_mime_parser ("%s:%s: Parser for \"%s\" is %p", - SRCNAME, __func__, get_subject ().c_str(), m_parser.get()); + SRCNAME, __func__, getSubject_o ().c_str(), m_parser.get()); gpgol_release (cipherstream); HANDLE parser_thread = CreateThread (NULL, 0, do_parsing, (LPVOID) this, 0, @@ -1049,7 +1049,7 @@ void find_and_replace(std::string& source, const std::string &find, } void -Mail::update_body() +Mail::updateBody_o () { if (!m_parser) { @@ -1166,7 +1166,7 @@ Mail::update_body() buf += "\n\n"; buf += _("This message is shown only once."); - gpgol_message_box (get_window(), buf.c_str(), caption.c_str(), + gpgol_message_box (getWindow (), buf.c_str(), caption.c_str(), MB_OK); opt.smime_html_warn_shown = true; write_options (); @@ -1236,7 +1236,7 @@ Mail::update_body() buf += _("Please ask the sender to sign the message or\n" "to send it with a plain text alternative."); - gpgol_message_box (get_window(), buf.c_str(), caption.c_str(), + gpgol_message_box (getWindow (), buf.c_str(), caption.c_str(), MB_OK); } @@ -1309,12 +1309,12 @@ Mail::parsing_done() m_crypto_flags |= 2; } - update_sigstate (); + updateSigstate_o (); m_needs_wipe = !m_is_send_again; TRACEPOINT; /* Set categories according to the result. */ - update_categories (); + updateCategories_o (); TRACEPOINT; m_block_html = m_parser->shouldBlockHtml (); @@ -1322,16 +1322,16 @@ Mail::parsing_done() if (m_block_html) { // Just to be careful. - set_block_status (); + setBlockStatus_m (); } TRACEPOINT; /* Update the body */ - update_body(); + updateBody_o (); TRACEPOINT; /* Check that there are no unsigned / unencrypted messages. */ - check_attachments (); + checkAttachments_o (); /* Update attachments */ if (add_attachments (m_mailitem, m_parser->get_attachments())) @@ -1357,7 +1357,7 @@ Mail::parsing_done() set_gpgol_draft_info_flags (msg, m_crypto_flags); gpgol_release (msg); } - remove_our_attachments (); + removeOurAttachments_o (); } log_debug ("%s:%s: Delayed invalidate to update sigstate.", @@ -1369,7 +1369,7 @@ Mail::parsing_done() } int -Mail::encrypt_sign_start () +Mail::encryptSignStart_o () { if (m_crypt_state != NeedsActualCrypt) { @@ -1429,12 +1429,12 @@ Mail::encrypt_sign_start () // Careful from here on we have to check every // error condition with window enabling again. - set_window_enabled (false); + setWindowEnabled_o (false); if (m_crypter->collect_data ()) { log_error ("%s:%s: Crypter for mail %p failed to collect data.", SRCNAME, __func__, this); - set_window_enabled (true); + setWindowEnabled_o (true); return -1; } @@ -1468,7 +1468,7 @@ Mail::needs_crypto () } int -Mail::wipe (bool force) +Mail::wipe_o (bool force) { if (!m_needs_wipe && !force) { @@ -1497,12 +1497,12 @@ Mail::wipe (bool force) } int -Mail::update_oom_data () +Mail::updateOOMData_o () { char *buf = nullptr; log_debug ("%s:%s", SRCNAME, __func__); - if (!is_crypto_mail()) + if (!isCryptoMail ()) { /* Update the body format. */ m_is_html_alternative = get_oom_int (m_mailitem, "BodyFormat") > 1; @@ -1518,14 +1518,14 @@ Mail::update_oom_data () xfree (m_cached_plain_body); m_cached_plain_body = get_oom_string (m_mailitem, "Body"); - char **recipients = get_recipients (); + char **recipients = getRecipients_o (); m_cached_recipients = cArray_to_vector ((const char **)recipients); xfree (recipients); } /* For some reason outlook may store the recipient address in the send using account field. If we have SMTP we prefer the SenderEmailAddress string. */ - if (is_crypto_mail ()) + if (isCryptoMail ()) { /* This is the case where we are reading a mail and not composing. When composing we need to use the SendUsingAccount because if @@ -1545,7 +1545,7 @@ Mail::update_oom_data () { buf = get_sender_SendUsingAccount (m_mailitem, &m_is_gsuite); } - if (!buf && !is_crypto_mail ()) + if (!buf && !isCryptoMail ()) { /* Try the sender Object */ buf = get_sender_Sender (m_mailitem); @@ -1568,21 +1568,21 @@ Mail::update_oom_data () } std::string -Mail::get_sender () +Mail::getSender_o () { if (m_sender.empty()) - update_oom_data(); + updateOOMData_o (); return m_sender; } std::string -Mail::get_cached_sender () const +Mail::getSender () const { return m_sender; } int -Mail::close_all_mails () +Mail::closeAllMails_o () { int err = 0; std::map::iterator it; @@ -1595,22 +1595,22 @@ Mail::close_all_mails () /* XXX For non racy code the is_valid_ptr check should not be necessary but we crashed sometimes closing a destroyed mail. */ - if (!is_valid_ptr (it->second)) + if (!isValidPtr (it->second)) { log_debug ("%s:%s: Already deleted mail for %p", SRCNAME, __func__, it->first); continue; } - if (!it->second->is_crypto_mail()) + if (!it->second->isCryptoMail ()) { continue; } - if (close_inspector (it->second) || close (it->second)) + if (closeInspector_o (it->second) || close (it->second)) { log_error ("Failed to close mail: %p ", it->first); /* Should not happen */ - if (is_valid_ptr (it->second) && it->second->revert()) + if (isValidPtr (it->second) && it->second->revert_o ()) { err++; } @@ -1619,21 +1619,21 @@ Mail::close_all_mails () return err; } int -Mail::revert_all_mails () +Mail::revertAllMails_o () { int err = 0; std::map::iterator it; gpgrt_lock_lock (&mail_map_lock); for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { - if (it->second->revert ()) + if (it->second->revert_o ()) { log_error ("Failed to revert mail: %p ", it->first); err++; continue; } - it->second->set_needs_save (true); + it->second->setNeedsSave (true); if (!invoke_oom_method (it->first, "Save", NULL)) { log_error ("Failed to save reverted mail: %p ", it->second); @@ -1646,14 +1646,14 @@ Mail::revert_all_mails () } int -Mail::wipe_all_mails () +Mail::wipeAllMails_o () { int err = 0; std::map::iterator it; gpgrt_lock_lock (&mail_map_lock); for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { - if (it->second->wipe ()) + if (it->second->wipe_o ()) { log_error ("Failed to wipe mail: %p ", it->first); err++; @@ -1664,7 +1664,7 @@ Mail::wipe_all_mails () } int -Mail::revert () +Mail::revert_o () { int err = 0; if (!m_processed) @@ -1679,7 +1679,7 @@ Mail::revert () { log_error ("%s:%s: Message revert failed falling back to wipe.", SRCNAME, __func__); - return wipe (); + return wipe_o (); } /* We need to reprocess the mail next time around. */ m_processed = false; @@ -1689,7 +1689,7 @@ Mail::revert () } bool -Mail::is_smime () +Mail::isSMIME_m () { msgtype_t msgtype; LPMESSAGE message; @@ -1748,25 +1748,25 @@ get_string (LPDISPATCH item, const char *str) } std::string -Mail::get_subject() const +Mail::getSubject_o () const { return get_string (m_mailitem, "Subject"); } std::string -Mail::get_body() const +Mail::getBody_o () const { return get_string (m_mailitem, "Body"); } std::string -Mail::get_html_body() const +Mail::getHTMLBody_o () const { return get_string (m_mailitem, "HTMLBody"); } char ** -Mail::get_recipients() const +Mail::getRecipients_o () const { LPDISPATCH recipients = get_oom_object (m_mailitem, "Recipients"); if (!recipients) @@ -1780,7 +1780,7 @@ Mail::get_recipients() const } int -Mail::close_inspector (Mail *mail) +Mail::closeInspector_o (Mail *mail) { LPDISPATCH inspector = get_oom_object (mail->item(), "GetInspector"); HRESULT hr; @@ -1834,7 +1834,7 @@ Mail::close (Mail *mail) log_oom_extra ("%s:%s: Invoking close for: %p", SRCNAME, __func__, mail->item()); - mail->set_close_triggered (true); + mail->setCloseTriggered (true); int rc = invoke_oom_method_with_parms (mail->item(), "Close", NULL, &dispparams); @@ -1844,13 +1844,13 @@ Mail::close (Mail *mail) } void -Mail::set_close_triggered (bool value) +Mail::setCloseTriggered (bool value) { m_close_triggered = value; } bool -Mail::get_close_triggered () const +Mail::getCloseTriggered () const { return m_close_triggered; } @@ -1898,9 +1898,9 @@ get_uid_for_sender (const Key &k, const char *sender) } void -Mail::update_sigstate () +Mail::updateSigstate_o () { - std::string sender = get_sender(); + std::string sender = getSender_o (); if (sender.empty()) { @@ -1963,13 +1963,13 @@ Mail::update_sigstate () } bool -Mail::is_valid_sig () const +Mail::isValidSig () const { return m_is_valid; } void -Mail::remove_categories () +Mail::removeCategories_o () { const char *decCategory = _("GpgOL: Encrypted Message"); const char *verifyCategory = _("GpgOL: Trusted Sender Address"); @@ -2040,11 +2040,11 @@ resize_active_window () } void -Mail::update_categories () +Mail::updateCategories_o () { const char *decCategory = _("GpgOL: Encrypted Message"); const char *verifyCategory = _("GpgOL: Trusted Sender Address"); - if (is_valid_sig()) + if (isValidSig ()) { add_category (m_mailitem, verifyCategory); } @@ -2070,19 +2070,19 @@ Mail::update_categories () } bool -Mail::is_signed() const +Mail::isSigned () const { return m_verify_result.numSignatures() > 0; } bool -Mail::is_encrypted() const +Mail::isEncrypted () const { return !m_decrypt_result.isNull(); } int -Mail::set_uuid() +Mail::setUUID_o () { char *uuid; if (!m_uuid.empty()) @@ -2112,7 +2112,7 @@ Mail::set_uuid() if (m_uuid.empty()) { m_uuid = uuid; - Mail *other = get_mail_for_uuid (uuid); + Mail *other = getMailForUUID (uuid); if (other) { /* According to documentation this should not @@ -2227,11 +2227,11 @@ level_4_check (const UserID &uid) } std::string -Mail::get_crypto_summary () const +Mail::getCryptoSummary () const { const int level = get_signature_level (); - bool enc = is_encrypted (); + bool enc = isEncrypted (); if (level == 4 && enc) { return _("Security Level 4"); @@ -2260,7 +2260,7 @@ Mail::get_crypto_summary () const { return _("Encrypted"); } - if (is_signed ()) + if (isSigned ()) { /* Even if it is signed, if it is not validly signed it's still completly insecure as anyone @@ -2273,10 +2273,10 @@ Mail::get_crypto_summary () const } std::string -Mail::get_crypto_one_line() const +Mail::getCryptoOneLine () const { - bool sig = is_signed (); - bool enc = is_encrypted (); + bool sig = isSigned (); + bool enc = isEncrypted (); if (sig || enc) { if (sig && enc) @@ -2296,12 +2296,12 @@ Mail::get_crypto_one_line() const } std::string -Mail::get_crypto_details() +Mail::getCryptoDetails_o () { std::string message; /* No signature with keys but error */ - if (!is_encrypted() && !is_signed () && m_verify_result.error()) + if (!isEncrypted () && !isSigned () && m_verify_result.error()) { message = _("You cannot be sure who sent, " "modified and read the message in transit."); @@ -2312,13 +2312,13 @@ Mail::get_crypto_details() return message; } /* No crypo, what are we doing here? */ - if (!is_encrypted () && !is_signed ()) + if (!isEncrypted () && !isSigned ()) { return _("You cannot be sure who sent, " "modified and read the message in transit."); } /* Handle encrypt only */ - if (is_encrypted() && !is_signed ()) + if (isEncrypted () && !isSigned ()) { if (in_de_vs_mode ()) { @@ -2338,7 +2338,7 @@ Mail::get_crypto_details() } bool keyFound = true; - bool isOpenPGP = m_sig.key().isNull() ? !is_smime() : + bool isOpenPGP = m_sig.key().isNull() ? !isSMIME_m () : m_sig.key().protocol() == Protocol::OpenPGP; char *buf; bool hasConflict = false; @@ -2436,7 +2436,7 @@ Mail::get_crypto_details() { /* Now we are in level 0, this could be a technical problem, no key or just unkown. */ - message = is_encrypted () ? _("But the sender address is not trustworthy because:") : + message = isEncrypted () ? _("But the sender address is not trustworthy because:") : _("The sender address is not trustworthy because:"); message += "\n"; keyFound = !(m_sig.summary() & Signature::Summary::KeyMissing); @@ -2503,7 +2503,7 @@ Mail::get_crypto_details() else if (m_uid.isNull()) { gpgrt_asprintf (&buf, _("does not claim the address: \"%s\"."), - get_sender().c_str()); + getSender_o ().c_str()); message += buf; xfree (buf); } @@ -2534,7 +2534,7 @@ Mail::get_crypto_details() message += "\n\n"; if (in_de_vs_mode ()) { - if (is_signed ()) + if (isSigned ()) { if (m_sig.isDeVs ()) { @@ -2546,7 +2546,7 @@ Mail::get_crypto_details() } message += "\n"; } - if (is_encrypted ()) + if (isEncrypted ()) { if (m_decrypt_result.isDeVs ()) { @@ -2622,15 +2622,15 @@ Mail::get_signature_level () const } int -Mail::get_crypto_icon_id () const +Mail::getCryptoIconID () const { int level = get_signature_level (); - int offset = is_encrypted () ? ENCRYPT_ICON_OFFSET : 0; + int offset = isEncrypted () ? ENCRYPT_ICON_OFFSET : 0; return IDI_LEVEL_0 + level + offset; } const char* -Mail::get_sig_fpr() const +Mail::getSigFpr () const { if (!m_is_signed || m_sig.isNull()) { @@ -2641,7 +2641,7 @@ Mail::get_sig_fpr() const /** Try to locate the keys for all recipients */ void -Mail::locate_keys() +Mail::locateKeys_o () { static bool locate_in_progress; @@ -2674,23 +2674,23 @@ Mail::locate_keys() locate_in_progress = true; // First update oom data to have recipients and sender updated. - update_oom_data (); - KeyCache::instance()->startLocateSecret (get_sender ().c_str (), this); - KeyCache::instance()->startLocate (get_sender ().c_str (), this); - KeyCache::instance()->startLocate (get_cached_recipients (), this); - autoresolve_check_s (); + updateOOMData_o (); + KeyCache::instance()->startLocateSecret (getSender_o ().c_str (), this); + KeyCache::instance()->startLocate (getSender_o ().c_str (), this); + KeyCache::instance()->startLocate (getRecipients (), this); + autoresolveCheck (); locate_in_progress = false; } bool -Mail::is_html_alternative () const +Mail::isHTMLAlternative () const { return m_is_html_alternative; } char * -Mail::take_cached_html_body () +Mail::takeCachedHTMLBody () { char *ret = m_cached_html_body; m_cached_html_body = nullptr; @@ -2698,7 +2698,7 @@ Mail::take_cached_html_body () } char * -Mail::take_cached_plain_body () +Mail::takeCachedPlainBody () { char *ret = m_cached_plain_body; m_cached_plain_body = nullptr; @@ -2706,37 +2706,37 @@ Mail::take_cached_plain_body () } int -Mail::get_crypto_flags () const +Mail::getCryptoFlags () const { return m_crypto_flags; } void -Mail::set_needs_encrypt (bool value) +Mail::setNeedsEncrypt (bool value) { m_needs_encrypt = value; } bool -Mail::needs_encrypt() const +Mail::getNeedsEncrypt () const { return m_needs_encrypt; } std::vector -Mail::get_cached_recipients() +Mail::getRecipients () { return m_cached_recipients; } void -Mail::append_to_inline_body (const std::string &data) +Mail::appendToInlineBody (const std::string &data) { m_inline_body += data; } int -Mail::inline_body_to_body() +Mail::inlineBodyToBody () { if (!m_crypter) { @@ -2760,7 +2760,7 @@ Mail::inline_body_to_body() } void -Mail::update_crypt_mapi() +Mail::updateCryptMAPI_m () { log_debug ("%s:%s: Update crypt mapi", SRCNAME, __func__); @@ -2801,10 +2801,10 @@ Mail::update_crypt_mapi() } /** If sync we need the crypter in update_crypt_oom */ - if (!async_crypt_disabled ()) + if (!isAsyncCryptDisabled ()) { // We don't need the crypter anymore. - reset_crypter (); + resetCrypter (); } } @@ -2815,7 +2815,7 @@ Mail::update_crypt_mapi() static std::pair has_crypt_or_empty_body_oom (Mail *mail) { - auto body = mail->get_body(); + auto body = mail->getBody_o (); std::pair ret; ret.first = false; ret.second = false; @@ -2838,7 +2838,7 @@ has_crypt_or_empty_body_oom (Mail *mail) } void -Mail::update_crypt_oom() +Mail::updateCryptOOM_o () { log_debug ("%s:%s: Update crypt oom for %p", SRCNAME, __func__, this); @@ -2846,13 +2846,13 @@ Mail::update_crypt_oom() { log_debug ("%s:%s: invalid state %i", SRCNAME, __func__, m_crypt_state); - reset_crypter (); + resetCrypter (); return; } - if (do_pgp_inline ()) + if (getDoPGPInline ()) { - if (inline_body_to_body ()) + if (inlineBodyToBody ()) { log_error ("%s:%s: Inline body to body failed %p.", SRCNAME, __func__, this); @@ -2878,9 +2878,9 @@ Mail::update_crypt_oom() /** When doing async update_crypt_mapi follows and needs the crypter. */ - if (async_crypt_disabled ()) + if (isAsyncCryptDisabled ()) { - reset_crypter (); + resetCrypter (); } const auto pair = has_crypt_or_empty_body_oom (this); @@ -2893,7 +2893,7 @@ Mail::update_crypt_oom() } // We are in MIME land. Wipe the body. - if (wipe (true)) + if (wipe_o (true)) { log_debug ("%s:%s: Cancel send for %p.", SRCNAME, __func__, this); @@ -2915,7 +2915,7 @@ Mail::update_crypt_oom() } void -Mail::set_window_enabled (bool value) +Mail::setWindowEnabled_o (bool value) { if (!value) { @@ -2965,7 +2965,7 @@ Mail::check_inline_response () char * inlineSubject = get_oom_string (inlineResponse, "Subject"); gpgol_release (inlineResponse); - const auto subject = get_subject (); + const auto subject = getSubject_o (); if (inlineResponse && !subject.empty() && !strcmp (subject.c_str (), inlineSubject)) { log_debug ("%s:%s: Detected inline response for '%p'", @@ -2982,9 +2982,9 @@ Mail::check_inline_response () // static Mail * -Mail::get_last_mail () +Mail::getLastMail () { - if (!s_last_mail || !is_valid_ptr (s_last_mail)) + if (!s_last_mail || !isValidPtr (s_last_mail)) { s_last_mail = nullptr; } @@ -2993,14 +2993,14 @@ Mail::get_last_mail () // static void -Mail::invalidate_last_mail () +Mail::clearLastMail () { s_last_mail = nullptr; } // static void -Mail::locate_all_crypto_recipients() +Mail::locateAllCryptoRecipients_o () { if (!opt.autoresolve) { @@ -3013,14 +3013,14 @@ Mail::locate_all_crypto_recipients() { if (it->second->needs_crypto ()) { - it->second->locate_keys (); + it->second->locateKeys_o (); } } gpgrt_lock_unlock (&mail_map_lock); } int -Mail::remove_all_attachments () +Mail::removeAllAttachments_o () { int ret = 0; LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments"); @@ -3065,7 +3065,7 @@ Mail::remove_all_attachments () } int -Mail::remove_our_attachments () +Mail::removeOurAttachments_o () { LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments"); if (!attachments) @@ -3127,7 +3127,7 @@ Mail::remove_our_attachments () /* We are very verbose because if we fail it might mean that we have leaked plaintext -> critical. */ bool -Mail::has_crypted_or_empty_body () +Mail::hasCryptedOrEmptyBody_o () { const auto pair = has_crypt_or_empty_body_oom (this); @@ -3186,7 +3186,7 @@ Mail::has_crypted_or_empty_body () } std::string -Mail::get_verification_result_dump() +Mail::getVerificationResultDump () { std::stringstream ss; ss << m_verify_result; @@ -3194,7 +3194,7 @@ Mail::get_verification_result_dump() } void -Mail::set_block_status() +Mail::setBlockStatus_m () { SPropValue prop; @@ -3215,19 +3215,19 @@ Mail::set_block_status() } void -Mail::set_block_html(bool value) +Mail::setBlockHTML (bool value) { m_block_html = value; } void -Mail::increment_locate_count() +Mail::incrementLocateCount () { m_locate_count++; } void -Mail::decrement_locate_count() +Mail::decrementLocateCount () { m_locate_count--; @@ -3239,12 +3239,12 @@ Mail::decrement_locate_count() } if (!m_locate_count) { - autoresolve_check_s (); + autoresolveCheck (); } } void -Mail::autoresolve_check_s() +Mail::autoresolveCheck () { if (!opt.autoresolve || m_manual_crypto_opts || m_locate_count) @@ -3266,7 +3266,7 @@ Mail::autoresolve_check_s() } void -Mail::set_do_autosecure_mapi(bool value) +Mail::setDoAutosecure_m (bool value) { TRACEPOINT; LPMESSAGE msg = get_oom_base_message (m_mailitem); @@ -3277,7 +3277,7 @@ Mail::set_do_autosecure_mapi(bool value) } /* We need to set a uuid so that autosecure can be disabled manually */ - set_uuid (); + setUUID_o (); int old_flags = get_gpgol_draft_info_flags (msg); if (old_flags && m_first_autosecure_check) diff --git a/src/mail.h b/src/mail.h index 7190306..287d07d 100644 --- a/src/mail.h +++ b/src/mail.h @@ -111,7 +111,7 @@ public: @returns A reference to an existing mailitem or NULL in case none could be found. */ - static Mail* get_mail_for_item (LPDISPATCH mailitem); + static Mail* getMailForItem (LPDISPATCH mailitem); /** @brief looks for existing Mail objects in the uuid map. Only objects for which set_uid has been called can be found @@ -120,16 +120,16 @@ public: @returns A reference to an existing mailitem or NULL in case none could be found. */ - static Mail* get_mail_for_uuid (const char *uuid); + static Mail* getMailForUUID (const char *uuid); /** @brief Get the last created mail. @returns A reference to the last created mail or null. */ - static Mail* get_last_mail (); + static Mail* getLastMail (); /** @brief voids the last mail variable. */ - static void invalidate_last_mail (); + static void clearLastMail (); /** @brief Lock mail deletion. @@ -146,22 +146,22 @@ public: Use it in your thread like: - Mail::delete_lock (); - Mail::is_valid_ptr (mail); + Mail::lockDelete (); + Mail::isValidPtr (mail); mail->set_or_check_something (); - Mail::delete_unlock (); + Mail::unlockDelete (); Still be carefull when it is a mapi or oom function. */ - static void delete_lock (); - static void delete_unlock (); + static void lockDelete (); + static void unlockDelete (); /** @brief looks for existing Mail objects. @returns A reference to an existing mailitem or NULL in case none could be found. Can be used to check if a mail object was destroyed. */ - static bool is_valid_ptr (const Mail *mail); + static bool isValidPtr (const Mail *mail); /** @brief wipe the plaintext from all known Mail objects. * @@ -171,7 +171,7 @@ public: * * @returns the number of errors that occured. */ - static int wipe_all_mails (); + static int wipeAllMails_o (); /** @brief revert all known Mail objects. * @@ -180,7 +180,7 @@ public: * * @returns the number of errors that occured. */ - static int revert_all_mails (); + static int revertAllMails_o (); /** @brief close all known Mail objects. * @@ -195,13 +195,13 @@ public: * * @returns the number of errors that occured. */ - static int close_all_mails (); + static int closeAllMails_o (); /** @brief closes the inspector for a mail * * @returns true on success. */ - static int close_inspector (Mail *mail); + static int closeInspector_o (Mail *mail); /** Call close with discard changes to discard plaintext. returns the value of the oom close @@ -220,7 +220,7 @@ public: * we march over all mails and if they are crypto mails we check * that the recipents were located. */ - static void locate_all_crypto_recipients (); + static void locateAllCryptoRecipients_o (); /** @brief Reference to the mailitem. Do not Release! */ LPDISPATCH item () { return m_mailitem; } @@ -233,14 +233,14 @@ public: * * @returns 0 on success. */ - int pre_process_message (); + int preProcessMessage_m (); /** @brief Decrypt / Verify the mail. * * Sets the needs_wipe and was_encrypted variable. * * @returns 0 on success. */ - int decrypt_verify (); + int decryptVerify_o (); /** @brief start crypto operations as selected by the user. * @@ -248,10 +248,10 @@ public: * draft info flags. * * @returns 0 on success. */ - int encrypt_sign_start (); + int encryptSignStart_o (); /** @brief Necessary crypto operations were completed successfully. */ - bool crypto_successful () { return m_crypt_successful || !needs_crypto(); } + bool wasCryptoSuccessful_m () { return m_crypt_successful || !needs_crypto(); } /** @brief Message should be encrypted and or signed. 0: No @@ -264,12 +264,12 @@ public: /** @brief wipe the plaintext from the message and encrypt attachments. * * @returns 0 on success; */ - int wipe (bool force = false); + int wipe_o (bool force = false); /** @brief revert the message to the original mail before our changes. * * @returns 0 on success; */ - int revert (); + int revert_o (); /** @brief update some data collected from the oom * @@ -284,7 +284,7 @@ public: * It also updated the is_html_alternative value. * * @returns 0 on success */ - int update_oom_data (); + int updateOOMData_o (); /** @brief get sender SMTP address (UTF-8 encoded). * @@ -292,19 +292,19 @@ public: * calls update_sender before returning the sender. * * @returns A reference to the utf8 sender address. Or an empty string. */ - std::string get_sender (); + std::string getSender_o (); /** @brief get sender SMTP address (UTF-8 encoded). * * Like get_sender but ensures not to touch oom or mapi * * @returns A reference to the utf8 sender address. Or an empty string. */ - std::string get_cached_sender () const; + std::string getSender () const; /** @brief get the subject string (UTF-8 encoded). * * @returns the subject or an empty string. */ - std::string get_subject () const; + std::string getSubject_o () const; /** @brief Is this a crypto mail handled by gpgol. * @@ -313,23 +313,23 @@ public: * @returns true if the mail was either signed or encrypted and we processed * it. */ - bool is_crypto_mail () const; + bool isCryptoMail () const; /** @brief This mail needs to be actually written. * * @returns true if the next write event should not be canceled. */ - bool needs_save () { return m_needs_save; } + bool needsSave () { return m_needs_save; } /** @brief set the needs save state. */ - void set_needs_save (bool val) { m_needs_save = val; } + void setNeedsSave (bool val) { m_needs_save = val; } /** @brief is this mail an S/MIME mail. * * @returns true for smime messages. */ - bool is_smime (); + bool isSMIME_m (); /** @brief get the associated parser. only valid while the actual parsing happens. */ @@ -337,7 +337,7 @@ public: /** @brief get the associated cryptcontroller. only valid while the crypting happens. */ - std::shared_ptr crypter () { return m_crypter; } + std::shared_ptr cryper () { return m_crypter; } /** To be called from outside once the paser was done. In Qt this would be a slot that is called once it is finished @@ -348,90 +348,90 @@ public: /** Returns true if the mail was verified and has at least one signature. Regardless of the validity of the mail */ - bool is_signed () const; + bool isSigned () const; /** Returns true if the mail is encrypted to at least one recipient. Regardless if it could be decrypted. */ - bool is_encrypted () const; + bool isEncrypted () const; /** Are we "green" */ - bool is_valid_sig () const; + bool isValidSig () const; /** Get UID gets UniqueID property of this mail. Returns an empty string if the uid was not set with set uid.*/ - const std::string & get_uuid () const { return m_uuid; } + const std::string & getUUID () const { return m_uuid; } /** Returns 0 on success if the mail has a uid alrady or sets the uid. Setting only succeeds if the OOM is currently accessible. Returns -1 on error. */ - int set_uuid (); + int setUUID_o (); /** Returns a localized string describing in one or two words the crypto status of this mail. */ - std::string get_crypto_summary () const; + std::string getCryptoSummary () const; /** Returns a localized string describing the detailed crypto state of this mail. */ - std::string get_crypto_details (); + std::string getCryptoDetails_o (); /** Returns a localized string describing a one line summary of the crypto state. */ - std::string get_crypto_one_line () const; + std::string getCryptoOneLine () const; /** Get the icon id of the appropiate icon for this mail */ - int get_crypto_icon_id () const; + int getCryptoIconID () const; /** Get the fingerprint of an associated signature or null if it is not signed. */ - const char *get_sig_fpr() const; + const char *getSigFpr () const; /** Remove all categories of this mail */ - void remove_categories (); + void removeCategories_o (); /** Get the body of the mail */ - std::string get_body () const; + std::string getBody_o () const; /** Get the html of the mail */ - std::string get_html_body () const; + std::string getHTMLBody_o () const; /** Get the recipients recipients is a null terminated array of strings. Needs to be freed by the caller. */ - char ** get_recipients () const; + char ** getRecipients_o () const; /** Try to locate the keys for all recipients */ - void locate_keys(); + void locateKeys_o (); /** State variable to check if a close was triggerd by us. */ - void set_close_triggered (bool value); - bool get_close_triggered () const; + void setCloseTriggered (bool value); + bool getCloseTriggered () const; /** Check if the mail should be sent as html alternative mail. Only valid if update_oom_data was called before. */ - bool is_html_alternative () const; + bool isHTMLAlternative () const; /** Get the html body. It is updated in update_oom_data. Caller takes ownership of the string and has to free it. */ - char *take_cached_html_body (); + char *takeCachedHTMLBody (); /** Get the plain body. It is updated in update_oom_data. Caller takes ownership of the string and has to free it. */ - char *take_cached_plain_body (); + char *takeCachedPlainBody (); /** Get the cached recipients. It is updated in update_oom_data.*/ - std::vector get_cached_recipients (); + std::vector getRecipients (); /** Returns 1 if the mail was encrypted, 2 if signed, 3 if both. Only valid after decrypt_verify. */ - int get_crypto_flags () const; + int getCryptoFlags () const; /** Returns true if the mail should be encrypted in the after write event. */ - bool needs_encrypt () const; - void set_needs_encrypt (bool val); + bool getNeedsEncrypt () const; + void setNeedsEncrypt (bool val); /** Gets the level of the signature. See: https://wiki.gnupg.org/EasyGpg2016/AutomatedEncryption for @@ -440,43 +440,43 @@ public: /** Check if all attachments are hidden and show a warning message appropiate to the crypto state if necessary. */ - int check_attachments () const; + int checkAttachments_o () const; /** Check if the mail should be encrypted "inline" */ - bool do_pgp_inline () const {return m_do_inline;} + bool getDoPGPInline () const {return m_do_inline;} /** Check if the mail should be encrypted "inline" */ - void set_do_pgp_inline (bool value) {m_do_inline = value;} + void setDoPGPInline (bool value) {m_do_inline = value;} /** Append data to a cached inline body. Helper to do this on MAPI level and later add it through OOM */ - void append_to_inline_body (const std::string &data); + void appendToInlineBody (const std::string &data); /** Set the inline body as OOM body property. */ - int inline_body_to_body (); + int inlineBodyToBody (); /** Get the crypt state */ - CryptState crypt_state () const {return m_crypt_state;} + CryptState cryptState () const {return m_crypt_state;} /** Set the crypt state */ - void set_crypt_state (CryptState state) {m_crypt_state = state;} + void setCryptState (CryptState state) {m_crypt_state = state;} /** Update MAPI data after encryption. */ - void update_crypt_mapi (); + void updateCryptMAPI_m (); /** Update OOM data after encryption. Checks for plain text leaks and does not advance crypt state if body can't be cleaned. */ - void update_crypt_oom (); + void updateCryptOOM_o (); /** Enable / Disable the window of this mail. When value is false the active window will be disabled and the handle stored for a later enable. */ - void set_window_enabled (bool value); + void setWindowEnabled_o (bool value); /** Determine if the mail is an inline response. @@ -484,7 +484,7 @@ public: from the OOM. We need synchronous encryption for inline responses. */ - bool async_crypt_disabled () { return m_async_crypt_disabled; } + bool isAsyncCryptDisabled () { return m_async_crypt_disabled; } /** Check through OOM if the current mail is an inline response. @@ -498,36 +498,36 @@ public: really valid in the time that the window is disabled. Use with care and can be null or invalid. */ - HWND get_window () { return m_window; } + HWND getWindow () { return m_window; } /** Cleanup any attached crypter object. Useful on error. */ - void reset_crypter () { m_crypter = nullptr; } + void resetCrypter () { m_crypter = nullptr; } /** Set special crypto mime data that should be used as the mime structure when sending. */ - void set_override_mime_data (const std::string &data) {m_mime_data = data;} + void setOverrideMIMEData (const std::string &data) {m_mime_data = data;} /** Get the mime data that should be used when sending. */ std::string get_override_mime_data () const { return m_mime_data; } /** Set if this is a forward of a crypto mail. */ - void set_is_forwarded_crypto_mail (bool value) { m_is_forwarded_crypto_mail = value; } + void setIsForwardedCryptoMail (bool value) { m_is_forwarded_crypto_mail = value; } bool is_forwarded_crypto_mail () { return m_is_forwarded_crypto_mail; } /** Set if this is a reply of a crypto mail. */ - void set_is_reply_crypto_mail (bool value) { m_is_reply_crypto_mail = value; } + void setIsReplyCryptoMail (bool value) { m_is_reply_crypto_mail = value; } bool is_reply_crypto_mail () { return m_is_reply_crypto_mail; } /** Remove the hidden GpgOL attachments. This is needed when forwarding without encryption so that our attachments are not included in the forward. Returns 0 on success. Works in OOM. */ - int remove_our_attachments (); + int removeOurAttachments_o (); /** Remove all attachments. Including our own. This is needed for forwarding of unsigned S/MIME mails (Efail). Returns 0 on success. Works in OOM. */ - int remove_all_attachments (); + int removeAllAttachments_o (); /** Check both OOM and MAPI if the body is either empty or encrypted. Won't abort on OOM or MAPI errors, so it can be @@ -539,58 +539,58 @@ public: of encryption and is only an extra check to catch unexpected errors. */ - bool has_crypted_or_empty_body (); + bool hasCryptedOrEmptyBody_o (); - void update_body (); + void updateBody_o (); /** Set if this mail looks like the send again of a crypto mail. This will mean that after it is decrypted it is treated like an unencrypted mail so that it can be encrypted again or sent unencrypted. */ - void set_is_send_again (bool value) { m_is_send_again = value; } + void setIsSendAgain (bool value) { m_is_send_again = value; } /* Attachment removal state variables. */ - bool attachment_remove_warning_disabled () { return m_disable_att_remove_warning; } + bool attachmentRemoveWarningDisabled () { return m_disable_att_remove_warning; } /* Gets the string dump of the verification result. */ - std::string get_verification_result_dump (); + std::string getVerificationResultDump (); /* Block loading HTML content */ - void set_block_html (bool value); - bool is_block_html () const { return m_block_html; } + void setBlockHTML (bool value); + bool isBlockHTML () const { return m_block_html; } /* Remove automatic loading of HTML references setting. */ - void set_block_status (); + void setBlockStatus_m (); /* Crypto options (sign/encrypt) have been set manually. */ - void set_crypto_selected_manually (bool v) { m_manual_crypto_opts = v; } + void setCryptoSelectedManually (bool v) { m_manual_crypto_opts = v; } // bool is_crypto_selected_manually () const { return m_manual_crypto_opts; } /* Reference that a resolver thread is running for this mail. */ - void increment_locate_count (); + void incrementLocateCount (); /* To be called when a resolver thread is done. If there are no running resolver threads we can check the recipients to see if we should toggle / untoggle the secure state. */ - void decrement_locate_count (); + void decrementLocateCount (); /* Check if the keys can be resolved automatically and trigger * setting the crypto flags accordingly. */ - void autoresolve_check_s (); + void autoresolveCheck (); /* Set if a mail should be secured (encrypted and signed) * * Only save to call from a place that may access mapi. */ - void set_do_autosecure_mapi (bool value); + void setDoAutosecure_m (bool value); private: - void update_categories (); - void update_sigstate (); + void updateCategories_o (); + void updateSigstate_o (); LPDISPATCH m_mailitem; LPDISPATCH m_event_sink; diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 51006f6..be15eea 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -127,7 +127,7 @@ EVENT_SINK_INVOKE(MailItemEvents) USE_INVOKE_ARGS if (!m_mail) { - m_mail = Mail::get_mail_for_item (m_object); + m_mail = Mail::getMailForItem (m_object); if (!m_mail) { log_error ("%s:%s: mail event without mail object known. Bug.", @@ -144,7 +144,7 @@ EVENT_SINK_INVOKE(MailItemEvents) log_oom_extra ("%s:%s: Open : %p", SRCNAME, __func__, m_mail); LPMESSAGE message; - if (g_ol_version_major < 14 && m_mail->set_uuid ()) + if (g_ol_version_major < 14 && m_mail->setUUID_o ()) { /* In Outlook 2007 we need the uid for every open mail to track the message in case @@ -182,7 +182,7 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: BeforeRead : %p", SRCNAME, __func__, m_mail); - if (m_mail->pre_process_message ()) + if (m_mail->preProcessMessage_m ()) { log_error ("%s:%s: Pre process message failed.", SRCNAME, __func__); @@ -193,7 +193,7 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: Read : %p", SRCNAME, __func__, m_mail); - if (!m_mail->is_crypto_mail()) + if (!m_mail->isCryptoMail ()) { log_debug ("%s:%s: Non crypto mail %p opened. Updating sigstatus.", SRCNAME, __func__, m_mail); @@ -202,26 +202,26 @@ EVENT_SINK_INVOKE(MailItemEvents) NULL)); break; } - if (m_mail->set_uuid ()) + if (m_mail->setUUID_o ()) { log_debug ("%s:%s: Failed to set uuid.", SRCNAME, __func__); delete m_mail; /* deletes this, too */ return S_OK; } - if (m_mail->decrypt_verify ()) + if (m_mail->decryptVerify_o ()) { log_error ("%s:%s: Decrypt message failed.", SRCNAME, __func__); } - if (!opt.enable_smime && m_mail->is_smime ()) + if (!opt.enable_smime && m_mail->isSMIME_m ()) { /* We want to save the mail when it's an smime mail and smime is disabled to revert it. */ log_debug ("%s:%s: S/MIME mail but S/MIME is disabled." " Need save.", SRCNAME, __func__); - m_mail->set_needs_save (true); + m_mail->setNeedsSave (true); } break; } @@ -236,7 +236,7 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } const wchar_t *prop_name = parms->rgvarg[0].bstrVal; - if (!m_mail->is_crypto_mail ()) + if (!m_mail->isCryptoMail ()) { if (!opt.autoresolve) { @@ -285,7 +285,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } log_debug ("%s:%s: Message %p looks like send again.", SRCNAME, __func__, m_object); - m_mail->set_is_send_again (true); + m_mail->setIsSendAgain (true); return S_OK; } @@ -355,7 +355,7 @@ EVENT_SINK_INVOKE(MailItemEvents) */ log_oom_extra ("%s:%s: Send : %p", SRCNAME, __func__, m_mail); - if (!m_mail->needs_crypto () && m_mail->crypt_state () == Mail::NoCryptMail) + if (!m_mail->needs_crypto () && m_mail->cryptState () == Mail::NoCryptMail) { log_debug ("%s:%s: No crypto neccessary. Passing send for %p obj %p", SRCNAME, __func__, m_mail, m_object); @@ -369,13 +369,13 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } - if (m_mail->crypt_state () == Mail::NoCryptMail && + if (m_mail->cryptState () == Mail::NoCryptMail && m_mail->needs_crypto ()) { // First contact with a mail to encrypt update // state and oom data. - m_mail->update_oom_data (); - m_mail->set_crypt_state (Mail::NeedsFirstAfterWrite); + m_mail->updateOOMData_o (); + m_mail->setCryptState (Mail::NeedsFirstAfterWrite); // Check inline response state before the write. m_mail->check_inline_response (); @@ -385,7 +385,7 @@ EVENT_SINK_INVOKE(MailItemEvents) // Save the Mail invoke_oom_method (m_object, "Save", NULL); - if (!m_mail->async_crypt_disabled ()) + if (!m_mail->isAsyncCryptDisabled ()) { // The afterwrite in the save should have triggered // the encryption. We cancel send for our asyncness. @@ -395,7 +395,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } else { - if (m_mail->crypt_state () == Mail::NoCryptMail) + if (m_mail->cryptState () == Mail::NoCryptMail) { // Crypto failed or was canceled log_debug ("%s:%s: Message %p mail %p cancelling send - " @@ -406,20 +406,20 @@ EVENT_SINK_INVOKE(MailItemEvents) } // For inline response we can't trigger send programatically // so we do the encryption in sync. - if (m_mail->crypt_state () == Mail::NeedsUpdateInOOM) + if (m_mail->cryptState () == Mail::NeedsUpdateInOOM) { - m_mail->update_crypt_oom (); + m_mail->updateCryptOOM_o (); } - if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite) + if (m_mail->cryptState () == Mail::NeedsSecondAfterWrite) { - m_mail->set_crypt_state (Mail::WantsSendMIME); + m_mail->setCryptState (Mail::WantsSendMIME); } - if (m_mail->do_pgp_inline () && m_mail->crypt_state () != Mail::WantsSendInline) + if (m_mail->getDoPGPInline () && m_mail->cryptState () != Mail::WantsSendInline) { log_debug ("%s:%s: Message %p mail %p cancelling send - " "Invalid state.", SRCNAME, __func__, m_object, m_mail); - gpgol_bug (m_mail->get_window (), + gpgol_bug (m_mail->getWindow (), ERR_INLINE_BODY_INV_STATE); *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; break; @@ -427,16 +427,16 @@ EVENT_SINK_INVOKE(MailItemEvents) } } - if (m_mail->crypt_state () == Mail::WantsSendInline) + if (m_mail->cryptState () == Mail::WantsSendInline) { - if (!m_mail->has_crypted_or_empty_body()) + if (!m_mail->hasCryptedOrEmptyBody_o ()) { log_debug ("%s:%s: Message %p mail %p cancelling send - " "not encrypted or not empty body detected.", SRCNAME, __func__, m_object, m_mail); - gpgol_bug (m_mail->get_window (), + gpgol_bug (m_mail->getWindow (), ERR_WANTS_SEND_INLINE_BODY); - m_mail->set_crypt_state (Mail::NoCryptMail); + m_mail->setCryptState (Mail::NoCryptMail); *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; break; } @@ -445,9 +445,9 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } - if (m_mail->crypt_state () == Mail::WantsSendMIME) + if (m_mail->cryptState () == Mail::WantsSendMIME) { - if (!m_mail->has_crypted_or_empty_body()) + if (!m_mail->hasCryptedOrEmptyBody_o ()) { /* The safety checks here trigger too often. Somehow for some users the body is not empty after the encryption but when @@ -462,12 +462,12 @@ EVENT_SINK_INVOKE(MailItemEvents) */ #define DISABLE_SAFTEY_CHECKS #ifndef DISABLE_SAFTEY_CHECKS - gpgol_bug (m_mail->get_window (), + gpgol_bug (m_mail->getWindow (), ERR_WANTS_SEND_MIME_BODY); log_debug ("%s:%s: Message %p mail %p cancelling send mime - " "not encrypted or not empty body detected.", SRCNAME, __func__, m_object, m_mail); - m_mail->set_crypt_state (Mail::NoCryptMail); + m_mail->setCryptState (Mail::NoCryptMail); *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; break; #else @@ -557,10 +557,10 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } - if (m_mail->is_crypto_mail () && !m_mail->needs_save ()) + if (m_mail->isCryptoMail () && !m_mail->needsSave ()) { - Mail *last_mail = Mail::get_last_mail (); - if (Mail::is_valid_ptr (last_mail)) + Mail *last_mail = Mail::getLastMail (); + if (Mail::isValidPtr (last_mail)) { /* We want to identify here if there was a mail created that should receive the contents of this mail. For this we check @@ -578,7 +578,7 @@ EVENT_SINK_INVOKE(MailItemEvents) Similarly if we crash or Outlook is closed before we see this revert. But as we immediately revert after the write this should also not happen. */ - const std::string lastSubject = last_mail->get_subject (); + const std::string lastSubject = last_mail->getSubject_o (); char *lastEntryID = get_oom_string (last_mail->item (), "EntryID"); int lastSize = get_oom_int (last_mail->item (), "Size"); std::string lastEntryStr; @@ -596,7 +596,7 @@ EVENT_SINK_INVOKE(MailItemEvents) /* This might be a forward. So don't invalidate yet. */ - // Mail::invalidate_last_mail (); + // Mail::clearLastMail (); do_in_ui_thread_async (REVERT_MAIL, m_mail); return S_OK; @@ -614,8 +614,8 @@ EVENT_SINK_INVOKE(MailItemEvents) return S_OK; } - if (m_mail->is_crypto_mail () && m_mail->needs_save () && - m_mail->revert ()) + if (m_mail->isCryptoMail () && m_mail->needsSave () && + m_mail->revert_o ()) { /* An error cleaning the mail should not happen normally. But just in case there is an error we cancel the @@ -625,8 +625,8 @@ EVENT_SINK_INVOKE(MailItemEvents) *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; } - if (!m_mail->is_crypto_mail () && m_mail->is_forwarded_crypto_mail () && - !m_mail->needs_crypto () && m_mail->crypt_state () == Mail::NoCryptMail) + if (!m_mail->isCryptoMail () && m_mail->is_forwarded_crypto_mail () && + !m_mail->needs_crypto () && m_mail->cryptState () == Mail::NoCryptMail) { /* We are sure now that while this is a forward of an encrypted * mail that the forward should not be signed or encrypted. So @@ -635,7 +635,7 @@ EVENT_SINK_INVOKE(MailItemEvents) log_debug ("%s:%s: Writing unencrypted forward of crypt mail. " "Removing attachments. mail: %p item: %p", SRCNAME, __func__, m_mail, m_object); - if (m_mail->remove_our_attachments ()) + if (m_mail->removeOurAttachments_o ()) { // Worst case we forward some encrypted data here not // a security problem, so let it pass. @@ -643,34 +643,34 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__); } /* Remove marker because we did this now. */ - m_mail->set_is_forwarded_crypto_mail (false); + m_mail->setIsForwardedCryptoMail (false); } log_debug ("%s:%s: Passing write event.", SRCNAME, __func__); - m_mail->set_needs_save (false); + m_mail->setNeedsSave (false); break; } case AfterWrite: { log_oom_extra ("%s:%s: AfterWrite : %p", SRCNAME, __func__, m_mail); - if (m_mail->crypt_state () == Mail::NeedsFirstAfterWrite) + if (m_mail->cryptState () == Mail::NeedsFirstAfterWrite) { /* Seen the first after write. Advance the state */ - m_mail->set_crypt_state (Mail::NeedsActualCrypt); - if (m_mail->encrypt_sign_start ()) + m_mail->setCryptState (Mail::NeedsActualCrypt); + if (m_mail->encryptSignStart_o ()) { log_debug ("%s:%s: Encrypt sign start failes.", SRCNAME, __func__); - m_mail->set_crypt_state (Mail::NoCryptMail); + m_mail->setCryptState (Mail::NoCryptMail); } return S_OK; } - if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite) + if (m_mail->cryptState () == Mail::NeedsSecondAfterWrite) { - m_mail->set_crypt_state (Mail::NeedsUpdateInMAPI); - m_mail->update_crypt_mapi (); + m_mail->setCryptState (Mail::NeedsUpdateInMAPI); + m_mail->updateCryptMAPI_m (); return S_OK; } break; @@ -679,7 +679,7 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: Close : %p", SRCNAME, __func__, m_mail); - if (m_mail->is_crypto_mail ()) + if (m_mail->isCryptoMail ()) { /* Close. This happens when an Opened mail is closed. To prevent the question of wether or not to save the changes @@ -696,10 +696,10 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__); break; } - if (m_mail->get_close_triggered ()) + if (m_mail->getCloseTriggered ()) { /* Our close with discard changes, pass through */ - m_mail->set_close_triggered (false); + m_mail->setCloseTriggered (false); return S_OK; } *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE; @@ -743,7 +743,7 @@ EVENT_SINK_INVOKE(MailItemEvents) { draft_flags += 2; } - bool is_crypto_mail = m_mail->is_crypto_mail(); + bool is_crypto_mail = m_mail->isCryptoMail (); /* If it is a crypto mail and the settings should not be taken * from the crypto mail and always encrypt / sign is on. Or @@ -780,8 +780,8 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } - Mail *last_mail = Mail::get_last_mail (); - if (Mail::is_valid_ptr (last_mail)) + Mail *last_mail = Mail::getLastMail (); + if (Mail::isValidPtr (last_mail)) { /* We want to identify here if there was a mail created that should receive the contents of this mail. For this we check @@ -809,7 +809,7 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__, last_mail, last_mail->item ()); - last_mail->set_is_forwarded_crypto_mail (true); + last_mail->setIsForwardedCryptoMail (true); } else { @@ -818,7 +818,7 @@ EVENT_SINK_INVOKE(MailItemEvents) SRCNAME, __func__, last_mail, last_mail->item ()); } - if (m_mail->is_block_html()) + if (m_mail->isBlockHTML ()) { std::string caption = _("GpgOL") + std::string (": "); caption += is_reply ? _("Dangerous reply") : @@ -845,7 +845,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } } // We can now invalidate the last mail - Mail::invalidate_last_mail (); + Mail::clearLastMail (); } log_oom_extra ("%s:%s: Reply Forward ReplyAll: %p", @@ -855,7 +855,7 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } int crypto_flags = 0; - if (!(crypto_flags = m_mail->get_crypto_flags ())) + if (!(crypto_flags = m_mail->getCryptoFlags ())) { break; } @@ -883,8 +883,8 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: AttachmentRemove: %p", SRCNAME, __func__, m_mail); - if (!m_mail->is_crypto_mail () || attachRemoveWarnShown || - m_mail->attachment_remove_warning_disabled ()) + if (!m_mail->isCryptoMail () || attachRemoveWarnShown || + m_mail->attachmentRemoveWarningDisabled ()) { return S_OK; } diff --git a/src/mimedataprovider.cpp b/src/mimedataprovider.cpp index d2eaa30..2b48382 100644 --- a/src/mimedataprovider.cpp +++ b/src/mimedataprovider.cpp @@ -1017,7 +1017,7 @@ MimeDataProvider::create_attachment() /* TODO handle encoding */ } -const std::string &MimeDataProvider::get_body() +const std::string &MimeDataProvider::get_body () { if (m_rawbuf.size()) { @@ -1031,7 +1031,7 @@ const std::string &MimeDataProvider::get_body() return m_body; } -const std::string &MimeDataProvider::get_html_body() +const std::string &MimeDataProvider::get_html_body () { if (!m_has_html_body) { diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index e4bd4aa..b1dfc31 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -97,7 +97,7 @@ int sink_string_write (sink_t sink, const void *data, size_t datalen) { Mail *mail = static_cast(sink->cb_data); - mail->append_to_inline_body (std::string((char*)data, datalen)); + mail->appendToInlineBody (std::string((char*)data, datalen)); return 0; } @@ -1026,7 +1026,7 @@ write_attachments (sink_t sink, static int is_related (Mail *mail, mapi_attach_item_t *table) { - if (!mail || !mail->is_html_alternative () || !table) + if (!mail || !mail->isHTMLAlternative () || !table) { return 0; } @@ -1287,7 +1287,7 @@ add_body (Mail *mail, const char *boundary, sink_t sink, bool is_alternative = false; if (mail) { - is_alternative = mail->is_html_alternative (); + is_alternative = mail->isHTMLAlternative (); } int rc = 0; @@ -1334,7 +1334,7 @@ add_body (Mail *mail, const char *boundary, sink_t sink, /* Now the html body. It is somehow not accessible through PR_HTML, OutlookSpy also shows MAPI Unsupported (but shows the data) strange. We just cache it. Memory is cheap :-) */ - char *html_body = mail->take_cached_html_body(); + char *html_body = mail->takeCachedHTMLBody (); if (!html_body) { log_error ("%s:%s: BUG: Body but no html body in alternative mail?", diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index d14af9f..5adada8 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -485,11 +485,11 @@ ParseController::parse() } const std::string -ParseController::get_html_body() const +ParseController::get_html_body () const { if (m_outputprovider) { - return m_outputprovider->get_html_body(); + return m_outputprovider->get_html_body (); } else { @@ -498,11 +498,11 @@ ParseController::get_html_body() const } const std::string -ParseController::get_body() const +ParseController::get_body () const { if (m_outputprovider) { - return m_outputprovider->get_body(); + return m_outputprovider->get_body (); } else { diff --git a/src/parsecontroller.h b/src/parsecontroller.h index c318b9d..863b94c 100644 --- a/src/parsecontroller.h +++ b/src/parsecontroller.h @@ -74,7 +74,7 @@ public: void parse(); /** Get the Body. Call parse first. */ - const std::string get_body() const; + const std::string get_body () const; /** Get the charset of the body. Call parse first. * @@ -86,7 +86,7 @@ public: const std::string get_html_charset() const; /** Get an alternative? HTML Body. Call parse first. */ - const std::string get_html_body() const; + const std::string get_html_body () const; /** Get the decrypted / verified attachments. Call parse first. */ diff --git a/src/revert.cpp b/src/revert.cpp index 302de55..1d3834d 100644 --- a/src/revert.cpp +++ b/src/revert.cpp @@ -105,7 +105,7 @@ gpgol_mailitem_revert (LPDISPATCH mailitem) return -1; } - mail = Mail::get_mail_for_item (mailitem); + mail = Mail::getMailForItem (mailitem); if (!mail) { xfree (msgcls); @@ -113,7 +113,7 @@ gpgol_mailitem_revert (LPDISPATCH mailitem) SRCNAME, __func__); return -1; } - is_smime = mail->is_smime (); + is_smime = mail->isSMIME_m (); message = get_oom_base_message (mailitem); attachments = get_oom_object (mailitem, "Attachments"); @@ -349,7 +349,7 @@ gpgol_mailitem_revert (LPDISPATCH mailitem) else if (is_smime && !opt.enable_smime) { /* SMIME is disabled remove our categories. */ - mail->remove_categories (); + mail->removeCategories_o (); } } diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp index 87ceab6..c38dd55 100644 --- a/src/ribbon-callbacks.cpp +++ b/src/ribbon-callbacks.cpp @@ -210,13 +210,13 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) Mail *mail = nullptr; if (uid) { - mail = Mail::get_mail_for_uuid (uid); + mail = Mail::getMailForUUID (uid); xfree (uid); } if (mail) { - mail->set_crypto_selected_manually (true); + mail->setCryptoSelectedManually (true); } else { @@ -260,7 +260,7 @@ mark_mime_action (LPDISPATCH ctrl, int flags, bool is_explorer) if (newflags & 1) { - Mail::locate_all_crypto_recipients (); + Mail::locateAllCryptoRecipients_o (); } return S_OK; @@ -485,7 +485,7 @@ get_mail_from_control (LPDISPATCH ctrl, bool *none_selected) } } - auto ret = Mail::get_mail_for_uuid (uid); + auto ret = Mail::getMailForUUID (uid); xfree (uid); if (!ret) { @@ -544,7 +544,7 @@ HRESULT get_sig_label (LPDISPATCH ctrl, VARIANT *result) xfree (w_result); return S_OK; } - w_result = utf8_to_wchar (mail->get_crypto_summary ().c_str ()); + w_result = utf8_to_wchar (mail->getCryptoSummary ().c_str ()); result->bstrVal = SysAllocString (w_result); xfree (w_result); return S_OK; @@ -558,7 +558,7 @@ HRESULT get_sig_ttip (LPDISPATCH ctrl, VARIANT *result) wchar_t *w_result; if (mail) { - w_result = utf8_to_wchar (mail->get_crypto_one_line().c_str()); + w_result = utf8_to_wchar (mail->getCryptoOneLine ().c_str()); } else if (!none_selected) { @@ -583,7 +583,7 @@ HRESULT get_sig_stip (LPDISPATCH ctrl, VARIANT *result) result->bstrVal = SysAllocString (L""); return S_OK; } - if (!mail || !mail->is_crypto_mail ()) + if (!mail || !mail->isCryptoMail ()) { wchar_t *w_result; w_result = utf8_to_wchar (utf8_gettext ("You cannot be sure who sent, " @@ -593,7 +593,7 @@ HRESULT get_sig_stip (LPDISPATCH ctrl, VARIANT *result) xfree (w_result); return S_OK; } - const auto message = mail->get_crypto_details (); + const auto message = mail->getCryptoDetails_o (); wchar_t *w_message = utf8_to_wchar (message.c_str()); result->bstrVal = SysAllocString (w_message); xfree (w_message); @@ -604,14 +604,14 @@ HRESULT launch_cert_details (LPDISPATCH ctrl) { MY_MAIL_GETTER - if (!mail || (!mail->is_signed () && !mail->is_encrypted ())) + if (!mail || (!mail->isSigned () && !mail->isEncrypted ())) { ShellExecuteA(NULL, NULL, "https://emailselfdefense.fsf.org/infographic", 0, 0, SW_SHOWNORMAL); return S_OK; } - if (!mail->is_signed () && mail->is_encrypted ()) + if (!mail->isSigned () && mail->isEncrypted ()) { /* Encrypt only, no information but show something. because we want the button to be active. @@ -625,18 +625,18 @@ HRESULT launch_cert_details (LPDISPATCH ctrl) char * buf; gpgrt_asprintf (&buf, _("The message was not cryptographically signed.\n" "There is no additional information available if it " - "was actually sent by '%s' or if someone faked the sender address."), mail->get_sender ().c_str()); + "was actually sent by '%s' or if someone faked the sender address."), mail->getSender_o ().c_str()); MessageBox (NULL, buf, _("GpgOL"), MB_ICONINFORMATION|MB_OK); xfree (buf); return S_OK; } - if (!mail->get_sig_fpr()) + if (!mail->getSigFpr ()) { std::string buf = _("There was an error verifying the signature.\n" "Full details:\n"); - buf += mail->get_verification_result_dump(); + buf += mail->getVerificationResultDump (); gpgol_message_box (get_active_hwnd(), buf.c_str(), _("GpgOL"), MB_OK); } @@ -662,7 +662,7 @@ HRESULT launch_cert_details (LPDISPATCH ctrl) std::string parentWid = std::to_string ((int) (intptr_t) get_active_hwnd ()); const char *argv[] = {path.c_str(), "--query", - mail->get_sig_fpr(), + mail->getSigFpr (), "--parent-windowid", parentWid.c_str(), NULL }; @@ -701,7 +701,7 @@ HRESULT get_crypto_icon (LPDISPATCH ctrl, VARIANT *result) if (mail) { - return getIcon (mail->get_crypto_icon_id (), result); + return getIcon (mail->getCryptoIconID (), result); } return getIcon (IDI_LEVEL_0, result); } @@ -712,7 +712,7 @@ HRESULT get_is_crypto_mail (LPDISPATCH ctrl, VARIANT *result) result->vt = VT_BOOL | VT_BYREF; result->pboolVal = (VARIANT_BOOL*) xmalloc (sizeof (VARIANT_BOOL)); - *(result->pboolVal) = (mail && (mail->is_signed () || mail->is_encrypted ())) ? + *(result->pboolVal) = (mail && (mail->isSigned () || mail->isEncrypted ())) ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 082dfa8..787f435 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -47,7 +47,7 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case (PARSING_DONE): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: Parsing done for mail which is gone.", SRCNAME, __func__); @@ -59,26 +59,26 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case (RECIPIENT_ADDED): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: Recipient add for mail which is gone.", SRCNAME, __func__); break; } - mail->locate_keys(); + mail->locateKeys_o (); break; } case (REVERT_MAIL): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: Revert mail for mail which is gone.", SRCNAME, __func__); break; } - mail->set_needs_save (true); + mail->setNeedsSave (true); /* Some magic here. Accessing any existing inline body cements it. Otherwise updating the body through the revert also changes the body of a inline mail. */ @@ -91,7 +91,7 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) invoke_oom_method (mail->item (), "Save", NULL); log_debug ("%s:%s: Revert mail. Save done. Updating body..", SRCNAME, __func__); - mail->update_body (); + mail->updateBody_o (); log_debug ("%s:%s: Revert mail done.", SRCNAME, __func__); break; @@ -109,13 +109,13 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { log_debug ("%s:%s: Invalidating last mail", SRCNAME, __func__); - Mail::invalidate_last_mail (); + Mail::clearLastMail (); break; } case (CLOSE): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: Close for mail which is gone.", SRCNAME, __func__); @@ -127,21 +127,21 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case (CRYPTO_DONE): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: Crypto done for mail which is gone.", SRCNAME, __func__); break; } // modify the mail. - if (mail->crypt_state () == Mail::NeedsUpdateInOOM) + if (mail->cryptState () == Mail::NeedsUpdateInOOM) { // Save the Mail log_debug ("%s:%s: Crypto done for %p updating oom.", SRCNAME, __func__, mail); - mail->update_crypt_oom(); + mail->updateCryptOOM_o (); } - if (mail->crypt_state () == Mail::NeedsSecondAfterWrite) + if (mail->cryptState () == Mail::NeedsSecondAfterWrite) { invoke_oom_method (mail->item (), "Save", NULL); log_debug ("%s:%s: Second save done for %p Invoking second send.", @@ -185,38 +185,38 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case (CLEAR_REPLY_FORWARD): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: Clear reply forward for mail which is gone.", SRCNAME, __func__); break; } - mail->wipe (true); - mail->remove_all_attachments (); + mail->wipe_o (true); + mail->removeAllAttachments_o (); break; } case (DO_AUTO_SECURE): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: DO_AUTO_SECURE for mail which is gone.", SRCNAME, __func__); break; } - mail->set_do_autosecure_mapi (true); + mail->setDoAutosecure_m (true); break; } case (DONT_AUTO_SECURE): { auto mail = (Mail*) ctx->data; - if (!Mail::is_valid_ptr (mail)) + if (!Mail::isValidPtr (mail)) { log_debug ("%s:%s: DO_AUTO_SECURE for mail which is gone.", SRCNAME, __func__); break; } - mail->set_do_autosecure_mapi (false); + mail->setDoAutosecure_m (false); break; } default: @@ -368,7 +368,7 @@ gpgol_hook(int code, WPARAM wParam, LPARAM lParam) log_debug ("%s:%s: WM_CLOSE windowmessage for explorer. " "Closing all mails.", SRCNAME, __func__); - Mail::close_all_mails(); + Mail::closeAllMails_o (); break; } } @@ -382,7 +382,7 @@ gpgol_hook(int code, WPARAM wParam, LPARAM lParam) { log_debug ("%s:%s: SC_CLOSE syscommand. Closing all mails.", SRCNAME, __func__); - Mail::close_all_mails(); + Mail::closeAllMails_o (); } */ break; default: diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index 52c05c1..9799576 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -621,16 +621,16 @@ WKSHelper::send_mail (const std::string &mimeData) const a different value then the one with which we saw the ItemLoad event. But we want to get the mail object. So,.. surpise a Hack! :-) */ - auto last_mail = Mail::get_last_mail (); + auto last_mail = Mail::getLastMail (); - if (!Mail::is_valid_ptr (last_mail)) + if (!Mail::isValidPtr (last_mail)) { log_error ("%s:%s: Invalid last mail %p.", SRCNAME, __func__, last_mail); return -1; } - last_mail->set_override_mime_data (mimeData); - last_mail->set_crypt_state (Mail::NeedsSecondAfterWrite); + last_mail->setOverrideMIMEData (mimeData); + last_mail->setCryptState (Mail::NeedsSecondAfterWrite); if (invoke_oom_method (mail, "Save", nullptr)) { @@ -760,7 +760,7 @@ WKSHelper::handle_confirmation_notify (const std::string &mbox) const _("GpgOL: Request confirmed!"), MB_OK); } - if (mail && Mail::is_valid_ptr (mail)) + if (mail && Mail::isValidPtr (mail)) { invoke_oom_method (mail->item(), "Delete", nullptr); } @@ -782,7 +782,7 @@ WKSHelper::handle_confirmation_read (Mail *mail, LPSTREAM stream) const } /* Get the recipient of the confirmation mail */ - char **recipients = mail->get_recipients (); + char **recipients = mail->getRecipients_o (); /* We assert that we have one recipient as the mail should have been sent by the wks-server. */ commit b0d80b45053d6c705377f26a5eff95e34f4070ff Author: Andre Heinecke Date: Thu Jun 21 14:34:21 2018 +0200 Constify some calls -- diff --git a/src/mail.cpp b/src/mail.cpp index f2be77c..e817b1e 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1576,7 +1576,7 @@ Mail::get_sender () } std::string -Mail::get_cached_sender () +Mail::get_cached_sender () const { return m_sender; } @@ -1963,7 +1963,7 @@ Mail::update_sigstate () } bool -Mail::is_valid_sig () +Mail::is_valid_sig () const { return m_is_valid; } @@ -2227,7 +2227,7 @@ level_4_check (const UserID &uid) } std::string -Mail::get_crypto_summary () +Mail::get_crypto_summary () const { const int level = get_signature_level (); @@ -2273,7 +2273,7 @@ Mail::get_crypto_summary () } std::string -Mail::get_crypto_one_line() +Mail::get_crypto_one_line() const { bool sig = is_signed (); bool enc = is_encrypted (); diff --git a/src/mail.h b/src/mail.h index 19f9859..7190306 100644 --- a/src/mail.h +++ b/src/mail.h @@ -197,6 +197,19 @@ public: */ static int close_all_mails (); + /** @brief closes the inspector for a mail + * + * @returns true on success. + */ + static int close_inspector (Mail *mail); + + /** Call close with discard changes to discard + plaintext. returns the value of the oom close + call. This may have delete the mail if the close + triggers an unload. + */ + static int close (Mail *mail); + /** @brief locate recipients for all crypto mails * * To avoid lookups of recipients for non crypto mails we only @@ -238,7 +251,7 @@ public: int encrypt_sign_start (); /** @brief Necessary crypto operations were completed successfully. */ - bool crypto_successful () { return !needs_crypto() || m_crypt_successful; } + bool crypto_successful () { return m_crypt_successful || !needs_crypto(); } /** @brief Message should be encrypted and or signed. 0: No @@ -286,7 +299,7 @@ public: * Like get_sender but ensures not to touch oom or mapi * * @returns A reference to the utf8 sender address. Or an empty string. */ - std::string get_cached_sender (); + std::string get_cached_sender () const; /** @brief get the subject string (UTF-8 encoded). * @@ -318,12 +331,6 @@ public: */ bool is_smime (); - /** @brief closes the inspector for a mail - * - * @returns true on success. - */ - static int close_inspector (Mail *mail); - /** @brief get the associated parser. only valid while the actual parsing happens. */ std::shared_ptr parser () { return m_parser; } @@ -348,7 +355,7 @@ public: bool is_encrypted () const; /** Are we "green" */ - bool is_valid_sig (); + bool is_valid_sig () const; /** Get UID gets UniqueID property of this mail. Returns an empty string if the uid was not set with set uid.*/ @@ -361,7 +368,7 @@ public: /** Returns a localized string describing in one or two words the crypto status of this mail. */ - std::string get_crypto_summary (); + std::string get_crypto_summary () const; /** Returns a localized string describing the detailed crypto state of this mail. */ @@ -369,7 +376,7 @@ public: /** Returns a localized string describing a one line summary of the crypto state. */ - std::string get_crypto_one_line (); + std::string get_crypto_one_line () const; /** Get the icon id of the appropiate icon for this mail */ int get_crypto_icon_id () const; @@ -392,13 +399,6 @@ public: by the caller. */ char ** get_recipients () const; - /** Call close with discard changes to discard - plaintext. returns the value of the oom close - call. This may have delete the mail if the close - triggers an unload. - */ - static int close (Mail *mail); - /** Try to locate the keys for all recipients */ void locate_keys(); commit f8a13fcbfcbf2b04f9763621d0917b4f402b5670 Author: Andre Heinecke Date: Thu Jun 21 14:28:26 2018 +0200 Introduce naming conventions * src/mail.h: Add comment explaining naming convetions and explain window message and OOM interaction. diff --git a/src/mail.h b/src/mail.h index afd8d09..19f9859 100644 --- a/src/mail.h +++ b/src/mail.h @@ -44,6 +44,42 @@ class CryptController; * * This class bundles such information and also provides a way to * access the event handler of a mail. + * + * Naming conventions of the suffixes: + * _o functions that work on OOM and possibly also MAPI. + * _m functions that work on MAPI. + * _s functions that only work on internal data and are safe to call + * from any thread. + * + * O and M functions _must_ only be called from the main thread. Use + * a WindowMessage to signal the Main thread. But be wary. A WindowMessage + * might be handled while an OOM call in the main thread waits for completion. + * + * An example for this is how update_oom_data can work: + * + * Main Thread: + * call update_oom_data + * ?> internally invokes an OOM function that might do network access e.g. + * to connect to the exchange server to fetch the address. + * + * Counterintutively the Main thread does not return from that function or + * blocks for it's completion but handles windowmessages. + * + * After a windowmessage was handled and if the OOM invocation is + * completed the invocation returns and normal execution continues. + * + * So if the window message handler's includes for example + * also a call to lookup recipients we crash. Note that it's usually + * safe to do OOM / MAPI calls from a window message. + * + * + * While this seems impossible, remember that we do not work directly + * with functions but everything is handled through COM. Without this + * logic Outlook would probably become unusable because as any long running + * call to the OOM would block it completely and freeze the UI. + * (no windowmessages handled). + * + * So be wary when accessing the OOM from a Window Message. */ class Mail { ----------------------------------------------------------------------- Summary of changes: src/cryptcontroller.cpp | 40 +++--- src/gpgoladdin.cpp | 2 +- src/keycache.cpp | 20 +-- src/mail.cpp | 312 +++++++++++++++++++++++------------------------ src/mail.h | 234 ++++++++++++++++++++--------------- src/mailitem-events.cpp | 122 +++++++++--------- src/mimedataprovider.cpp | 4 +- src/mimemaker.cpp | 8 +- src/parsecontroller.cpp | 8 +- src/parsecontroller.h | 4 +- src/revert.cpp | 6 +- src/ribbon-callbacks.cpp | 32 ++--- src/windowmessages.cpp | 42 +++---- src/wks-helper.cpp | 12 +- 14 files changed, 441 insertions(+), 405 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 21 20:36:57 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Jun 2018 20:36:57 +0200 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-162-g592deed Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 592deeddb9bf4ae9b3e236b439e2f39644eb6d46 (commit) via b7cd2c2093ae1b47645be50fa1d431a028187cad (commit) from 386b9c4f25b28fd769d7563f2d86ac3a19cc3011 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 592deeddb9bf4ae9b3e236b439e2f39644eb6d46 Author: Werner Koch Date: Thu Jun 21 20:28:40 2018 +0200 gpg: Print revocation reason for "rev" records. * g10/main.h: Add prototype. * g10/keylist.c (list_keyblock_print): Print revocation info. (list_keyblock_colon): Ditto. * g10/test-stubs.c (get_revocation_reason): New stub. * g10/gpgv.c (get_revocation_reason): New stub. -- GnuPG-bug-id: 1173 Signed-off-by: Werner Koch diff --git a/g10/gpgv.c b/g10/gpgv.c index c43067d..c142cef 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -772,3 +772,18 @@ tofu_notice_key_changed (ctrl_t ctrl, kbnode_t kb) return 0; } + + +int +get_revocation_reason (PKT_signature *sig, char **r_reason, + char **r_comment, size_t *r_commentlen) +{ + (void)sig; + (void)r_commentlen; + + if (r_reason) + *r_reason = NULL; + if (r_comment) + *r_comment = NULL; + return 0; +} diff --git a/g10/keylist.c b/g10/keylist.c index 1f501fc..39b87e4 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1107,6 +1107,9 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, PKT_signature *sig = node->pkt->pkt.signature; int sigrc; char *sigstr; + char *reason_text = NULL; + char *reason_comment = NULL; + size_t reason_commentlen; if (listctx->check_sigs) { @@ -1143,7 +1146,11 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, if (sig->sig_class == 0x20 || sig->sig_class == 0x28 || sig->sig_class == 0x30) - sigstr = "rev"; + { + sigstr = "rev"; + get_revocation_reason (sig, &reason_text, + &reason_comment, &reason_commentlen); + } else if ((sig->sig_class & ~3) == 0x10) sigstr = "sig"; else if (sig->sig_class == 0x18) @@ -1205,6 +1212,40 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) show_keyserver_url (sig, 3, 0); + if (reason_text) + { + es_fprintf (es_stdout, " %s%s\n", + _("reason for revocation: "), reason_text); + if (reason_comment) + { + const byte *s, *s_lf; + size_t n, n_lf; + + s = reason_comment; + n = reason_commentlen; + s_lf = NULL; + do + { + /* We don't want any empty lines, so we skip them. */ + for (;n && *s == '\n'; s++, n--) + ; + if (n) + { + s_lf = memchr (s, '\n', n); + n_lf = s_lf? s_lf - s : n; + es_fprintf (es_stdout, " %s", + _("revocation comment: ")); + es_write_sanitized (es_stdout, s, n_lf, NULL, NULL); + es_putc ('\n', es_stdout); + s += n_lf; n -= n_lf; + } + } while (s_lf); + } + } + + xfree (reason_text); + xfree (reason_comment); + /* fixme: check or list other sigs here */ } } @@ -1554,10 +1595,19 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, char *siguid; size_t siguidlen; char *issuer_fpr = NULL; + char *reason_text = NULL; + char *reason_comment = NULL; + size_t reason_commentlen; + int reason_code; if (sig->sig_class == 0x20 || sig->sig_class == 0x28 || sig->sig_class == 0x30) - sigstr = "rev"; + { + sigstr = "rev"; + reason_code = get_revocation_reason (sig, &reason_text, + &reason_comment, + &reason_commentlen); + } else if ((sig->sig_class & ~3) == 0x10) sigstr = "sig"; else if (sig->sig_class == 0x18) @@ -1651,8 +1701,11 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, else if (siguid) es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL); - es_fprintf (es_stdout, ":%02x%c::", sig->sig_class, + es_fprintf (es_stdout, ":%02x%c", sig->sig_class, sig->flags.exportable ? 'x' : 'l'); + if (reason_text) + es_fprintf (es_stdout, ",%02x", reason_code); + es_fputs ("::", es_stdout); if (opt.no_sig_cache && opt.check_sigs && fprokay) { @@ -1662,12 +1715,23 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, else if ((issuer_fpr = issuer_fpr_string (sig))) es_fputs (issuer_fpr, es_stdout); - es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo); + es_fprintf (es_stdout, ":::%d:", sig->digest_algo); + + if (reason_comment) + { + es_fputs ("::::", es_stdout); + es_write_sanitized (es_stdout, reason_comment, reason_commentlen, + ":", NULL); + es_putc (':', es_stdout); + } + es_putc ('\n', es_stdout); if (opt.show_subpackets) print_subpackets_colon (sig); /* fixme: check or list other sigs here */ + xfree (reason_text); + xfree (reason_comment); xfree (siguid); xfree (issuer_fpr); } diff --git a/g10/main.h b/g10/main.h index 453d122..768f7cf 100644 --- a/g10/main.h +++ b/g10/main.h @@ -396,6 +396,9 @@ gpg_error_t transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats, int collapse_uids( KBNODE *keyblock ); +int get_revocation_reason (PKT_signature *sig, char **r_reason, + char **r_comment, size_t *r_commentlen); + /*-- export.c --*/ struct export_stats_s; diff --git a/g10/test-stubs.c b/g10/test-stubs.c index e5fd3ae..1e13632 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -535,3 +535,17 @@ tofu_notice_key_changed (ctrl_t ctrl, kbnode_t kb) return 0; } + +int +get_revocation_reason (PKT_signature *sig, char **r_reason, + char **r_comment, size_t *r_commentlen) +{ + (void)sig; + (void)r_commentlen; + + if (r_reason) + *r_reason = NULL; + if (r_comment) + *r_comment = NULL; + return 0; +} commit b7cd2c2093ae1b47645be50fa1d431a028187cad Author: Werner Koch Date: Thu Jun 21 18:32:13 2018 +0200 gpg: Print revocation reason for "rvs" records. * g10/import.c (get_revocation_reason): New. (list_standalone_revocation): Extend function. -- Note that this function extends the "rvs" field signature-class (field 11) with the revocation reason. GPGME does not yet parse this but it can be expected that the comma delimiter does not break other parsers. A new field is added to the "rvs" (and in future also the "rev") record to carry a record specific comment. Hopefully all parsers meanwhile learned the lesson from other new fields and don't bail out on more fields than they know about. This is partial solution to GnuPG-bug-id: 1173 Signed-off-by: Werner Koch diff --git a/doc/DETAILS b/doc/DETAILS index 1bfc04d..eb6d7dd 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -180,6 +180,9 @@ described here. revocation key is also given here, 'x' and 'l' is used the same way. This field if not used for X.509. + "rev" and "rvs" may be followed by a comma and a 2 digit hexnumber + with the revocation reason. + *** Field 12 - Key capabilities The defined capabilities are: @@ -262,6 +265,12 @@ described here. optionally followed by a space and an URL. This goes along with the previous field. The URL is quoted in C style. +*** Field 21 - Comment + + This is currently only used in "rev" and "rvs" records to carry + the the comment field of the recocation reason. The value is + quoted in C style. + ** Special fields *** PKD - Public key data diff --git a/g10/import.c b/g10/import.c index 022f077..b20879c 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2633,6 +2633,69 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, +/* Return the recocation reason from signature SIG. If no revocation + * reason is availabale 0 is returned, in other cases the reason + * (0..255). If R_REASON is not NULL a malloced textual + * representation of the code is stored there. If R_COMMENT is not + * NULL the comment from the reason is stored there and its length at + * R_COMMENTLEN. Note that the value at R_COMMENT is not filtered but + * user supplied data in UTF8; thus it needs to be escaped for display + * purposes. Both return values are either NULL or a malloced + * string/buffer. */ +int +get_revocation_reason (PKT_signature *sig, char **r_reason, + char **r_comment, size_t *r_commentlen) +{ + int reason_seq = 0; + size_t reason_n; + const byte *reason_p; + char reason_code_buf[20]; + const char *reason_text = NULL; + int reason_code = 0; + + if (r_reason) + *r_reason = NULL; + if (r_comment) + *r_comment = NULL; + + /* Skip over empty reason packets. */ + while ((reason_p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REVOC_REASON, + &reason_n, &reason_seq, NULL)) + && !reason_n) + ; + if (reason_p) + { + reason_code = *reason_p; + reason_n--; reason_p++; + switch (reason_code) + { + case 0x00: reason_text = _("No reason specified"); break; + case 0x01: reason_text = _("Key is superseded"); break; + case 0x02: reason_text = _("Key has been compromised"); break; + case 0x03: reason_text = _("Key is no longer used"); break; + case 0x20: reason_text = _("User ID is no longer valid"); break; + default: + snprintf (reason_code_buf, sizeof reason_code_buf, + "code=%02x", reason_code); + reason_text = reason_code_buf; + break; + } + + if (r_reason) + *r_reason = xstrdup (reason_text); + + if (r_comment && reason_n) + { + *r_comment = xmalloc (reason_n); + memcpy (*r_comment, reason_p, reason_n); + *r_commentlen = reason_n; + } + } + + return reason_code; +} + + /* List the recocation signature as a "rvs" record. SIGRC shows the * character from the signature verification or 0 if no public key was * found. */ @@ -2642,6 +2705,10 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) char *siguid = NULL; size_t siguidlen = 0; char *issuer_fpr = NULL; + int reason_code = 0; + char *reason_text = NULL; + char *reason_comment = NULL; + size_t reason_commentlen; if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode) { @@ -2651,6 +2718,9 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) sigrc = '?'; } + reason_code = get_revocation_reason (sig, &reason_text, + &reason_comment, &reason_commentlen); + if (opt.with_colons) { es_fputs ("rvs:", es_stdout); @@ -2665,13 +2735,25 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) if (siguid) es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL); - es_fprintf (es_stdout, ":%02x%c::", sig->sig_class, + es_fprintf (es_stdout, ":%02x%c", sig->sig_class, sig->flags.exportable ? 'x' : 'l'); + if (reason_text) + es_fprintf (es_stdout, ",%02x", reason_code); + es_fputs ("::", es_stdout); if ((issuer_fpr = issuer_fpr_string (sig))) es_fputs (issuer_fpr, es_stdout); - es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo); + es_fprintf (es_stdout, ":::%d:", sig->digest_algo); + + if (reason_comment) + { + es_fputs ("::::", es_stdout); + es_write_sanitized (es_stdout, reason_comment, reason_commentlen, + ":", NULL); + es_putc (':', es_stdout); + } + es_putc ('\n', es_stdout); if (opt.show_subpackets) print_subpackets_colon (sig); @@ -2712,10 +2794,43 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) if (sig->flags.pref_ks && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) show_keyserver_url (sig, 3, 0); + + if (reason_text) + { + es_fprintf (es_stdout, " %s%s\n", + _("reason for revocation: "), reason_text); + if (reason_comment) + { + const byte *s, *s_lf; + size_t n, n_lf; + + s = reason_comment; + n = reason_commentlen; + s_lf = NULL; + do + { + /* We don't want any empty lines, so we skip them. */ + for (;n && *s == '\n'; s++, n--) + ; + if (n) + { + s_lf = memchr (s, '\n', n); + n_lf = s_lf? s_lf - s : n; + es_fprintf (es_stdout, " %s", + _("revocation comment: ")); + es_write_sanitized (es_stdout, s, n_lf, NULL, NULL); + es_putc ('\n', es_stdout); + s += n_lf; n -= n_lf; + } + } while (s_lf); + } + } } es_fflush (es_stdout); + xfree (reason_text); + xfree (reason_comment); xfree (siguid); xfree (issuer_fpr); } diff --git a/g10/pkclist.c b/g10/pkclist.c index 6aec138..2322f78 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -113,7 +113,7 @@ void show_revocation_reason (ctrl_t ctrl, PKT_public_key *pk, int mode) { /* Hmmm, this is not so easy because we have to duplicate the code - * used in the trustbd to calculate the keyflags. We need to find + * used in the trustdb to calculate the keyflags. We need to find * a clean way to check revocation certificates on keys and * signatures. And there should be no duplicate code. Because we * enter this function only when the trustdb told us that we have ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 9 +++++ g10/gpgv.c | 15 +++++++ g10/import.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- g10/keylist.c | 72 +++++++++++++++++++++++++++++++-- g10/main.h | 3 ++ g10/pkclist.c | 2 +- g10/test-stubs.c | 14 +++++++ 7 files changed, 227 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 22 15:21:24 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 22 Jun 2018 15:21:24 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-16-gb853a5a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via b853a5a70e325c80628edf4720e3ccb6030f1860 (commit) via d78c84ff7bb45a3ac6a5f277db2210730b0609c9 (commit) from b4b5960c7397ce65d0c105f3538270157fd40e5e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b853a5a70e325c80628edf4720e3ccb6030f1860 Author: Andre Heinecke Date: Fri Jun 22 15:19:34 2018 +0200 Fix WKS when async enc is disabled * src/mailitem-events.cpp (Send): Allow notify after the send. * src/windowmessages.cpp (CRYPTO_DONE): Don't do allow notify here. diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 9191005..41c1376 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -30,6 +30,7 @@ #include "mail.h" #include "mapihelp.h" #include "gpgoladdin.h" +#include "wks-helper.h" #undef _ #define _(a) utf8_gettext (a) @@ -361,16 +362,17 @@ EVENT_SINK_INVOKE(MailItemEvents) if (m_mail->cryptState () == Mail::NoCryptMail && m_mail->needs_crypto_m ()) { + log_debug ("%s:%s: Send event for crypto mail %p saving and starting.", + SRCNAME, __func__, m_mail); + // First contact with a mail to encrypt update // state and oom data. m_mail->updateOOMData_o (); + m_mail->setCryptState (Mail::NeedsFirstAfterWrite); // Check inline response state before the write. m_mail->check_inline_response (); - - log_debug ("%s:%s: Send event for crypto mail %p saving and starting.", - SRCNAME, __func__, m_mail); // Save the Mail invoke_oom_method (m_object, "Save", NULL); @@ -431,6 +433,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } log_debug ("%s:%s: Passing send event for no-mime message %p.", SRCNAME, __func__, m_object); + WKSHelper::instance()->allow_notify (1000); break; } @@ -516,8 +519,9 @@ EVENT_SINK_INVOKE(MailItemEvents) { break; } - log_debug ("%s:%s: Passing send event for message %p.", + log_debug ("%s:%s: Passing send event for mime-encrypted message %p.", SRCNAME, __func__, m_object); + WKSHelper::instance()->allow_notify (1000); break; } else diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 787f435..83d0cfd 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -151,10 +151,6 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) invoke_oom_method (mail->item (), "Send", NULL); log_debug ("%s:%s: Send for %p completed.", SRCNAME, __func__, mail); - // Allow the WKS helper to queue a notification. - WKSHelper::instance()->allow_notify (); - log_debug ("%s:%s: Crypto done handler completed.", - SRCNAME, __func__); break; } case (BRING_TO_FRONT): commit d78c84ff7bb45a3ac6a5f277db2210730b0609c9 Author: Andre Heinecke Date: Fri Jun 22 14:46:04 2018 +0200 More cleanup and convetional naming -- diff --git a/src/mail.cpp b/src/mail.cpp index 783ccd3..11266e5 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -202,6 +202,7 @@ Mail::~Mail() SRCNAME, __func__); } +//static Mail * Mail::getMailForItem (LPDISPATCH mailitem) { @@ -220,6 +221,7 @@ Mail::getMailForItem (LPDISPATCH mailitem) return it->second; } +//static Mail * Mail::getMailForUUID (const char *uuid) { @@ -237,6 +239,7 @@ Mail::getMailForUUID (const char *uuid) return it->second; } +//static bool Mail::isValidPtr (const Mail *mail) { @@ -297,7 +300,7 @@ Mail::preProcessMessage_m () } static LPDISPATCH -get_attachment (LPDISPATCH mailitem, int pos) +get_attachment_o (LPDISPATCH mailitem, int pos) { LPDISPATCH attachment; LPDISPATCH attachments = get_oom_object (mailitem, "Attachments"); @@ -418,7 +421,7 @@ Mail::checkAttachments_o () const /** Get the cipherstream of the mailitem. */ static LPSTREAM -get_attachment_stream (LPDISPATCH mailitem, int pos) +get_attachment_stream_o (LPDISPATCH mailitem, int pos) { if (!pos) { @@ -426,7 +429,7 @@ get_attachment_stream (LPDISPATCH mailitem, int pos) SRCNAME, __func__); return NULL; } - LPDISPATCH attachment = get_attachment (mailitem, pos); + LPDISPATCH attachment = get_attachment_o (mailitem, pos); LPSTREAM stream = NULL; if (!attachment) @@ -610,7 +613,7 @@ copy_attachment_to_file (std::shared_ptr att, HANDLE hFile) /** Sets some meta data on the last attachment added. The meta data is taken from the attachment object. */ static int -fixup_last_attachment (LPDISPATCH mail, std::shared_ptr attachment) +fixup_last_attachment_o (LPDISPATCH mail, std::shared_ptr attachment) { /* Currently we only set content id */ if (attachment->get_content_id ().empty()) @@ -620,7 +623,7 @@ fixup_last_attachment (LPDISPATCH mail, std::shared_ptr attachment) return 0; } - LPDISPATCH attach = get_attachment (mail, -1); + LPDISPATCH attach = get_attachment_o (mail, -1); if (!attach) { log_error ("%s:%s: No attachment.", @@ -637,7 +640,7 @@ fixup_last_attachment (LPDISPATCH mail, std::shared_ptr attachment) /** Helper to update the attachments of a mail object in oom. does not modify the underlying mapi structure. */ static int -add_attachments(LPDISPATCH mail, +add_attachments_o(LPDISPATCH mail, std::vector > attachments) { int err = 0; @@ -675,7 +678,7 @@ add_attachments(LPDISPATCH mail, xfree (wchar_file); xfree (wchar_name); - err = fixup_last_attachment (mail, att); + err = fixup_last_attachment_o (mail, att); } return err; } @@ -1004,7 +1007,7 @@ Mail::decryptVerify_o () xfree (placeholder_buf); /* Do the actual parsing */ - auto cipherstream = get_attachment_stream (m_mailitem, m_moss_position); + auto cipherstream = get_attachment_stream_o (m_mailitem, m_moss_position); if (m_type == MSGTYPE_GPGOL_WKS_CONFIRMATION) { @@ -1309,7 +1312,7 @@ Mail::parsing_done() m_crypto_flags |= 2; } - updateSigstate_o (); + updateSigstate (); m_needs_wipe = !m_is_send_again; TRACEPOINT; @@ -1334,7 +1337,7 @@ Mail::parsing_done() checkAttachments_o (); /* Update attachments */ - if (add_attachments (m_mailitem, m_parser->get_attachments())) + if (add_attachments_o (m_mailitem, m_parser->get_attachments())) { log_error ("%s:%s: Failed to update attachments.", SRCNAME, __func__); @@ -1378,7 +1381,7 @@ Mail::encryptSignStart_o () return -1; } int flags = 0; - if (!needs_crypto()) + if (!needs_crypto_m ()) { return 0; } @@ -1452,7 +1455,7 @@ Mail::encryptSignStart_o () } int -Mail::needs_crypto () +Mail::needs_crypto_m () const { LPMESSAGE message = get_oom_message (m_mailitem); bool ret; @@ -1737,7 +1740,7 @@ Mail::isSMIME_m () } static std::string -get_string (LPDISPATCH item, const char *str) +get_string_o (LPDISPATCH item, const char *str) { char *buf = get_oom_string (item, str); if (!buf) @@ -1750,19 +1753,19 @@ get_string (LPDISPATCH item, const char *str) std::string Mail::getSubject_o () const { - return get_string (m_mailitem, "Subject"); + return get_string_o (m_mailitem, "Subject"); } std::string Mail::getBody_o () const { - return get_string (m_mailitem, "Body"); + return get_string_o (m_mailitem, "Body"); } std::string Mail::getHTMLBody_o () const { - return get_string (m_mailitem, "HTMLBody"); + return get_string_o (m_mailitem, "HTMLBody"); } char ** @@ -1898,9 +1901,9 @@ get_uid_for_sender (const Key &k, const char *sender) } void -Mail::updateSigstate_o () +Mail::updateSigstate () { - std::string sender = getSender_o (); + std::string sender = getSender (); if (sender.empty()) { @@ -2736,7 +2739,7 @@ Mail::appendToInlineBody (const std::string &data) } int -Mail::inlineBodyToBody () +Mail::inlineBodyToBody_o () { if (!m_crypter) { @@ -2852,7 +2855,7 @@ Mail::updateCryptOOM_o () if (getDoPGPInline ()) { - if (inlineBodyToBody ()) + if (inlineBodyToBody_o ()) { log_error ("%s:%s: Inline body to body failed %p.", SRCNAME, __func__, this); @@ -3011,7 +3014,7 @@ Mail::locateAllCryptoRecipients_o () std::map::iterator it; for (it = s_mail_map.begin(); it != s_mail_map.end(); ++it) { - if (it->second->needs_crypto ()) + if (it->second->needs_crypto_m ()) { it->second->locateKeys_o (); } diff --git a/src/mail.h b/src/mail.h index 287d07d..4e6bb92 100644 --- a/src/mail.h +++ b/src/mail.h @@ -251,7 +251,7 @@ public: int encryptSignStart_o (); /** @brief Necessary crypto operations were completed successfully. */ - bool wasCryptoSuccessful_m () { return m_crypt_successful || !needs_crypto(); } + bool wasCryptoSuccessful_m () { return m_crypt_successful || !needs_crypto_m (); } /** @brief Message should be encrypted and or signed. 0: No @@ -259,7 +259,7 @@ public: 2: Sign 3: Encrypt & Sign */ - int needs_crypto (); + int needs_crypto_m () const; /** @brief wipe the plaintext from the message and encrypt attachments. * @@ -453,7 +453,7 @@ public: void appendToInlineBody (const std::string &data); /** Set the inline body as OOM body property. */ - int inlineBodyToBody (); + int inlineBodyToBody_o (); /** Get the crypt state */ CryptState cryptState () const {return m_crypt_state;} @@ -590,7 +590,7 @@ public: private: void updateCategories_o (); - void updateSigstate_o (); + void updateSigstate (); LPDISPATCH m_mailitem; LPDISPATCH m_event_sink; diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index be15eea..9191005 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -143,23 +143,12 @@ EVENT_SINK_INVOKE(MailItemEvents) { log_oom_extra ("%s:%s: Open : %p", SRCNAME, __func__, m_mail); - LPMESSAGE message; - if (g_ol_version_major < 14 && m_mail->setUUID_o ()) - { - /* In Outlook 2007 we need the uid for every - open mail to track the message in case - it is sent and crypto is required. */ - log_debug ("%s:%s: Failed to set uuid.", - SRCNAME, __func__); - delete m_mail; /* deletes this, too */ - return S_OK; - } int draft_flags = 0; if (!opt.encrypt_default && !opt.sign_default) { return S_OK; } - message = get_oom_base_message (m_object); + LPMESSAGE message = get_oom_base_message (m_object); if (!message) { log_error ("%s:%s: Failed to get message.", @@ -248,7 +237,7 @@ EVENT_SINK_INVOKE(MailItemEvents) Testing shows that Outlook always sends these three in a row */) { - if (opt.autosecure || (m_mail->needs_crypto() & 1)) + if (opt.autosecure || (m_mail->needs_crypto_m () & 1)) { /* XXX Racy race. This is a fix for crashes that happend if a resolved recipient is copied an pasted. @@ -355,7 +344,7 @@ EVENT_SINK_INVOKE(MailItemEvents) */ log_oom_extra ("%s:%s: Send : %p", SRCNAME, __func__, m_mail); - if (!m_mail->needs_crypto () && m_mail->cryptState () == Mail::NoCryptMail) + if (!m_mail->needs_crypto_m () && m_mail->cryptState () == Mail::NoCryptMail) { log_debug ("%s:%s: No crypto neccessary. Passing send for %p obj %p", SRCNAME, __func__, m_mail, m_object); @@ -370,7 +359,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } if (m_mail->cryptState () == Mail::NoCryptMail && - m_mail->needs_crypto ()) + m_mail->needs_crypto_m ()) { // First contact with a mail to encrypt update // state and oom data. @@ -626,7 +615,7 @@ EVENT_SINK_INVOKE(MailItemEvents) } if (!m_mail->isCryptoMail () && m_mail->is_forwarded_crypto_mail () && - !m_mail->needs_crypto () && m_mail->cryptState () == Mail::NoCryptMail) + !m_mail->needs_crypto_m () && m_mail->cryptState () == Mail::NoCryptMail) { /* We are sure now that while this is a forward of an encrypted * mail that the forward should not be signed or encrypted. So ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 45 ++++++++++++++++++++++++--------------------- src/mail.h | 8 ++++---- src/mailitem-events.cpp | 33 +++++++++++++-------------------- src/windowmessages.cpp | 4 ---- 4 files changed, 41 insertions(+), 49 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 22 17:09:11 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 22 Jun 2018 17:09:11 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-19-ga41e34f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via a41e34fde420cff26e2c09316259cedcbde649f2 (commit) via 746c9df891eefe4dedb2e0c13f9fa9c8eed59405 (commit) via 696419405e9bba5a2c7d8dd602a42dc7d9e80990 (commit) from b853a5a70e325c80628edf4720e3ccb6030f1860 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a41e34fde420cff26e2c09316259cedcbde649f2 Author: Andre Heinecke Date: Fri Jun 22 17:06:21 2018 +0200 Take language from Outlook instead of the system * src/oomhelp.cpp (invoke_oom_method_with_parms_type): New. Helper to allow invokes with a custom type. (invoke_oom_method_with_parms): Use it. (get_ol_ui_language): New. Read out the UI language of outlook. * src/w32-gettext.c (_nl_locale_name): Use it. * src/oomhelp.h: Update accordingly. -- It makes sense to use the same language as outlook does. Users will find anything else confusing and broken. This also makes it easier to switch languages for screenshots :-P diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp index 29fca98..b0097d0 100644 --- a/src/oomhelp.cpp +++ b/src/oomhelp.cpp @@ -1412,9 +1412,10 @@ get_oom_base_message (LPDISPATCH mailitem) return ret; } -int -invoke_oom_method_with_parms (LPDISPATCH pDisp, const char *name, - VARIANT *rVariant, DISPPARAMS *params) +static int +invoke_oom_method_with_parms_type (LPDISPATCH pDisp, const char *name, + VARIANT *rVariant, DISPPARAMS *params, + int type) { HRESULT hr; DISPID dispid; @@ -1427,7 +1428,7 @@ invoke_oom_method_with_parms (LPDISPATCH pDisp, const char *name, DISPPARAMS dispparams = {NULL, NULL, 0, 0}; hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, - DISPATCH_METHOD, params ? params : &dispparams, + type, params ? params : &dispparams, rVariant, &execpinfo, NULL); if (hr != S_OK) { @@ -1442,6 +1443,14 @@ invoke_oom_method_with_parms (LPDISPATCH pDisp, const char *name, } int +invoke_oom_method_with_parms (LPDISPATCH pDisp, const char *name, + VARIANT *rVariant, DISPPARAMS *params) +{ + return invoke_oom_method_with_parms_type (pDisp, name, rVariant, params, + DISPATCH_METHOD); +} + +int invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant) { return invoke_oom_method_with_parms (pDisp, name, rVariant, NULL); @@ -2061,3 +2070,52 @@ get_ex_major_version_for_addr (const char *mbox) return (int) version; } + +int +get_ol_ui_language () +{ + LPDISPATCH app = GpgolAddin::get_instance()->get_application(); + if (!app) + { + TRACEPOINT; + return 0; + } + + LPDISPATCH langSettings = get_oom_object (app, "LanguageSettings"); + if (!langSettings) + { + TRACEPOINT; + return 0; + } + + VARIANT var; + VariantInit (&var); + + VARIANT aVariant[1]; + DISPPARAMS dispparams; + + dispparams.rgvarg = aVariant; + dispparams.rgvarg[0].vt = VT_INT; + dispparams.rgvarg[0].intVal = 2; + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + + if (invoke_oom_method_with_parms_type (langSettings, "LanguageID", &var, + &dispparams, + DISPATCH_PROPERTYGET)) + { + TRACEPOINT; + return 0; + } + if (var.vt != VT_INT && var.vt != VT_I4) + { + TRACEPOINT; + return 0; + } + + int result = var.intVal; + + log_debug ("XXXXX %i", result); + VariantClear (&var); + return result; +} diff --git a/src/oomhelp.h b/src/oomhelp.h index c2afd4a..ac6d2bb 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -350,6 +350,9 @@ char *get_inline_body (void); or exchange is not used.*/ int get_ex_major_version_for_addr (const char *mbox); +/* Get the language code used for Outlooks UI */ +int get_ol_ui_language (void); + #ifdef __cplusplus char *get_sender_SendUsingAccount (LPDISPATCH mailitem, bool *r_is_GSuite); } diff --git a/src/w32-gettext.c b/src/w32-gettext.c index 30ff0a0..081f050 100644 --- a/src/w32-gettext.c +++ b/src/w32-gettext.c @@ -69,6 +69,8 @@ #include #include +#include + #ifdef HAVE_W32_SYSTEM # include /* List of language codes, sorted by value: @@ -787,8 +789,14 @@ _nl_locale_name (int category, const char *categoryname) if (retval != NULL && retval[0] != '\0') return retval; - /* Use native Win32 API locale ID. */ - lcid = GetThreadLocale (); + /* Prefer the Ui language of Outlook. */ + lcid = get_ol_ui_language (); + + if (!lcid) + { + /* Use native Win32 API locale ID. */ + lcid = GetThreadLocale (); + } /* Strip off the sorting rules, keep only the language part. */ langid = LANGIDFROMLCID (lcid); commit 746c9df891eefe4dedb2e0c13f9fa9c8eed59405 Author: Andre Heinecke Date: Fri Jun 22 17:05:19 2018 +0200 Remove code about compat flags * src/main.c (read_options): Remove compat flags handling. -- This was no longer used and contained the only i18n call before the "OnStartupComplete" callback. diff --git a/src/main.c b/src/main.c index e479bb0..e0d553d 100644 --- a/src/main.c +++ b/src/main.c @@ -216,7 +216,6 @@ drop_locale_dir (char *locale_dir) void read_options (void) { - static int warnings_shown; char *val = NULL; /* Set the log file first so that output from this function is @@ -333,48 +332,6 @@ read_options (void) load_extension_value ("autosecure", &val); opt.autosecure = val == NULL ? 1 : *val != '1' ? 0 : 1; xfree (val); val = NULL; - /* Note, that on purpose these flags are only Registry changeable. - The format of the entry is a string of of "0" and "1" digits; see - the switch below for a description. */ - memset (&opt.compat, 0, sizeof opt.compat); - load_extension_value ("compatFlags", &val); - if (val) - { - const char *s = val; - int i, x; - - for (s=val, i=0; *s; s++, i++) - { - x = *s == '1'; - switch (i) - { - case 0: opt.compat.no_msgcache = x; break; - case 1: opt.compat.no_pgpmime = x; break; - case 2: opt.compat.no_oom_write = x; break; - case 3: opt.compat.no_preview_info = x; break; - case 4: opt.compat.old_reply_hack = x; break; - case 5: opt.compat.auto_decrypt = x; break; - case 6: opt.compat.no_attestation = x; break; - case 7: opt.compat.use_mwfmo = x; break; - } - } - log_debug ("Note: using compatibility flags: %s", val); - } - - if (!warnings_shown) - { - char tmpbuf[512]; - - warnings_shown = 1; - if (val && *val) - { - snprintf (tmpbuf, sizeof tmpbuf, - _("Note: Using compatibility flags: %s"), val); - MessageBox (NULL, tmpbuf, _("GpgOL"), MB_ICONWARNING|MB_OK); - } - } - xfree (val); val = NULL; - } commit 696419405e9bba5a2c7d8dd602a42dc7d9e80990 Author: Andre Heinecke Date: Fri Jun 22 17:03:08 2018 +0200 Move i18n_init after the addin connecction * src/common.h (i18n_init): Expose. * src/main.c (DllMain): Don't init here. (i18n_init): No longer static. * src/gpgoladdin.cpp (GpgolAddin::OnStartupComplete): Call it. -- This ensures that the Application object is accessible when initializing i18n. diff --git a/src/common.h b/src/common.h index 177bf6a..265955c 100644 --- a/src/common.h +++ b/src/common.h @@ -148,6 +148,7 @@ int gpgol_message_box (HWND parent, const char *utf8_text, /* Show a bug message with the code. */ void gpgol_bug (HWND parent, int code); +void i18n_init (void); #define ERR_CRYPT_RESOLVER_FAILED 1 #define ERR_WANTS_SEND_MIME_BODY 2 #define ERR_WANTS_SEND_INLINE_BODY 3 diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp index 95ec7c7..b43ef6f 100644 --- a/src/gpgoladdin.cpp +++ b/src/gpgoladdin.cpp @@ -483,6 +483,8 @@ GpgolAddin::OnStartupComplete (SAFEARRAY** custom) (void)custom; TRACEPOINT; + i18n_init (); + if (!create_responder_window()) { log_error ("%s:%s: Failed to create the responder window;", diff --git a/src/main.c b/src/main.c index 2d3590e..e479bb0 100644 --- a/src/main.c +++ b/src/main.c @@ -82,7 +82,7 @@ get_crypt_random (size_t nbytes) } -static void +void i18n_init (void) { char *locale_dir; @@ -158,7 +158,6 @@ DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) /* Early initializations of our subsystems. */ if (initialize_main ()) return FALSE; - i18n_init (); } else if (reason == DLL_PROCESS_DETACH) { ----------------------------------------------------------------------- Summary of changes: src/common.h | 1 + src/gpgoladdin.cpp | 2 ++ src/main.c | 46 +------------------------------------ src/oomhelp.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++---- src/oomhelp.h | 3 +++ src/w32-gettext.c | 12 ++++++++-- 6 files changed, 79 insertions(+), 51 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 22 17:12:19 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 22 Jun 2018 17:12:19 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-21-g27e7dfb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 27e7dfb1280f314286348a661e057eef5c8ab440 (commit) via 0554e238292253dcb2d5c0dd08e723b5e1ad4ac3 (commit) from a41e34fde420cff26e2c09316259cedcbde649f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 27e7dfb1280f314286348a661e057eef5c8ab440 Author: Andre Heinecke Date: Fri Jun 22 17:10:32 2018 +0200 Enable async crypto again (for now) * src/mail.cpp (DO_ASYNC_CRYPTO): Define. -- This works soo much better. But I still have not figured out why it crashes reliably for some users. :-/ diff --git a/src/mail.cpp b/src/mail.cpp index 11266e5..0e94871 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -70,6 +70,8 @@ static Mail *s_last_mail; #define COPYBUFSIZE (8 * 1024) +#define DO_ASYNC_CRYPTO + Mail::Mail (LPDISPATCH mailitem) : m_mailitem(mailitem), m_processed(false), commit 0554e238292253dcb2d5c0dd08e723b5e1ad4ac3 Author: Andre Heinecke Date: Fri Jun 22 17:09:27 2018 +0200 Note mbox in WKS message * src/wks-helper.cpp (WKSHelper::notify): Note for which mbox the message applies. -- With multiple accounts this can otherwise be confusing. We also avoid the word "domain" which is too technical for most. diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index 9799576..bf03425 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -400,12 +400,15 @@ WKSHelper::notify (const char *cBox) const if (state == NeedsPublish) { + char *buf; + gpgrt_asprintf (&buf, _("A Pubkey directory is available for the address:\n\n" + "\t%s\n\n" + "Register your Pubkey in that directory to make\n" + "it easy for others to send you encrypted mail.\n\n" + "It's secure and free!\n\n" + "Register automatically?"), mbox); if (gpgol_message_box (get_active_hwnd (), - _("A Pubkey directory is available for your domain.\n\n" - "Register your Pubkey in that directory to make\n" - "it easy for others to send you encrypted mail.\n\n" - "It's secure and free!\n\n" - "Register automatically?"), + buf, _("GpgOL: Pubkey directory available!"), MB_YESNO) == IDYES) { start_publish (mbox); @@ -414,6 +417,7 @@ WKSHelper::notify (const char *cBox) const { update_state (mbox, PublishDenied); } + xfree (buf); return; } if (state == ConfirmationSeen) ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 2 ++ src/wks-helper.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 22 17:28:18 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 22 Jun 2018 17:28:18 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-22-g1b9eb2a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 1b9eb2a608ea5053575298655ddb9c12837d2b1a (commit) from 27e7dfb1280f314286348a661e057eef5c8ab440 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1b9eb2a608ea5053575298655ddb9c12837d2b1a Author: Andre Heinecke Date: Fri Jun 22 17:27:33 2018 +0200 Fix passing std::string to asprintf * src/wks-helper.cpp (WKSHelper::notifiy): Fix asprintf call. -- ooops. diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index bf03425..79d2de2 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -406,7 +406,7 @@ WKSHelper::notify (const char *cBox) const "Register your Pubkey in that directory to make\n" "it easy for others to send you encrypted mail.\n\n" "It's secure and free!\n\n" - "Register automatically?"), mbox); + "Register automatically?"), mbox.c_str ()); if (gpgol_message_box (get_active_hwnd (), buf, _("GpgOL: Pubkey directory available!"), MB_YESNO) == IDYES) ----------------------------------------------------------------------- Summary of changes: src/wks-helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 26 11:19:04 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 26 Jun 2018 11:19:04 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-27-gfb09b26 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via fb09b2671359ce56b5c17afb8c7315cd0c63e088 (commit) via 63047f81e06b1becbead7e361691999063d1dfee (commit) via 3c04640f8cc815aa49b373cc2545652afe194fcf (commit) via 74a6555e2e5ddce8ad64a406e15427935a38a99a (commit) via 60eb684fa67777ab07c10fc791328794017c97d0 (commit) from 1b9eb2a608ea5053575298655ddb9c12837d2b1a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fb09b2671359ce56b5c17afb8c7315cd0c63e088 Author: Andre Heinecke Date: Tue Jun 26 11:17:24 2018 +0200 Improve state handling of WKS Mails * src/wks-helper.cpp: Add new PublishInProgress state. This avoids the possibility of multiple notifications due to the late advancement out of the needspublish state. diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index b11d7cb..7edb0ea 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -324,8 +324,14 @@ WKSHelper::load () const } WKSState state = (WKSState) strtol (states[0].c_str (), nullptr, 10); - time_t update_time = (time_t) strtol (states[1].c_str (), nullptr, 10); + if (state == PublishInProgress) + { + /* Probably an error during the last publish. Let's start again. */ + update_state (mbox, NotChecked, false); + continue; + } + time_t update_time = (time_t) strtol (states[1].c_str (), nullptr, 10); update_state (mbox, state, false); update_last_checked (mbox, update_time, false); } @@ -437,6 +443,7 @@ WKSHelper::start_publish (const std::string &mbox) const log_debug ("%s:%s: Start publish for '%s'", SRCNAME, __func__, mbox.c_str ()); + update_state (mbox, PublishInProgress); const auto key = GpgME::Key::locate (mbox.c_str ()); if (key.isNull ()) @@ -509,6 +516,8 @@ WKSHelper::start_publish (const std::string &mbox) const "your provider to finish the registration."), _("GpgOL: Registration request sent!"), MB_OK); } + + update_state (mbox, RequestSent); return; } diff --git a/src/wks-helper.h b/src/wks-helper.h index be3ae7b..db4a776 100644 --- a/src/wks-helper.h +++ b/src/wks-helper.h @@ -52,6 +52,7 @@ public: IsPublished, /* <-- WKS is supported for this address and published */ ConfirmationSeen, /* A confirmation request was seen for this mail addres. */ NeedsUpdate, /* <-- Not yet implemeted. */ + PublishInProgress, /* <-- Publishing is currently in progress. */ RequestSent, /* <-- A publishing request has been sent. */ PublishDenied, /* <-- A user denied publishing. */ ConfirmationSent, /* <-- The confirmation response was sent. */ commit 63047f81e06b1becbead7e361691999063d1dfee Author: Andre Heinecke Date: Tue Jun 26 11:17:00 2018 +0200 Minor improvement to german string -- diff --git a/po/de.po b/po/de.po index 83391a4..05e6c66 100644 --- a/po/de.po +++ b/po/de.po @@ -718,7 +718,7 @@ msgid "" "You might receive a confirmation challenge from\n" "your provider to finish the registration." msgstr "" -"Es ist m?glich das ihnen ihr Mailprovider noch eine Best?tigungs-\n" +"Es ist m?glich das ihnen ihr Mailprovider noch eine Best?tigungs-" "Anfrage sendet um die Eintragung abzuschlie?en." #: src/wks-helper.cpp:506 commit 3c04640f8cc815aa49b373cc2545652afe194fcf Author: Andre Heinecke Date: Tue Jun 26 11:15:28 2018 +0200 Ignore propchanges on custom mails * src/mail.h (Mail::hasOverrideMimeData): New. * src/mailitem-events.cpp (PropertyChange): Ignore changes for mails with override mime data. * src/wks-helper.cpp (WKSHelper::send_mail): Set override MIME data earlier. -- This removes auto key locates for our custom WKS Mails. diff --git a/src/mail.h b/src/mail.h index 4e6bb92..c5ea011 100644 --- a/src/mail.h +++ b/src/mail.h @@ -510,6 +510,7 @@ public: /** Get the mime data that should be used when sending. */ std::string get_override_mime_data () const { return m_mime_data; } + bool hasOverrideMimeData() const { return !m_mime_data.empty(); } /** Set if this is a forward of a crypto mail. */ void setIsForwardedCryptoMail (bool value) { m_is_forwarded_crypto_mail = value; } diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 41c1376..375a251 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -232,6 +232,11 @@ EVENT_SINK_INVOKE(MailItemEvents) { break; } + if (m_mail->hasOverrideMimeData()) + { + /* This is a mail created by us. Ignore propchanges. */ + break; + } if (!wcscmp (prop_name, L"To") /* || !wcscmp (prop_name, L"BCC") || !wcscmp (prop_name, L"CC") diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp index 79d2de2..b11d7cb 100644 --- a/src/wks-helper.cpp +++ b/src/wks-helper.cpp @@ -598,6 +598,23 @@ WKSHelper::send_mail (const std::string &mimeData) const return -1; } + /* Now we have a problem. The created LPDISPATCH pointer has + a different value then the one with which we saw the ItemLoad + event. But we want to get the mail object. So,.. surpise + a Hack! :-) */ + auto last_mail = Mail::getLastMail (); + + if (!Mail::isValidPtr (last_mail)) + { + log_error ("%s:%s: Invalid last mail %p.", + SRCNAME, __func__, last_mail); + return -1; + } + /* Adding to / Subject etc already leads to changes and events so + we set up the state before this. */ + last_mail->setOverrideMIMEData (mimeData); + last_mail->setCryptState (Mail::NeedsSecondAfterWrite); + if (put_oom_string (mail, "Subject", subject.c_str ())) { TRACEPOINT; @@ -621,21 +638,6 @@ WKSHelper::send_mail (const std::string &mimeData) const } gpgol_release (account); - /* Now we have a problem. The created LPDISPATCH pointer has - a different value then the one with which we saw the ItemLoad - event. But we want to get the mail object. So,.. surpise - a Hack! :-) */ - auto last_mail = Mail::getLastMail (); - - if (!Mail::isValidPtr (last_mail)) - { - log_error ("%s:%s: Invalid last mail %p.", - SRCNAME, __func__, last_mail); - return -1; - } - last_mail->setOverrideMIMEData (mimeData); - last_mail->setCryptState (Mail::NeedsSecondAfterWrite); - if (invoke_oom_method (mail, "Save", nullptr)) { // Should not happen. commit 74a6555e2e5ddce8ad64a406e15427935a38a99a Author: Andre Heinecke Date: Tue Jun 26 11:05:34 2018 +0200 Improve handling of UID origin * src/mail.cpp (Mail::getCryptoDetails_o, Mail::updateSigstate): Treat WKD origin as "shortcut to level 2. -- As described on https://wiki.gnupg.org/AutomatedEncryption we treat WKD already as a shortcut to level 2 as we have an HTTPS secure indication from the provider that the key matches the mail address. This sets the green bar "verified sender" already for such mails, because the senders address was verified through the provider. To protect against phishing attacks this does not help but for these Level 3 and 4 are required. diff --git a/src/mail.cpp b/src/mail.cpp index 556d7eb..2418544 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1931,7 +1931,16 @@ Mail::updateSigstate () { m_is_signed = true; m_uid = get_uid_for_sender (sig.key(), sender.c_str()); - if (m_uid.isNull() || (sig.validity() != Signature::Validity::Marginal && + + if (m_uid.origin() == GpgME::Key::OriginWKD && + (sig.validity() == Signature::Validity::Unknown || + sig.validity() == Signature::Validity::Marginal)) + { + // WKD is a shortcut to Level 2 trust. + log_debug ("%s:%s: Unknown or marginal from WKD -> Level 2", + SRCNAME, __func__); + } + else if (m_uid.isNull() || (sig.validity() != Signature::Validity::Marginal && sig.validity() != Signature::Validity::Full && sig.validity() != Signature::Validity::Ultimate)) { @@ -1939,7 +1948,7 @@ Mail::updateSigstate () the UID needs to match.*/ continue; } - if (sig.validity() == Signature::Validity::Marginal) + else if (sig.validity() == Signature::Validity::Marginal) { const auto tofu = m_uid.tofuInfo(); if (!tofu.isNull() && @@ -1954,8 +1963,8 @@ Mail::updateSigstate () continue; } } - log_debug ("%s:%s: Classified sender as verified uid validity: %i", - SRCNAME, __func__, m_uid.validity()); + log_debug ("%s:%s: Classified sender as verified uid validity: %i origin: %i", + SRCNAME, __func__, m_uid.validity(), m_uid.origin()); m_sig = sig; m_is_valid = true; return; @@ -2391,6 +2400,10 @@ Mail::getCryptoDetails_o () message = buf; xfree (buf); } + else if (level == 2 && m_uid.origin () == GpgME::Key::OriginWKD) + { + message = _("The mail provider of the recipient served this key."); + } else if (level == 2 && m_uid.tofuInfo ().isNull ()) { /* Marginal trust through pgp only */ commit 60eb684fa67777ab07c10fc791328794017c97d0 Author: Andre Heinecke Date: Tue Jun 26 11:03:18 2018 +0200 Fix potential crash in do autosecure * src/mail.cpp (Mail::setDoAutosecure_m): Return if msg is not found. -- This happens for example if we programatically created a mail and then set the "to" diff --git a/src/mail.cpp b/src/mail.cpp index 0e94871..556d7eb 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -3279,6 +3279,7 @@ Mail::setDoAutosecure_m (bool value) if (!msg) { TRACEPOINT; + return; } /* We need to set a uuid so that autosecure can be disabled manually */ ----------------------------------------------------------------------- Summary of changes: po/de.po | 2 +- src/mail.cpp | 22 ++++++++++++++++++---- src/mail.h | 1 + src/mailitem-events.cpp | 5 +++++ src/wks-helper.cpp | 43 +++++++++++++++++++++++++++---------------- src/wks-helper.h | 1 + 6 files changed, 53 insertions(+), 21 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 26 13:03:45 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 26 Jun 2018 13:03:45 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-28-g690c8fe Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 690c8fe80a15991be6a9c636967b12ac47a7a110 (commit) from fb09b2671359ce56b5c17afb8c7315cd0c63e088 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 690c8fe80a15991be6a9c636967b12ac47a7a110 Author: Andre Heinecke Date: Tue Jun 26 13:03:03 2018 +0200 Add i18n noops for config dialog * src/addin-options.cpp (i18n_noops): New. Strings to be used from the config dialog. diff --git a/src/addin-options.cpp b/src/addin-options.cpp index 160a34a..bc36911 100644 --- a/src/addin-options.cpp +++ b/src/addin-options.cpp @@ -31,6 +31,13 @@ #include #include + +__attribute__((__unused__)) static char const * +i18n_noops[] = { + N_("GnuPG System"), + N_("Enable the S/MIME support"), +}; + /* To avoid writing a dialog template for each language we use gettext for the labels and hope that there is enough space in the dialog to fit the longest translation.. */ ----------------------------------------------------------------------- Summary of changes: src/addin-options.cpp | 7 +++++++ 1 file changed, 7 insertions(+) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 26 14:47:52 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 26 Jun 2018 14:47:52 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-30-gb800b5c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via b800b5ca1ef64de3d18864781956cec56d1f4136 (commit) via 57a81b6b6f63501be979b3ee9dbeef800f254e48 (commit) from 690c8fe80a15991be6a9c636967b12ac47a7a110 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b800b5ca1ef64de3d18864781956cec56d1f4136 Author: Andre Heinecke Date: Tue Jun 26 14:46:49 2018 +0200 Enable auto-key-retrieve if autoresolve is set * src/parsecontroller.cpp (ParseController::parse): Enable auto-key-retrieve if autoresolve is set to true. -- With autoresolve we do network lookups already so it makes sense to reuse the option here. diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 5adada8..d61fc69 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -305,6 +305,13 @@ ParseController::parse() xfree (buf); return; } + + /* Maybe a different option for this ? */ + if (opt.autoresolve) + { + ctx->setFlag("auto-key-retrieve", "1"); + } + ctx->setArmor(true); if (!m_sender.empty()) commit 57a81b6b6f63501be979b3ee9dbeef800f254e48 Author: Andre Heinecke Date: Tue Jun 26 14:43:10 2018 +0200 Fix bring to foreground logic * src/mail.cpp (do_crypt): Bring to foreground with delay. * src/windowmessages.cpp (gpgol_window_proc): Don't sleep in the UI thread. -- Sleeping in the UI thread to wait for the UI thread to do something (close a window) was stupid. GnuPG-Bug-Id: T3771 diff --git a/src/mail.cpp b/src/mail.cpp index 2418544..ead39ec 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -927,7 +927,7 @@ do_crypt (LPVOID arg) See GnuPG-Bug-Id: T3732 */ - do_in_ui_thread_async (BRING_TO_FRONT, nullptr); + do_in_ui_thread_async (BRING_TO_FRONT, nullptr, 250); log_debug ("%s:%s: crypto thread for %p finished", SRCNAME, __func__, arg); return 0; diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp index 83d0cfd..c371886 100644 --- a/src/windowmessages.cpp +++ b/src/windowmessages.cpp @@ -155,9 +155,6 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } case (BRING_TO_FRONT): { - // We want to avoid a race where the mail window - // was still the active window. - Sleep (250); HWND wnd = get_active_hwnd (); if (wnd) { ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 2 +- src/parsecontroller.cpp | 7 +++++++ src/windowmessages.cpp | 3 --- 3 files changed, 8 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jun 26 16:26:21 2018 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Tue, 26 Jun 2018 16:26:21 +0200 Subject: [git] GpgOL - branch, master, updated. gpgol-2.2.0-31-g87e96e7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via 87e96e7ee79ee837065883bb5434c9839024035f (commit) from b800b5ca1ef64de3d18864781956cec56d1f4136 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 87e96e7ee79ee837065883bb5434c9839024035f Author: Andre Heinecke Date: Tue Jun 26 16:18:38 2018 +0200 Make it possible to move decrypted mails * src/Makefile.am: Add folder-events.cpp * src/eventsinks.h (install_FolderEvents_sink), (detach_FolderEvents_sink): New. * src/folder-events.cpp: New event handler. * src/mail.cpp (s_folder_events_map): New map to track registered handlers. (Mail::isAboutToBeMoved, Mail::setIsAboutToBeMoved): New. (Mail::installFolderEventHandler_o): New. (Mail::closeAllMails_o): detach folder handler. * src/mail.h: Update accordingly. * src/mailitem-events.cpp (Write): Pass if mail is about to be moved. * src/oomhelp.h (IID_FolderEvents): New. -- Finally! While the application has the item copy events the folder has a before item move event. To catch this we register an event handler for each folder in which a mail was decrypted. If a crypto mail is then about to be moved we close it with discard changes to discard the plaintext, then we pass the write event to allow the move. Works flawlessly in the first tests. GnuPG-Bug-Id: T3459 GnuPG-Bug-Id: T3956 GnuPG-Bug-Id: T3418 diff --git a/src/Makefile.am b/src/Makefile.am index 2e6f529..161bd88 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ gpgol_SOURCES = \ explorer-events.cpp \ explorers-events.cpp \ filetype.c filetype.h \ + folder-events.cpp \ gmime-table-private.h \ gpgoladdin.cpp gpgoladdin.h \ gpgol.def \ diff --git a/src/eventsinks.h b/src/eventsinks.h index 96b067f..1508a62 100644 --- a/src/eventsinks.h +++ b/src/eventsinks.h @@ -30,4 +30,6 @@ LPDISPATCH install_ExplorerEvents_sink (LPDISPATCH obj); void detach_ExplorerEvents_sink (LPDISPATCH obj); LPDISPATCH install_ExplorersEvents_sink (LPDISPATCH obj); void detach_ExplorersEvents_sink (LPDISPATCH obj); +LPDISPATCH install_FolderEvents_sink (LPDISPATCH obj); +void detach_FolderEvents_sink (LPDISPATCH obj); #endif // EVENTSINKS_H diff --git a/src/folder-events.cpp b/src/folder-events.cpp new file mode 100644 index 0000000..8c765c1 --- /dev/null +++ b/src/folder-events.cpp @@ -0,0 +1,135 @@ +/* folder-events.cpp - Event handling for a folder. + * Copyright (C) 2018 Intevation GmBH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +/* The event handler classes defined in this file follow the + general pattern that they implment the IDispatch interface + through the eventsink macros and handle event invocations + in their invoke methods. +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "eventsink.h" +#include "ocidl.h" +#include "common.h" +#include "oomhelp.h" +#include "mail.h" + +/* Folder Events */ +BEGIN_EVENT_SINK(FolderEvents, IDispatch) +EVENT_SINK_DEFAULT_CTOR(FolderEvents) +EVENT_SINK_DEFAULT_DTOR(FolderEvents) +typedef enum + { + BeforeItemMove = 0xFBA9, + BeforeFolderMove = 0xFBA8, + } FolderEvent; + +EVENT_SINK_INVOKE(FolderEvents) +{ + USE_INVOKE_ARGS + switch(dispid) + { + case BeforeItemMove: + { + log_oom_extra ("%s:%s: Item Move in folder: %p", + SRCNAME, __func__, this); + + /* Parameters should be + disp item Represents the Outlook item that is to be moved or deleted. + disp folder Represents the folder to which the item is being moved. + If null the message will be deleted. + bool cancel Move should be canceled. + + Remember that the order is inverted. */ + if (!(parms->cArgs == 3 && parms->rgvarg[1].vt == (VT_DISPATCH) && + parms->rgvarg[2].vt == (VT_DISPATCH) && + parms->rgvarg[0].vt == (VT_BOOL | VT_BYREF))) + { + log_error ("%s:%s: Invalid args.", + SRCNAME, __func__); + break; + } + + if (!parms->rgvarg[1].pdispVal) + { + log_oom_extra ("%s:%s: Passing delete", + SRCNAME, __func__); + break; + } + + LPDISPATCH mailitem = parms->rgvarg[2].pdispVal; + + char *name = get_object_name (mailitem); + if (!name || strcmp (name, "_MailItem")) + { + log_debug ("%s:%s: move is not about a mailitem.", + SRCNAME, __func__); + xfree (name); + break; + } + xfree (name); + + char *uid = get_unique_id (mailitem, 0, nullptr); + if (!uid) + { + LPMESSAGE msg = get_oom_base_message (mailitem); + uid = mapi_get_uid (msg); + gpgol_release (msg); + if (!uid) + { + log_debug ("%s:%s: Failed to get uid for %p", + SRCNAME, __func__, mailitem); + break; + } + } + + Mail *mail = Mail::getMailForUUID (uid); + xfree (uid); + if (!mail) + { + log_error ("%s:%s: Failed to find mail for uuid", + SRCNAME, __func__); + break; + } + if (mail->isCryptoMail ()) + { + log_debug ("%s:%s: Detected move of crypto mail. %p Closing", + SRCNAME, __func__, mail); + + mail->setIsAboutToBeMoved (true); + if (Mail::close (mail)) + { + log_error ("%s:%s: Failed to close.", + SRCNAME, __func__); + break; + } + } + } + default: + break; +#if 0 + log_oom_extra ("%s:%s: Unhandled Event: %lx \n", + SRCNAME, __func__, dispid); +#endif + } + return S_OK; +} +END_EVENT_SINK(FolderEvents, IID_FolderEvents) diff --git a/src/mail.cpp b/src/mail.cpp index ead39ec..cb0c9e3 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -61,6 +61,7 @@ using namespace GpgME; static std::map s_mail_map; static std::map s_uid_map; +static std::map s_folder_events_map; static std::set uids_searched; GPGRT_LOCK_DEFINE (mail_map_lock); @@ -101,7 +102,8 @@ Mail::Mail (LPDISPATCH mailitem) : m_disable_att_remove_warning(false), m_manual_crypto_opts(false), m_first_autosecure_check(true), - m_locate_count(0) + m_locate_count(0), + m_is_about_to_be_moved(false) { if (getMailForItem (mailitem)) { @@ -1365,6 +1367,8 @@ Mail::parsing_done() removeOurAttachments_o (); } + installFolderEventHandler_o (); + log_debug ("%s:%s: Delayed invalidate to update sigstate.", SRCNAME, __func__); CloseHandle(CreateThread (NULL, 0, delayed_invalidate_ui, (LPVOID) this, 0, @@ -1621,6 +1625,11 @@ Mail::closeAllMails_o () } } } + for (auto fit = s_folder_events_map.begin(); fit != s_folder_events_map.end(); ++fit) + { + detach_FolderEvents_sink (fit->second); + } + s_folder_events_map.clear(); return err; } int @@ -3315,3 +3324,55 @@ Mail::setDoAutosecure_m (bool value) set_gpgol_draft_info_flags (msg, value ? 3 : 0); gpgoladdin_invalidate_ui(); } + +void +Mail::installFolderEventHandler_o() +{ + TRACEPOINT; + LPDISPATCH folder = get_oom_object (m_mailitem, "Parent"); + + if (!folder) + { + TRACEPOINT; + return; + } + + char *objName = get_object_name (folder); + if (!objName || strcmp (objName, "MAPIFolder")) + { + log_debug ("%s:%s: Mail %p parent is not a mapi folder.", + SRCNAME, __func__, m_mailitem); + xfree (objName); + gpgol_release (folder); + return; + } + xfree (objName); + + char *path = get_oom_string (folder, "FullFolderPath"); + if (!path) + { + TRACEPOINT; + path = get_oom_string (folder, "FolderPath"); + } + if (!path) + { + log_error ("%s:%s: Mail %p parent has no folder path.", + SRCNAME, __func__, m_mailitem); + gpgol_release (folder); + return; + } + + std::string strPath (path); + xfree (path); + + if (s_folder_events_map.find (strPath) == s_folder_events_map.end()) + { + log_error ("%s:%s: Install folder events watcher for %s.", + SRCNAME, __func__, strPath.c_str()); + install_FolderEvents_sink (folder); + s_folder_events_map.insert (std::make_pair (strPath, folder)); + } + + /* Folder already registered */ + gpgol_release (folder); +} diff --git a/src/mail.h b/src/mail.h index c5ea011..c6ecd2c 100644 --- a/src/mail.h +++ b/src/mail.h @@ -589,6 +589,13 @@ public: */ void setDoAutosecure_m (bool value); + /* Install an event handler for the folder of this mail. */ + void installFolderEventHandler_o (); + + /* Marker for a "Move" of this mail */ + bool isAboutToBeMoved () { return m_is_about_to_be_moved; } + void setIsAboutToBeMoved (bool value) { m_is_about_to_be_moved = value; } + private: void updateCategories_o (); void updateSigstate (); @@ -636,5 +643,6 @@ private: bool m_manual_crypto_opts; /* Crypto options (sign/encrypt) have been set manually. */ bool m_first_autosecure_check; /* This is the first autoresolve check */ int m_locate_count; /* The number of key locates pending for this mail. */ + bool m_is_about_to_be_moved; }; #endif // MAIL_H diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index 375a251..ab100c5 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -555,6 +555,13 @@ EVENT_SINK_INVOKE(MailItemEvents) break; } + if (m_mail->isAboutToBeMoved()) + { + log_debug ("%s:%s: Mail is about to be moved. Passing write for %p", + SRCNAME, __func__, m_mail); + break; + } + if (m_mail->isCryptoMail () && !m_mail->needsSave ()) { Mail *last_mail = Mail::getLastMail (); diff --git a/src/oomhelp.h b/src/oomhelp.h index ac6d2bb..8b8c7a4 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -62,6 +62,8 @@ DEFINE_GUID(IID_IConnectionPointContainer, DEFINE_GUID(IID_IPictureDisp, 0x7bf80981, 0xbf32, 0x101a, 0x8b, 0xbb, 0x00, 0xaa, 0x00, 0x30, 0x0c, 0xab); +DEFINE_GUID(IID_FolderEvents, 0x000630F7, 0x0000, 0x0000, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); DEFINE_GUID(IID_ApplicationEvents, 0x0006304E, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); DEFINE_GUID(IID_ExplorerEvents, 0x0006300F, 0x0000, 0x0000, ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 1 + src/eventsinks.h | 2 + src/folder-events.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mail.cpp | 63 +++++++++++++++++++++- src/mail.h | 8 +++ src/mailitem-events.cpp | 7 +++ src/oomhelp.h | 2 + 7 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 src/folder-events.cpp hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 27 11:22:00 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 27 Jun 2018 11:22:00 +0200 Subject: [git] GPGME - branch, ben/export-keys, created. gpgme-1.11.1-65-g14cbbb3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/export-keys has been created at 14cbbb3d702ba6d2dabd0a5cf4025e9101c5c2bd (commit) - Log ----------------------------------------------------------------- commit 14cbbb3d702ba6d2dabd0a5cf4025e9101c5c2bd Author: Ben McGinnes Date: Wed Jun 27 19:16:29 2018 +1000 python bindings: export secret keys * The holy grail: a function to export secret keys. * GPGME will still invoke pinentry and gpg-agent as usual to authorise the export. * Mostly similar to the two previous export functions for public keys except that it will return None if the result had a length of zero bytes. Meaning that the difference between the specified pattern (if any) not matching available keys and an incorrect passphrase is not able to be determined from this function (or the underlying one for that matter). Signed-off-by: Ben McGinnes diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 86a62b5..d1376da 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -611,7 +611,7 @@ class Context(GpgmeWrapper): Raises: GPGMEError -- as signaled by the underlying library. -""" + """ data = Data() mode = gpgme.GPGME_EXPORT_MODE_MINIMAL try: @@ -623,6 +623,47 @@ class Context(GpgmeWrapper): return result + def key_export_secret(self, pattern=None): + """Export secret keys. + + Exports secret keys matching the pattern specified. If no + pattern is specified then exports or attempts to export all + available secret keys. + + IMPORTANT: Each secret key to be exported will prompt for its + passphrase via an invocation of pinentry and gpg-agent. If the + passphrase is not entered or does not match then no data will be + exported. This is the same result as when specifying a pattern + that is not matched by the available keys. + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + + Returns: + -- On success a key block containing one or more OpenPGP + secret keys in either ASCII armoured or binary format + as determined by the Context(). + -- On failure while not raising an exception, returns None. + + Raises: + GPGMEError -- as signaled by the underlying library. + """ + data = Data() + mode = gpgme.GPGME_EXPORT_MODE_SECRET + try: + self.op_export(pattern, mode, data) + data.seek(0, os.SEEK_SET) + sk_result = data.read() + except GPGMEError as e: + sk_result = e + + if len(sk_result) > 0: + result = sk_result + else: + result = None + + return result + def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, source=None): commit 870c317120e08d3f606c6c5675d559e1d457290d Author: Ben McGinnes Date: Wed Jun 27 18:51:09 2018 +1000 python bindings: export public keys * Added functions for exporting public keys to gpg.core in both complete form and in minimised form. * Rather than letting people need to worry about the export modes we are simply separating the functions as people would be more familiar with from the command line usage anyway. * Functions added for Context are: ctx.key_export_minimal and ctx.key_export as the default or full export. Signed-off-by: Ben McGinnes diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 8f2e9d8..86a62b5 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -537,7 +537,7 @@ class Context(GpgmeWrapper): managed to run the function without any arguments, while an argument of None triggers the first NODATA of errors.GPGME in the - exception. + exception. """ try: self.op_import(data) @@ -566,6 +566,63 @@ class Context(GpgmeWrapper): return import_result + def key_export(self, pattern=None): + """Export keys. + + Exports public keys matching the pattern specified. If no + pattern is specified then exports all available keys. + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + + Returns: + -- A key block containing one or more OpenPGP keys in + either ASCII armoured or binary format as determined + by the Context(). + + Raises: + GPGMEError -- as signaled by the underlying library. + """ + data = Data() + mode = 0 + try: + self.op_export(pattern, mode, data) + data.seek(0, os.SEEK_SET) + result = data.read() + except GPGMEError as e: + result = e + + return result + + def key_export_minimal(self, pattern=None): + """Export keys. + + Exports public keys matching the pattern specified in a + minimised format. If no pattern is specified then exports all + available keys. + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + + Returns: + -- A key block containing one or more minimised OpenPGP + keys in either ASCII armoured or binary format as + determined by the Context(). + + Raises: + GPGMEError -- as signaled by the underlying library. +""" + data = Data() + mode = gpgme.GPGME_EXPORT_MODE_MINIMAL + try: + self.op_export(pattern, mode, data) + data.seek(0, os.SEEK_SET) + result = data.read() + except GPGMEError as e: + result = e + + return result + def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, source=None): ----------------------------------------------------------------------- hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 27 12:15:11 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 27 Jun 2018 12:15:11 +0200 Subject: [git] GPGME - branch, ben/export-keys, updated. gpgme-1.11.1-66-gcd03423 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/export-keys has been updated via cd03423b8ffb0a70adb878ad9f72ebdd28d71a7d (commit) from 14cbbb3d702ba6d2dabd0a5cf4025e9101c5c2bd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cd03423b8ffb0a70adb878ad9f72ebdd28d71a7d Author: Ben McGinnes Date: Wed Jun 27 20:12:27 2018 +1000 python bindings examples: three export scripts * Example of default exporting keys. * Example of exporting minimised keys. * Example of exporting secret keys to a file with correct permissions. Signed-off-by: Ben McGinnes diff --git a/lang/python/examples/howto/export-key.py b/lang/python/examples/howto/export-key.py new file mode 100755 index 0000000..41be64f --- /dev/null +++ b/lang/python/examples/howto/export-key.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export(pattern=logrus) +except: + result = c.key_export(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) +else: + pass diff --git a/lang/python/examples/howto/export-minimised-key.py b/lang/python/examples/howto/export-minimised-key.py new file mode 100755 index 0000000..d28b1cb --- /dev/null +++ b/lang/python/examples/howto/export-minimised-key.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys in minimised form. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export_minimal(pattern=logrus) +except: + result = c.key_export_minimal(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) +else: + pass diff --git a/lang/python/examples/howto/export-secret-key.py b/lang/python/examples/howto/export-secret-key.py new file mode 100755 index 0000000..8bbe409 --- /dev/null +++ b/lang/python/examples/howto/export-secret-key.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os +import os.path +import sys + +print(""" +This script exports one or more secret keys. + +The gpg-agent and pinentry are invoked to authorise the export. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export_secret(pattern=logrus) +except: + result = c.key_export_secret(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + os.chmod(keyfile, 0o600) +else: + pass ----------------------------------------------------------------------- Summary of changes: .../howto/{add-userid.py => export-key.py} | 43 +++++++++++++-------- .../{add-userid.py => export-minimised-key.py} | 43 +++++++++++++-------- .../{revoke-userid.py => export-secret-key.py} | 45 ++++++++++++++-------- 3 files changed, 84 insertions(+), 47 deletions(-) copy lang/python/examples/howto/{add-userid.py => export-key.py} (59%) copy lang/python/examples/howto/{add-userid.py => export-minimised-key.py} (59%) copy lang/python/examples/howto/{revoke-userid.py => export-secret-key.py} (56%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jun 27 17:53:03 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Wed, 27 Jun 2018 17:53:03 +0200 Subject: [git] GPGME - branch, ben/export-keys, updated. gpgme-1.11.1-68-g4bbe247 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/export-keys has been updated via 4bbe247c845795e2bb09509c40a8472a910e907d (commit) via 483de0330ddcb71a94a7964e31241d7309f6c3f5 (commit) from cd03423b8ffb0a70adb878ad9f72ebdd28d71a7d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4bbe247c845795e2bb09509c40a8472a910e907d Author: Ben McGinnes Date: Thu Jun 28 01:50:56 2018 +1000 python bindings: import example * Added an example script for importing a key from a file (either ASCII armoured or not). diff --git a/lang/python/examples/howto/import-key.py b/lang/python/examples/howto/import-key.py new file mode 100755 index 0000000..56cfe25 --- /dev/null +++ b/lang/python/examples/howto/import-key.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 3: + keyfile = sys.argv[1] + homedir = sys.argv[2] +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to import the key(s) from: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +if os.path.isfile(keyfile) is True: + with open(keyfile, "rb") as f: + incoming = f.read() + result = c.key_import(incoming) +else: + result = None + +if result is not None and hasattr(result, "considered") is False: + print(result) +elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" +The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} +Number of new secret keys: {5} + Number of unchanged keys: {6} + +The key IDs for all considered keys were: +""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") +elif result is None: + print("You must specify a key file to import.") commit 483de0330ddcb71a94a7964e31241d7309f6c3f5 Author: Ben McGinnes Date: Thu Jun 28 00:57:37 2018 +1000 python bindings: export public keys * Updated key_export and key_export_minimal to return None where a pattern matched no keys in a manner simnilar to the possible result of key_export_secret. diff --git a/lang/python/src/core.py b/lang/python/src/core.py index d1376da..f8e0c60 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -578,7 +578,8 @@ class Context(GpgmeWrapper): Returns: -- A key block containing one or more OpenPGP keys in either ASCII armoured or binary format as determined - by the Context(). + by the Context(). If there are no matching keys it + returns None. Raises: GPGMEError -- as signaled by the underlying library. @@ -588,9 +589,14 @@ class Context(GpgmeWrapper): try: self.op_export(pattern, mode, data) data.seek(0, os.SEEK_SET) - result = data.read() + pk_result = data.read() except GPGMEError as e: - result = e + pk_result = e + + if len(pk_result) > 0: + result = pk_result + else: + result = None return result @@ -607,7 +613,8 @@ class Context(GpgmeWrapper): Returns: -- A key block containing one or more minimised OpenPGP keys in either ASCII armoured or binary format as - determined by the Context(). + determined by the Context(). If there are no matching + keys it returns None. Raises: GPGMEError -- as signaled by the underlying library. @@ -617,9 +624,14 @@ class Context(GpgmeWrapper): try: self.op_export(pattern, mode, data) data.seek(0, os.SEEK_SET) - result = data.read() + pk_result = data.read() except GPGMEError as e: - result = e + pk_result = e + + if len(pk_result) > 0: + result = pk_result + else: + result = None return result ----------------------------------------------------------------------- Summary of changes: .../howto/{export-key.py => import-key.py} | 56 ++++++++++++++-------- lang/python/src/core.py | 24 +++++++--- 2 files changed, 55 insertions(+), 25 deletions(-) copy lang/python/examples/howto/{export-key.py => import-key.py} (58%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 28 10:04:58 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 28 Jun 2018 10:04:58 +0200 Subject: [git] GPGME - branch, ben/howto-dita, updated. gpgme-1.11.1-16-gdda54cc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/howto-dita has been updated via dda54cc851490be045832d5ee0b03be082529d17 (commit) from 34308fe1fc45cc8ea1f809c54168f418a146f0ca (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dda54cc851490be045832d5ee0b03be082529d17 Author: Ben McGinnes Date: Thu Jun 28 18:02:43 2018 +1000 python bindings howto: dita version * Drafts of instructions for exporting public and secret keys ready, along in addition to the code. diff --git a/lang/python/docs/dita/gpgme-python-howto-footer.xhtml b/lang/python/docs/dita/gpgme-python-howto-footer.xhtml new file mode 100644 index 0000000..77d681a --- /dev/null +++ b/lang/python/docs/dita/gpgme-python-howto-footer.xhtml @@ -0,0 +1,9 @@ + + + + + + +
Copyright ? Benjamin D. McGinnes, 2018
for the GnuPG Project
+ + \ No newline at end of file diff --git a/lang/python/docs/dita/gpgme-python-howto.ditamap b/lang/python/docs/dita/gpgme-python-howto.ditamap index e66c9f4..1809acb 100644 --- a/lang/python/docs/dita/gpgme-python-howto.ditamap +++ b/lang/python/docs/dita/gpgme-python-howto.ditamap @@ -58,6 +58,11 @@ + + + + + @@ -87,4 +92,7 @@ + + + diff --git a/lang/python/docs/dita/gpgme-python.ditamap b/lang/python/docs/dita/gpgme-python.ditamap index 5232dca..6b8926b 100644 --- a/lang/python/docs/dita/gpgme-python.ditamap +++ b/lang/python/docs/dita/gpgme-python.ditamap @@ -3,4 +3,5 @@ GPGME Python Bindings + diff --git a/lang/python/docs/dita/gpgmePython.xpr b/lang/python/docs/dita/gpgmePython.xpr index e8756fc..59fe977 100644 --- a/lang/python/docs/dita/gpgmePython.xpr +++ b/lang/python/docs/dita/gpgmePython.xpr @@ -1,20 +1,35 @@ - + - + scenario.associations + gpgme-python.ditamap + + + + DITA Map WebHelp - TS/HC - GPGME + + + + + DITAMAP + + + + + gpgme-python-howto.ditamap - gpgme-python-howto (WebHelp Responsive) + DITA Map WebHelp - TS/HC - GPGME @@ -39,6 +54,455 @@ ${cfd} + ${cfd}/out/webhelp-${ddt} + + + ${cfd}/temp/webhelp-${ddt} + + + webhelp + + + + + false + + + true + + + + + + + + + + + + + + true + + + file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css + + + file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css + + + + + + + + + + + + + + + + + + + + + args.xhtml.classattr + + + + + + yes + + + yes + + + 4 + + + + yes + no + + + + + + + + + + + + + webhelp.footer.include + + + + + + yes + + + yes + + + 4 + + + + yes + no + + + + + + If the "webhelp.footer.file" parameter has a value, the content of that file is used as footer. If "webhelp.footer.file" has no value, the default Oxygen footer is inserted in each Webhelp page. + No footer is added to the Webhelp pages. + + + + + + webhelp.footer.file + + + + + + /Users/ben/dev/hgit/mine/gnupg/dita/gpgme/python/gpgme-python-howto-footer.xhtml + + + + + + 2 + + + + + + + + + + + webhelp.copyright + + + + + + Copyright ? Benjamin D. McGinnes, 2018 + + + + + + 0 + + + + + + + + + + + + -Xmx384m + + + false + + + + + + false + + + + + + + + + true + + + + + + DITA Map WebHelp - TS/HC - GPGME + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + DITAMAP + + + true + + + true + + + + + + + + + false + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + + + + + + + DITA-OT + + + + + + + + false + + + false + + + ${cfd} + + + ${cfd}/out/html5-${ddt} + + + ${cfd}/temp/html5-${ddt} + + + html5 + + + + + false + + + true + + + + + + + + + + + + + + true + + + file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css + + + file:/usr/local/oXygenXML/custom/webhelp-skins/high-contrast-skin.css + + + + + + + + + + + + + + + + + + + + + -Xmx384m + + + false + + + + + + false + + + + + + + + + true + + + + + + gpgme-python (HTML5) + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + DITAMAP + + + true + + + true + + + + + + + + + false + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + + + + + + + DITA-OT + + + + + + + + false + + + false + + + ${cfd} + + ${cfd}/out/html5 diff --git a/lang/python/docs/dita/howto/part01/docs-source.dita b/lang/python/docs/dita/howto/part01/docs-source.dita index 8e97a35..7c90b59 100644 --- a/lang/python/docs/dita/howto/part01/docs-source.dita +++ b/lang/python/docs/dita/howto/part01/docs-source.dita @@ -14,15 +14,16 @@
  1. A bug in either Org-Mode or Babel prevented the more complex examples included in the HOWTO - from displaying correctly.
  2. + from displaying correctly while also retaining syntax highlighting.
  3. To demonstrate some of the advantages of DITA XML over existing documentation production software used in the project (particularly Texinfo and LaTeX).

-

The XML format definitely supports displaying all the more complex Python code correctly, - as well as being designed to produce standards compliant print and HTML output. Whereas - currently the existing tools utilised by the GnuPG Project can't display the example code in - a way which would actually pass the project's own git commit ruleset.

+

The XML format definitely supports displaying all the more complex Python code correctly + with syntax highlighting, as well as being designed to produce standards compliant print and + HTML output. Whereas currently the existing tools utilised by the GnuPG Project can't + display the example code in a way which would actually pass the project's own git commit + ruleset.

diff --git a/lang/python/docs/dita/howto/part03/exporting-pubkeys.dita b/lang/python/docs/dita/howto/part03/exporting-pubkeys.dita new file mode 100644 index 0000000..8ae4f5b --- /dev/null +++ b/lang/python/docs/dita/howto/part03/exporting-pubkeys.dita @@ -0,0 +1,120 @@ + + + + + Exporting Public Keys + +

There are two methods of exporting public keys, both of which are very similar to the + other. The default method, key_export() will export a public key or keys + matching a specified pattern as normal. The alternative, the + key_export_minimal() method will do the same thing except producing a + minimised output with extra signatures and third party signatures or certifications + removed.

+

+ import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export(pattern=logrus) +except: + result = c.key_export(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) +else: + pass + +

+

It is important to note that the result will only return + None when a pattern has been entered for logrus, but + it has not matched any keys. When the search pattern itself is set to None + this triggers the exporting of the entire public keybox.

+

+ import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys in minimised form. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export_minimal(pattern=logrus) +except: + result = c.key_export_minimal(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) +else: + pass + +

+

+ + + diff --git a/lang/python/docs/dita/howto/part03/exporting-seckeys.dita b/lang/python/docs/dita/howto/part03/exporting-seckeys.dita new file mode 100644 index 0000000..9093aa0 --- /dev/null +++ b/lang/python/docs/dita/howto/part03/exporting-seckeys.dita @@ -0,0 +1,161 @@ + + + + + Exporting Secret Keys + +

Exporting secret keys is, functionally, very similar to exporting public keys; save for the + invocation of pinentry via gpg-agent in order to + securely enter the key's passphrase and authorise the export.

+

The following example exports the secret key to a file which is then set with the same + permissions as the output files created by the command line secret key export options.

+

+ import gpg +import os +import os.path +import sys + +print(""" +This script exports one or more secret keys. + +The gpg-agent and pinentry are invoked to authorise the export. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export_secret(pattern=logrus) +except: + result = c.key_export_secret(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + os.chmod(keyfile, 0o600) +else: + pass + +

+

Alternatively the approach of the following script can be used. This longer example saves + the exported secret key(s) in files in the GnuPG home directory, in addition to setting the + file permissions as only readable and writable by the user. It also exports the secret + key(s) twice in order to output both GPG binary (.gpg) and ASCII armoured + (.asc) files.

+

+ import gpg +import os +import os.path +import subprocess +import sys + +print(""" +This script exports one or more secret keys as both ASCII armored and binary +file formats, saved in files within the user's GPG home directory. + +The gpg-agent and pinentry are invoked to authorise the export. +""") + +if sys.platform == "win32": + gpgconfcmd = "gpgconf.exe --list-dirs homedir" +else: + gpgconfcmd = "gpgconf --list-dirs homedir" + +a = gpg.Context(armor=True) +b = gpg.Context() +c = gpg.Context() + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +if c.home_dir is not None: + if c.home_dir.endswith("/"): + gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}{1}.asc".format(c.home_dir, keyfile) + else: + gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile) +else: + if os.path.exists(os.environ["GNUPGHOME"]) is True: + hd = os.environ["GNUPGHOME"] + else: + hd = subprocess.getoutput(gpgconfcmd) + gpgfile = "{0}/{1}.gpg".format(hd, keyfile) + ascfile = "{0}/{1}.asc".format(hd, keyfile) + +try: + a_result = a.key_export_secret(pattern=logrus) + b_result = b.key_export_secret(pattern=logrus) +except: + a_result = a.key_export_secret(pattern=None) + b_result = b.key_export_secret(pattern=None) + +if a_result is not None: + with open(ascfile, "wb") as f: + f.write(a_result) + os.chmod(ascfile, 0o600) +else: + pass + +if b_result is not None: + with open(gpgfile, "wb") as f: + f.write(b_result) + os.chmod(gpgfile, 0o600) +else: + pass + +

+

+ + + diff --git a/lang/python/docs/dita/howto/part03/exporting.dita b/lang/python/docs/dita/howto/part03/exporting.dita new file mode 100644 index 0000000..8c054af --- /dev/null +++ b/lang/python/docs/dita/howto/part03/exporting.dita @@ -0,0 +1,12 @@ + + + + + Exporting Keys + +

Exporting keys remains a reasonably simple task, but has been separated into three + different functions for the OpenPGP cryptographic engine. Two of those functions are for + exporting public keys and the third is for exporting secret keys.

+ +
+
diff --git a/lang/python/docs/dita/howto/part03/importing.dita b/lang/python/docs/dita/howto/part03/importing.dita new file mode 100644 index 0000000..267eb94 --- /dev/null +++ b/lang/python/docs/dita/howto/part03/importing.dita @@ -0,0 +1,67 @@ + + + + + Importing keys + +

Importing keys is possible with the key_import() method and takes one + argument which is a bytes literal object containing either the binary or ASCII armoured key + data for one or more keys.

+

The following example retrieves one or more keys from the SKS keyservers via the web using + the requests module. Since requests returns the content as a bytes literal object, we can + then use that directly to import the resulting data into our keybox.

+

+ import gpg +import os.path +import requests + +c = gpg.Context() +url = "https://sks-keyservers.net/pks/lookup" +pattern = input("Enter the pattern to search for key or user IDs: ") +payload = { "op": "get", "search": pattern } + +r = requests.get(url, verify=True, params=payload) +result = c.key_import(r.content) + +if result is not None and hasattr(result, "considered") is False: + print(result) +elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" +The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} +Number of new secret keys: {5} + Number of unchanged keys: {6} + +The key IDs for all considered keys were: +""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") +else: + pass + +

+

+ When searching for a key ID of any length or a fingerprint (without spaces), the SKS + servers require the the leading 0x indicative of hexadecimal be included. + Also note that the old short key IDs (e.g. 0xDEADBEEF) should no longer + be used due to the relative ease by which such key IDs can be reproduced, as demonstrated + by the Evil32 + Project in 2014 (which was subsequently exploited in 2016). +

+

+ + + diff --git a/lang/python/docs/dita/howto/part04/decryption.dita b/lang/python/docs/dita/howto/part04/decryption.dita index 41a4650..bb8c368 100644 --- a/lang/python/docs/dita/howto/part04/decryption.dita +++ b/lang/python/docs/dita/howto/part04/decryption.dita @@ -30,9 +30,20 @@ else: pass

-

The data available in plaintext in this example is the decrypted content - as a byte object, the recipient key IDs and algorithms in result and the - results of verifying any signatures of the data in verify_result.

+

The data available in plaintext following a successful decryption in this + example is the decrypted content as a byte object, the recipient key IDs and algorithms in + result and the results of verifying any signatures of the data in + verify_result.

+

+ The graceful handling of GPGMEError with the try/except statement is + to handle the decryption error message produced if the file ciphertext, + and thus cfile, are encrypted with deprecated and insecure methods. + Particularly without MDC integrity checks or utilising deprecated encryption algorithms. + Messages and files encrypted with these are not decrypted with GPGME at all and any user + requiring archival access will need to access it manually with pre-GnuPG 2.3 versions of + the software which meets the requirements of the specific use case. +

+

diff --git a/lang/python/docs/dita/howto/part06/group-lines.dita b/lang/python/docs/dita/howto/part06/group-lines.dita index f4aca74..1dbfc97 100644 --- a/lang/python/docs/dita/howto/part06/group-lines.dita +++ b/lang/python/docs/dita/howto/part06/group-lines.dita @@ -44,6 +44,10 @@ for i in range(len(group_lists)):

from groups import group_lists

+

A demonstration of using the groups.py module is also available in + the form of the executable mutt-groups.py script. This second script + reads all the group entries in a user's gpg.conf file and converts them + into crypt-hooks suitable for use with the Mutt and Neomutt mail clients.

diff --git a/lang/python/docs/dita/howto/version-info.dita b/lang/python/docs/dita/howto/version-info.dita index 6776820..f9bb42a 100644 --- a/lang/python/docs/dita/howto/version-info.dita +++ b/lang/python/docs/dita/howto/version-info.dita @@ -4,10 +4,12 @@ Documentation Version -

Version: 0.1.1

+

Version: 0.1.2-DRAFT

Author: Ben McGinnes <ben at gnupg.org>

-

Author GPG Key ID: DB4724E6FA4286C92B4E55C4321E4E2373590E5D

+

Author GPG Key ID: + DB4724E6FA4286C92B4E55C4321E4E2373590E5D

Language: Australian English, British English

----------------------------------------------------------------------- Summary of changes: .../docs/dita/gpgme-python-howto-footer.xhtml | 9 + lang/python/docs/dita/gpgme-python-howto.ditamap | 8 + lang/python/docs/dita/gpgme-python.ditamap | 1 + lang/python/docs/dita/gpgmePython.xpr | 470 ++++++++++++++++++++- .../python/docs/dita/howto/part01/docs-source.dita | 11 +- .../docs/dita/howto/part03/exporting-pubkeys.dita | 120 ++++++ .../docs/dita/howto/part03/exporting-seckeys.dita | 161 +++++++ lang/python/docs/dita/howto/part03/exporting.dita | 12 + lang/python/docs/dita/howto/part03/importing.dita | 67 +++ lang/python/docs/dita/howto/part04/decryption.dita | 17 +- .../python/docs/dita/howto/part06/group-lines.dita | 4 + lang/python/docs/dita/howto/version-info.dita | 6 +- 12 files changed, 873 insertions(+), 13 deletions(-) create mode 100644 lang/python/docs/dita/gpgme-python-howto-footer.xhtml create mode 100644 lang/python/docs/dita/howto/part03/exporting-pubkeys.dita create mode 100644 lang/python/docs/dita/howto/part03/exporting-seckeys.dita create mode 100644 lang/python/docs/dita/howto/part03/exporting.dita create mode 100644 lang/python/docs/dita/howto/part03/importing.dita hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 28 10:16:52 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 28 Jun 2018 10:16:52 +0200 Subject: [git] GPGME - branch, ben/export-keys, updated. gpgme-1.11.1-70-g6573eb3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/export-keys has been updated via 6573eb339a2a657354d3290061b5a2f9e31dab85 (commit) via 248c42788f7f665b6a2a42c5ccf5c2a4baed1058 (commit) from 4bbe247c845795e2bb09509c40a8472a910e907d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6573eb339a2a657354d3290061b5a2f9e31dab85 Author: Ben McGinnes Date: Thu Jun 28 18:14:13 2018 +1000 python bindings examples * Added a secret key export variant which saves output as both GPG binary and ASCII armoured, plus saves in $GNUPGHOME and uses multiple methods of determining what that location is. diff --git a/lang/python/examples/howto/export-secret-keys.py b/lang/python/examples/howto/export-secret-keys.py new file mode 100755 index 0000000..03037c9 --- /dev/null +++ b/lang/python/examples/howto/export-secret-keys.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os +import os.path +import subprocess +import sys + +print(""" +This script exports one or more secret keys as both ASCII armored and binary +file formats, saved in files within the user's GPG home directory. + +The gpg-agent and pinentry are invoked to authorise the export. +""") + +if sys.platform == "win32": + gpgconfcmd = "gpgconf.exe --list-dirs homedir" +else: + gpgconfcmd = "gpgconf --list-dirs homedir" + +a = gpg.Context(armor=True) +b = gpg.Context() +c = gpg.Context() + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +if c.home_dir is not None: + if c.home_dir.endswith("/"): + gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}{1}.asc".format(c.home_dir, keyfile) + else: + gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile) +else: + if os.path.exists(os.environ["GNUPGHOME"]) is True: + hd = os.environ["GNUPGHOME"] + else: + hd = subprocess.getoutput(gpgconfcmd) + gpgfile = "{0}/{1}.gpg".format(hd, keyfile) + ascfile = "{0}/{1}.asc".format(hd, keyfile) + +try: + a_result = a.key_export_secret(pattern=logrus) + b_result = b.key_export_secret(pattern=logrus) +except: + a_result = a.key_export_secret(pattern=None) + b_result = b.key_export_secret(pattern=None) + +if a_result is not None: + with open(ascfile, "wb") as f: + f.write(a_result) + os.chmod(ascfile, 0o600) +else: + pass + +if b_result is not None: + with open(gpgfile, "wb") as f: + f.write(b_result) + os.chmod(gpgfile, 0o600) +else: + pass commit 248c42788f7f665b6a2a42c5ccf5c2a4baed1058 Author: Ben McGinnes Date: Thu Jun 28 03:28:07 2018 +1000 python bindings examples * Added a key import variant which accesses the SKS keyservers in a RESTful fashion and then imports or attempts to import the response. diff --git a/lang/python/examples/howto/import-keys.py b/lang/python/examples/howto/import-keys.py new file mode 100755 index 0000000..8a3bb29 --- /dev/null +++ b/lang/python/examples/howto/import-keys.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import requests + +print(""" +This script imports one or more public keys from the SKS keyservers. +""") + +import gpg +import requests + +c = gpg.Context() +url = "https://sks-keyservers.net/pks/lookup" +pattern = input("Enter the pattern to search for key or user IDs: ") +payload = { "op": "get", "search": pattern } + +r = requests.get(url, verify=True, params=payload) +result = c.key_import(r.content) + +if result is not None and hasattr(result, "considered") is False: + print(result) +elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" +The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} +Number of new secret keys: {5} + Number of unchanged keys: {6} + +The key IDs for all considered keys were: +""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") +else: + pass ----------------------------------------------------------------------- Summary of changes: ...{export-secret-key.py => export-secret-keys.py} | 51 ++++++++++++++++++---- .../howto/{import-key.py => import-keys.py} | 42 +++++------------- 2 files changed, 54 insertions(+), 39 deletions(-) copy lang/python/examples/howto/{export-secret-key.py => export-secret-keys.py} (60%) copy lang/python/examples/howto/{import-key.py => import-keys.py} (69%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 28 10:36:10 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 28 Jun 2018 10:36:10 +0200 Subject: [git] GPGME - branch, ben/export-keys, updated. gpgme-1.11.1-71-gfa1a4e0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, ben/export-keys has been updated via fa1a4e0b25faf995ff1fbadd54917de23da59ebd (commit) from 6573eb339a2a657354d3290061b5a2f9e31dab85 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fa1a4e0b25faf995ff1fbadd54917de23da59ebd Author: Ben McGinnes Date: Thu Jun 28 18:33:51 2018 +1000 docs: python bindings howto * Updated official doc (the org-mode file) with the instructions on importing and exporting both public and secret keys. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 3325c08..6a3f9db 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -454,6 +454,364 @@ literals with the fingerprint when getting a key in this way. +** Importing keys + :PROPERTIES: + :CUSTOM_ID: howto-import-key + :END: + + Importing keys is possible with the =key_import()= method and takes + one argument which is a bytes literal object containing either the + binary or ASCII armoured key data for one or more keys. + + The following example retrieves one or more keys from the SKS + keyservers via the web using the requests module. Since requests + returns the content as a bytes literal object, we can then use that + directly to import the resulting data into our keybox. + + #+begin_src python + import gpg + import os.path + import requests + + c = gpg.Context() + url = "https://sks-keyservers.net/pks/lookup" + pattern = input("Enter the pattern to search for key or user IDs: ") + payload = { "op": "get", "search": pattern } + + r = requests.get(url, verify=True, params=payload) + result = c.key_import(r.content) + + if result is not None and hasattr(result, "considered") is False: + print(result) + elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" + The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} + Number of new secret keys: {5} + Number of unchanged keys: {6} + + The key IDs for all considered keys were: + """.format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") + else: + pass + #+end_src + + *NOTE:* When searching for a key ID of any length or a fingerprint + (without spaces), the SKS servers require the the leading =0x= + indicative of hexadecimal be included. Also note that the old short + key IDs (e.g. =0xDEADBEEF=) should no longer be used due to the + relative ease by which such key IDs can be reproduced, as + demonstrated by the Evil32 Project in 2014 (which was subsequently + exploited in 2016). + + +** Exporting keys + :PROPERTIES: + :CUSTOM_ID: howto-export-key + :END: + + Exporting keys remains a reasonably simple task, but has been + separated into three different functions for the OpenPGP + cryptographic engine. Two of those functions are for exporting + public keys and the third is for exporting secret keys. + + +*** Exporting public keys + :PROPERTIES: + :CUSTOM_ID: howto-export-public-key + :END: + + There are two methods of exporting public keys, both of which are + very similar to the other. The default method, =key_export()=, + will export a public key or keys matching a specified pattern as + normal. The alternative, the =key_export_minimal()= method, will + do the same thing except producing a minimised output with extra + signatures and third party signatures or certifications removed. + + #+begin_src python + import gpg + import os.path + import sys + + print(""" + This script exports one or more public keys. + """) + + c = gpg.Context(armor=True) + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + try: + result = c.key_export(pattern=logrus) + except: + result = c.key_export(pattern=None) + + if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + else: + pass + #+end_src + + It is important to note that the result will only return =None= + when a pattern has been entered for =logrus=, but it has not + matched any keys. When the search pattern itself is set to =None= + this triggers the exporting of the entire public keybox. + + #+begin_src python + import gpg + import os.path + import sys + + print(""" + This script exports one or more public keys in minimised form. + """) + + c = gpg.Context(armor=True) + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + try: + result = c.key_export_minimal(pattern=logrus) + except: + result = c.key_export_minimal(pattern=None) + + if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + else: + pass + #+end_src + + +*** Exporting secret keys + :PROPERTIES: + :CUSTOM_ID: howto-export-secret-key + :END: + + Exporting secret keys is, functionally, very similar to exporting + public keys; save for the invocation of =pinentry= via =gpg-agent= + in order to securely enter the key's passphrase and authorise the + export. + + The following example exports the secret key to a file which is + then set with the same permissions as the output files created by + the command line secret key export options. + + #+begin_src python + import gpg + import os + import os.path + import sys + + print(""" + This script exports one or more secret keys. + + The gpg-agent and pinentry are invoked to authorise the export. + """) + + c = gpg.Context(armor=True) + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + try: + result = c.key_export_secret(pattern=logrus) + except: + result = c.key_export_secret(pattern=None) + + if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + os.chmod(keyfile, 0o600) + else: + pass + #+end_src + + Alternatively the approach of the following script can be + used. This longer example saves the exported secret key(s) in + files in the GnuPG home directory, in addition to setting the file + permissions as only readable and writable by the user. It also + exports the secret key(s) twice in order to output both GPG binary + (=.gpg=) and ASCII armoured (=.asc=) files. + + #+begin_src python + import gpg + import os + import os.path + import subprocess + import sys + + print(""" + This script exports one or more secret keys as both ASCII armored and binary + file formats, saved in files within the user's GPG home directory. + + The gpg-agent and pinentry are invoked to authorise the export. + """) + + if sys.platform == "win32": + gpgconfcmd = "gpgconf.exe --list-dirs homedir" + else: + gpgconfcmd = "gpgconf --list-dirs homedir" + + a = gpg.Context(armor=True) + b = gpg.Context() + c = gpg.Context() + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + if c.home_dir is not None: + if c.home_dir.endswith("/"): + gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}{1}.asc".format(c.home_dir, keyfile) + else: + gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile) + else: + if os.path.exists(os.environ["GNUPGHOME"]) is True: + hd = os.environ["GNUPGHOME"] + else: + hd = subprocess.getoutput(gpgconfcmd) + gpgfile = "{0}/{1}.gpg".format(hd, keyfile) + ascfile = "{0}/{1}.asc".format(hd, keyfile) + + try: + a_result = a.key_export_secret(pattern=logrus) + b_result = b.key_export_secret(pattern=logrus) + except: + a_result = a.key_export_secret(pattern=None) + b_result = b.key_export_secret(pattern=None) + + if a_result is not None: + with open(ascfile, "wb") as f: + f.write(a_result) + os.chmod(ascfile, 0o600) + else: + pass + + if b_result is not None: + with open(gpgfile, "wb") as f: + f.write(b_result) + os.chmod(gpgfile, 0o600) + else: + pass + #+end_src + + * Basic Functions :PROPERTIES: :CUSTOM_ID: howto-the-basics ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 358 ++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jun 28 10:52:48 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Thu, 28 Jun 2018 10:52:48 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-72-g48174b2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 48174b2bcc319e4542aefd0cc3aae02c4083784e (commit) via 6aec7d6e4a5173f54a079719020704a0098b8f0a (commit) via a7ccdc51efd8c199b902eb942e9db7b3549e721f (commit) via 7fc7e80e54235c558051cbf72b51dd60b4ca485e (commit) via 0d163a7d121eacacc5f6da11a3dee3548f98f124 (commit) via 4251cae34da0d825a29f509ac828f7ecb90c1752 (commit) via a5b91b21f561d7b13ddcb62fca3749ed92ea8720 (commit) via 7faef33d13fa8efce152ca7aa6e9d39030c1cf08 (commit) via 89c548efdf46bd7d9e6f0ca34a07efbbf420e821 (commit) from d8beab30c44482fb7a3e445b92cec482792b2ca0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 48174b2bcc319e4542aefd0cc3aae02c4083784e Author: Ben McGinnes Date: Thu Jun 28 18:46:31 2018 +1000 whitespace police: * There's always one or, in this case, two. diff --git a/lang/python/src/core.py b/lang/python/src/core.py index f8e0c60..7003b25 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -610,9 +610,9 @@ class Context(GpgmeWrapper): Keyword arguments: pattern -- return keys matching pattern (default: all keys) - Returns: + Returns: -- A key block containing one or more minimised OpenPGP - keys in either ASCII armoured or binary format as + keys in either ASCII armoured or binary format as determined by the Context(). If there are no matching keys it returns None. commit 6aec7d6e4a5173f54a079719020704a0098b8f0a Author: Ben McGinnes Date: Thu Jun 28 18:33:51 2018 +1000 docs: python bindings howto * Updated official doc (the org-mode file) with the instructions on importing and exporting both public and secret keys. diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 3325c08..6a3f9db 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -454,6 +454,364 @@ literals with the fingerprint when getting a key in this way. +** Importing keys + :PROPERTIES: + :CUSTOM_ID: howto-import-key + :END: + + Importing keys is possible with the =key_import()= method and takes + one argument which is a bytes literal object containing either the + binary or ASCII armoured key data for one or more keys. + + The following example retrieves one or more keys from the SKS + keyservers via the web using the requests module. Since requests + returns the content as a bytes literal object, we can then use that + directly to import the resulting data into our keybox. + + #+begin_src python + import gpg + import os.path + import requests + + c = gpg.Context() + url = "https://sks-keyservers.net/pks/lookup" + pattern = input("Enter the pattern to search for key or user IDs: ") + payload = { "op": "get", "search": pattern } + + r = requests.get(url, verify=True, params=payload) + result = c.key_import(r.content) + + if result is not None and hasattr(result, "considered") is False: + print(result) + elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" + The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} + Number of new secret keys: {5} + Number of unchanged keys: {6} + + The key IDs for all considered keys were: + """.format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") + else: + pass + #+end_src + + *NOTE:* When searching for a key ID of any length or a fingerprint + (without spaces), the SKS servers require the the leading =0x= + indicative of hexadecimal be included. Also note that the old short + key IDs (e.g. =0xDEADBEEF=) should no longer be used due to the + relative ease by which such key IDs can be reproduced, as + demonstrated by the Evil32 Project in 2014 (which was subsequently + exploited in 2016). + + +** Exporting keys + :PROPERTIES: + :CUSTOM_ID: howto-export-key + :END: + + Exporting keys remains a reasonably simple task, but has been + separated into three different functions for the OpenPGP + cryptographic engine. Two of those functions are for exporting + public keys and the third is for exporting secret keys. + + +*** Exporting public keys + :PROPERTIES: + :CUSTOM_ID: howto-export-public-key + :END: + + There are two methods of exporting public keys, both of which are + very similar to the other. The default method, =key_export()=, + will export a public key or keys matching a specified pattern as + normal. The alternative, the =key_export_minimal()= method, will + do the same thing except producing a minimised output with extra + signatures and third party signatures or certifications removed. + + #+begin_src python + import gpg + import os.path + import sys + + print(""" + This script exports one or more public keys. + """) + + c = gpg.Context(armor=True) + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + try: + result = c.key_export(pattern=logrus) + except: + result = c.key_export(pattern=None) + + if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + else: + pass + #+end_src + + It is important to note that the result will only return =None= + when a pattern has been entered for =logrus=, but it has not + matched any keys. When the search pattern itself is set to =None= + this triggers the exporting of the entire public keybox. + + #+begin_src python + import gpg + import os.path + import sys + + print(""" + This script exports one or more public keys in minimised form. + """) + + c = gpg.Context(armor=True) + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + try: + result = c.key_export_minimal(pattern=logrus) + except: + result = c.key_export_minimal(pattern=None) + + if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + else: + pass + #+end_src + + +*** Exporting secret keys + :PROPERTIES: + :CUSTOM_ID: howto-export-secret-key + :END: + + Exporting secret keys is, functionally, very similar to exporting + public keys; save for the invocation of =pinentry= via =gpg-agent= + in order to securely enter the key's passphrase and authorise the + export. + + The following example exports the secret key to a file which is + then set with the same permissions as the output files created by + the command line secret key export options. + + #+begin_src python + import gpg + import os + import os.path + import sys + + print(""" + This script exports one or more secret keys. + + The gpg-agent and pinentry are invoked to authorise the export. + """) + + c = gpg.Context(armor=True) + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + try: + result = c.key_export_secret(pattern=logrus) + except: + result = c.key_export_secret(pattern=None) + + if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + os.chmod(keyfile, 0o600) + else: + pass + #+end_src + + Alternatively the approach of the following script can be + used. This longer example saves the exported secret key(s) in + files in the GnuPG home directory, in addition to setting the file + permissions as only readable and writable by the user. It also + exports the secret key(s) twice in order to output both GPG binary + (=.gpg=) and ASCII armoured (=.asc=) files. + + #+begin_src python + import gpg + import os + import os.path + import subprocess + import sys + + print(""" + This script exports one or more secret keys as both ASCII armored and binary + file formats, saved in files within the user's GPG home directory. + + The gpg-agent and pinentry are invoked to authorise the export. + """) + + if sys.platform == "win32": + gpgconfcmd = "gpgconf.exe --list-dirs homedir" + else: + gpgconfcmd = "gpgconf --list-dirs homedir" + + a = gpg.Context(armor=True) + b = gpg.Context() + c = gpg.Context() + + if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] + elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") + elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + else: + keyfile = input("Enter the filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + + if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass + elif os.path.exists(homedir) is True: + c.home_dir = homedir + else: + pass + + if c.home_dir is not None: + if c.home_dir.endswith("/"): + gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}{1}.asc".format(c.home_dir, keyfile) + else: + gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile) + else: + if os.path.exists(os.environ["GNUPGHOME"]) is True: + hd = os.environ["GNUPGHOME"] + else: + hd = subprocess.getoutput(gpgconfcmd) + gpgfile = "{0}/{1}.gpg".format(hd, keyfile) + ascfile = "{0}/{1}.asc".format(hd, keyfile) + + try: + a_result = a.key_export_secret(pattern=logrus) + b_result = b.key_export_secret(pattern=logrus) + except: + a_result = a.key_export_secret(pattern=None) + b_result = b.key_export_secret(pattern=None) + + if a_result is not None: + with open(ascfile, "wb") as f: + f.write(a_result) + os.chmod(ascfile, 0o600) + else: + pass + + if b_result is not None: + with open(gpgfile, "wb") as f: + f.write(b_result) + os.chmod(gpgfile, 0o600) + else: + pass + #+end_src + + * Basic Functions :PROPERTIES: :CUSTOM_ID: howto-the-basics commit a7ccdc51efd8c199b902eb942e9db7b3549e721f Author: Ben McGinnes Date: Thu Jun 28 18:14:13 2018 +1000 python bindings examples * Added a secret key export variant which saves output as both GPG binary and ASCII armoured, plus saves in $GNUPGHOME and uses multiple methods of determining what that location is. diff --git a/lang/python/examples/howto/export-secret-keys.py b/lang/python/examples/howto/export-secret-keys.py new file mode 100755 index 0000000..03037c9 --- /dev/null +++ b/lang/python/examples/howto/export-secret-keys.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os +import os.path +import subprocess +import sys + +print(""" +This script exports one or more secret keys as both ASCII armored and binary +file formats, saved in files within the user's GPG home directory. + +The gpg-agent and pinentry are invoked to authorise the export. +""") + +if sys.platform == "win32": + gpgconfcmd = "gpgconf.exe --list-dirs homedir" +else: + gpgconfcmd = "gpgconf --list-dirs homedir" + +a = gpg.Context(armor=True) +b = gpg.Context() +c = gpg.Context() + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +if c.home_dir is not None: + if c.home_dir.endswith("/"): + gpgfile = "{0}{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}{1}.asc".format(c.home_dir, keyfile) + else: + gpgfile = "{0}/{1}.gpg".format(c.home_dir, keyfile) + ascfile = "{0}/{1}.asc".format(c.home_dir, keyfile) +else: + if os.path.exists(os.environ["GNUPGHOME"]) is True: + hd = os.environ["GNUPGHOME"] + else: + hd = subprocess.getoutput(gpgconfcmd) + gpgfile = "{0}/{1}.gpg".format(hd, keyfile) + ascfile = "{0}/{1}.asc".format(hd, keyfile) + +try: + a_result = a.key_export_secret(pattern=logrus) + b_result = b.key_export_secret(pattern=logrus) +except: + a_result = a.key_export_secret(pattern=None) + b_result = b.key_export_secret(pattern=None) + +if a_result is not None: + with open(ascfile, "wb") as f: + f.write(a_result) + os.chmod(ascfile, 0o600) +else: + pass + +if b_result is not None: + with open(gpgfile, "wb") as f: + f.write(b_result) + os.chmod(gpgfile, 0o600) +else: + pass commit 7fc7e80e54235c558051cbf72b51dd60b4ca485e Author: Ben McGinnes Date: Thu Jun 28 03:28:07 2018 +1000 python bindings examples * Added a key import variant which accesses the SKS keyservers in a RESTful fashion and then imports or attempts to import the response. diff --git a/lang/python/examples/howto/import-keys.py b/lang/python/examples/howto/import-keys.py new file mode 100755 index 0000000..8a3bb29 --- /dev/null +++ b/lang/python/examples/howto/import-keys.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import requests + +print(""" +This script imports one or more public keys from the SKS keyservers. +""") + +import gpg +import requests + +c = gpg.Context() +url = "https://sks-keyservers.net/pks/lookup" +pattern = input("Enter the pattern to search for key or user IDs: ") +payload = { "op": "get", "search": pattern } + +r = requests.get(url, verify=True, params=payload) +result = c.key_import(r.content) + +if result is not None and hasattr(result, "considered") is False: + print(result) +elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" +The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} +Number of new secret keys: {5} + Number of unchanged keys: {6} + +The key IDs for all considered keys were: +""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") +else: + pass commit 0d163a7d121eacacc5f6da11a3dee3548f98f124 Author: Ben McGinnes Date: Wed Jun 27 20:12:27 2018 +1000 python bindings examples: three export scripts * Example of default exporting keys. * Example of exporting minimised keys. * Example of exporting secret keys to a file with correct permissions. Signed-off-by: Ben McGinnes diff --git a/lang/python/examples/howto/export-key.py b/lang/python/examples/howto/export-key.py new file mode 100755 index 0000000..41be64f --- /dev/null +++ b/lang/python/examples/howto/export-key.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export(pattern=logrus) +except: + result = c.key_export(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) +else: + pass diff --git a/lang/python/examples/howto/export-minimised-key.py b/lang/python/examples/howto/export-minimised-key.py new file mode 100755 index 0000000..d28b1cb --- /dev/null +++ b/lang/python/examples/howto/export-minimised-key.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys in minimised form. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export_minimal(pattern=logrus) +except: + result = c.key_export_minimal(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) +else: + pass diff --git a/lang/python/examples/howto/export-secret-key.py b/lang/python/examples/howto/export-secret-key.py new file mode 100755 index 0000000..8bbe409 --- /dev/null +++ b/lang/python/examples/howto/export-secret-key.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os +import os.path +import sys + +print(""" +This script exports one or more secret keys. + +The gpg-agent and pinentry are invoked to authorise the export. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 4: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = sys.argv[3] +elif len(sys.argv) == 3: + keyfile = sys.argv[1] + logrus = sys.argv[2] + homedir = input("Enter the GPG configuration directory path (optional): ") +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to save the secret key to: ") + logrus = input("Enter the UID matching the secret key(s) to export: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +try: + result = c.key_export_secret(pattern=logrus) +except: + result = c.key_export_secret(pattern=None) + +if result is not None: + with open(keyfile, "wb") as f: + f.write(result) + os.chmod(keyfile, 0o600) +else: + pass commit 4251cae34da0d825a29f509ac828f7ecb90c1752 Author: Ben McGinnes Date: Thu Jun 28 01:50:56 2018 +1000 python bindings: import example * Added an example script for importing a key from a file (either ASCII armoured or not). diff --git a/lang/python/examples/howto/import-key.py b/lang/python/examples/howto/import-key.py new file mode 100755 index 0000000..56cfe25 --- /dev/null +++ b/lang/python/examples/howto/import-key.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +# Copyright (C) 2018 Ben McGinnes +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU +# Lesser General Public Licensefor more details. +# +# You should have received a copy of the GNU General Public License and the GNU +# Lesser General Public along with this program; if not, see +# . + +import gpg +import os.path +import sys + +print(""" +This script exports one or more public keys. +""") + +c = gpg.Context(armor=True) + +if len(sys.argv) >= 3: + keyfile = sys.argv[1] + homedir = sys.argv[2] +elif len(sys.argv) == 2: + keyfile = sys.argv[1] + homedir = input("Enter the GPG configuration directory path (optional): ") +else: + keyfile = input("Enter the path and filename to import the key(s) from: ") + homedir = input("Enter the GPG configuration directory path (optional): ") + +if homedir.startswith("~"): + if os.path.exists(os.path.expanduser(homedir)) is True: + c.home_dir = os.path.expanduser(homedir) + else: + pass +elif os.path.exists(homedir) is True: + c.home_dir = homedir +else: + pass + +if os.path.isfile(keyfile) is True: + with open(keyfile, "rb") as f: + incoming = f.read() + result = c.key_import(incoming) +else: + result = None + +if result is not None and hasattr(result, "considered") is False: + print(result) +elif result is not None and hasattr(result, "considered") is True: + num_keys = len(result.imports) + new_revs = result.new_revocations + new_sigs = result.new_signatures + new_subs = result.new_sub_keys + new_uids = result.new_user_ids + new_scrt = result.secret_imported + nochange = result.unchanged + print(""" +The total number of keys considered for import was: {0} + + Number of keys revoked: {1} + Number of new signatures: {2} + Number of new subkeys: {3} + Number of new user IDs: {4} +Number of new secret keys: {5} + Number of unchanged keys: {6} + +The key IDs for all considered keys were: +""".format(num_keys, new_revs, new_sigs, new_subs, new_uids, new_scrt, + nochange)) + for i in range(num_keys): + print(result.imports[i].fpr) + print("") +elif result is None: + print("You must specify a key file to import.") commit a5b91b21f561d7b13ddcb62fca3749ed92ea8720 Author: Ben McGinnes Date: Wed Jun 27 19:16:29 2018 +1000 python bindings: export secret keys * The holy grail: a function to export secret keys. * GPGME will still invoke pinentry and gpg-agent as usual to authorise the export. * Mostly similar to the two previous export functions for public keys except that it will return None if the result had a length of zero bytes. Meaning that the difference between the specified pattern (if any) not matching available keys and an incorrect passphrase is not able to be determined from this function (or the underlying one for that matter). Signed-off-by: Ben McGinnes diff --git a/lang/python/src/core.py b/lang/python/src/core.py index d7db7de..f8e0c60 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -618,7 +618,7 @@ class Context(GpgmeWrapper): Raises: GPGMEError -- as signaled by the underlying library. -""" + """ data = Data() mode = gpgme.GPGME_EXPORT_MODE_MINIMAL try: @@ -635,6 +635,47 @@ class Context(GpgmeWrapper): return result + def key_export_secret(self, pattern=None): + """Export secret keys. + + Exports secret keys matching the pattern specified. If no + pattern is specified then exports or attempts to export all + available secret keys. + + IMPORTANT: Each secret key to be exported will prompt for its + passphrase via an invocation of pinentry and gpg-agent. If the + passphrase is not entered or does not match then no data will be + exported. This is the same result as when specifying a pattern + that is not matched by the available keys. + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + + Returns: + -- On success a key block containing one or more OpenPGP + secret keys in either ASCII armoured or binary format + as determined by the Context(). + -- On failure while not raising an exception, returns None. + + Raises: + GPGMEError -- as signaled by the underlying library. + """ + data = Data() + mode = gpgme.GPGME_EXPORT_MODE_SECRET + try: + self.op_export(pattern, mode, data) + data.seek(0, os.SEEK_SET) + sk_result = data.read() + except GPGMEError as e: + sk_result = e + + if len(sk_result) > 0: + result = sk_result + else: + result = None + + return result + def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, source=None): commit 7faef33d13fa8efce152ca7aa6e9d39030c1cf08 Author: Ben McGinnes Date: Thu Jun 28 00:57:37 2018 +1000 python bindings: export public keys * Updated key_export and key_export_minimal to return None where a pattern matched no keys in a manner simnilar to the possible result of key_export_secret. diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 86a62b5..d7db7de 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -578,7 +578,8 @@ class Context(GpgmeWrapper): Returns: -- A key block containing one or more OpenPGP keys in either ASCII armoured or binary format as determined - by the Context(). + by the Context(). If there are no matching keys it + returns None. Raises: GPGMEError -- as signaled by the underlying library. @@ -588,9 +589,14 @@ class Context(GpgmeWrapper): try: self.op_export(pattern, mode, data) data.seek(0, os.SEEK_SET) - result = data.read() + pk_result = data.read() except GPGMEError as e: - result = e + pk_result = e + + if len(pk_result) > 0: + result = pk_result + else: + result = None return result @@ -607,7 +613,8 @@ class Context(GpgmeWrapper): Returns: -- A key block containing one or more minimised OpenPGP keys in either ASCII armoured or binary format as - determined by the Context(). + determined by the Context(). If there are no matching + keys it returns None. Raises: GPGMEError -- as signaled by the underlying library. @@ -617,9 +624,14 @@ class Context(GpgmeWrapper): try: self.op_export(pattern, mode, data) data.seek(0, os.SEEK_SET) - result = data.read() + pk_result = data.read() except GPGMEError as e: - result = e + pk_result = e + + if len(pk_result) > 0: + result = pk_result + else: + result = None return result commit 89c548efdf46bd7d9e6f0ca34a07efbbf420e821 Author: Ben McGinnes Date: Wed Jun 27 18:51:09 2018 +1000 python bindings: export public keys * Added functions for exporting public keys to gpg.core in both complete form and in minimised form. * Rather than letting people need to worry about the export modes we are simply separating the functions as people would be more familiar with from the command line usage anyway. * Functions added for Context are: ctx.key_export_minimal and ctx.key_export as the default or full export. Signed-off-by: Ben McGinnes diff --git a/lang/python/src/core.py b/lang/python/src/core.py index 8f2e9d8..86a62b5 100644 --- a/lang/python/src/core.py +++ b/lang/python/src/core.py @@ -537,7 +537,7 @@ class Context(GpgmeWrapper): managed to run the function without any arguments, while an argument of None triggers the first NODATA of errors.GPGME in the - exception. + exception. """ try: self.op_import(data) @@ -566,6 +566,63 @@ class Context(GpgmeWrapper): return import_result + def key_export(self, pattern=None): + """Export keys. + + Exports public keys matching the pattern specified. If no + pattern is specified then exports all available keys. + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + + Returns: + -- A key block containing one or more OpenPGP keys in + either ASCII armoured or binary format as determined + by the Context(). + + Raises: + GPGMEError -- as signaled by the underlying library. + """ + data = Data() + mode = 0 + try: + self.op_export(pattern, mode, data) + data.seek(0, os.SEEK_SET) + result = data.read() + except GPGMEError as e: + result = e + + return result + + def key_export_minimal(self, pattern=None): + """Export keys. + + Exports public keys matching the pattern specified in a + minimised format. If no pattern is specified then exports all + available keys. + + Keyword arguments: + pattern -- return keys matching pattern (default: all keys) + + Returns: + -- A key block containing one or more minimised OpenPGP + keys in either ASCII armoured or binary format as + determined by the Context(). + + Raises: + GPGMEError -- as signaled by the underlying library. +""" + data = Data() + mode = gpgme.GPGME_EXPORT_MODE_MINIMAL + try: + self.op_export(pattern, mode, data) + data.seek(0, os.SEEK_SET) + result = data.read() + except GPGMEError as e: + result = e + + return result + def keylist(self, pattern=None, secret=False, mode=constants.keylist.mode.LOCAL, source=None): ----------------------------------------------------------------------- Summary of changes: lang/python/docs/GPGMEpythonHOWTOen.org | 358 +++++++++++++++++++++ .../howto/{add-userid.py => export-key.py} | 43 ++- .../{add-userid.py => export-minimised-key.py} | 43 ++- .../{revoke-userid.py => export-secret-key.py} | 45 ++- lang/python/examples/howto/export-secret-keys.py | 110 +++++++ lang/python/examples/howto/import-key.py | 91 ++++++ lang/python/examples/howto/import-keys.py | 73 +++++ lang/python/src/core.py | 112 ++++++- 8 files changed, 827 insertions(+), 48 deletions(-) copy lang/python/examples/howto/{add-userid.py => export-key.py} (59%) copy lang/python/examples/howto/{add-userid.py => export-minimised-key.py} (59%) copy lang/python/examples/howto/{revoke-userid.py => export-secret-key.py} (56%) create mode 100755 lang/python/examples/howto/export-secret-keys.py create mode 100755 lang/python/examples/howto/import-key.py create mode 100755 lang/python/examples/howto/import-keys.py hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jun 29 06:56:33 2018 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Fri, 29 Jun 2018 06:56:33 +0200 Subject: [git] GPGME - branch, master, updated. gpgme-1.11.1-74-g35e29e1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 35e29e139534ed217340879732a7adfdbd57c91d (commit) via 43a2b5754571292b25402e20cd044ebda9316c77 (commit) from 48174b2bcc319e4542aefd0cc3aae02c4083784e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 35e29e139534ed217340879732a7adfdbd57c91d Author: Ben McGinnes Date: Fri Jun 29 14:52:37 2018 +1000 m4 update: python 3.7 * Fixed an error in arcane m4 syntax. diff --git a/m4/python.m4 b/m4/python.m4 index db7b482..56220ba 100644 --- a/m4/python.m4 +++ b/m4/python.m4 @@ -35,16 +35,13 @@ AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not - dnl supported. (2.0 was released on October 16, 2000). + dnl supported. (2.0 was released on October 16, 2000). Python 3.0 + dnl through to Python 3.3 are also not supported. m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python2 python2.7 dnl python dnl - dnl old listing was pointless since biundings only work from Python 3.4: - dnl python3 python3.0 python3.1 python3.2 python3.3 - dnl move 3.7 to the front once 3.7.1 or 3.7.2 is released: - dnl python3 python3.7 python3.6 python3.5 python3.4 python3.8]) - dnl until then: - python3 python3.6 python3.5 python3.4 python3.7 python3.8]) + python3 python3.6 python3.5 python3.4 python3.7 dnl + python3.8]) AC_ARG_VAR([PYTHON], [the Python interpreter]) commit 43a2b5754571292b25402e20cd044ebda9316c77 Author: Ben McGinnes Date: Fri Jun 29 14:26:30 2018 +1000 python bindings: python 3.7 * Bindings confirmed to work with the newly released 3.7.0. * Updated M4 file to reflect this change and correct the Python binary search order (3.7 is not yet given priority, but will still be found first via the more generic python3 executable). * Updated setup.py.in, bindings documentation and README to reflect this. diff --git a/lang/python/README b/lang/python/README index 99da4dd..aadf980 100644 --- a/lang/python/README +++ b/lang/python/README @@ -44,8 +44,8 @@ functionality of the underlying library. ????????? PyME was created by John Goerzen, and maintained, developed, and - cherished by Igor Belyi, Martin Albrecht, Ben McGinnes, and everyone - who contributed to it in any way. + cherished by Igor Belyi, Martin Albrecht, Ben McGinnes, Justus + Winter, and everyone who contributed to it in any way. In 2016 we merged a port of PyME to into the GPGME repository, and development will continue there. Please see the VCS history for the diff --git a/lang/python/README.org b/lang/python/README.org index cba9966..df6c63d 100644 --- a/lang/python/README.org +++ b/lang/python/README.org @@ -27,8 +27,8 @@ Please report bugs using our bug tracker * Authors PyME was created by John Goerzen, and maintained, developed, and -cherished by Igor Belyi, Martin Albrecht, Ben McGinnes, and everyone -who contributed to it in any way. +cherished by Igor Belyi, Martin Albrecht, Ben McGinnes, Justus Winter, +and everyone who contributed to it in any way. In 2016 we merged a port of PyME to into the GPGME repository, and development will continue there. Please see the VCS history for the diff --git a/lang/python/docs/GPGMEpythonHOWTOen.org b/lang/python/docs/GPGMEpythonHOWTOen.org index 6a3f9db..5fa0136 100644 --- a/lang/python/docs/GPGMEpythonHOWTOen.org +++ b/lang/python/docs/GPGMEpythonHOWTOen.org @@ -14,7 +14,7 @@ :CUSTOM_ID: intro :END: - | Version: | 0.1.1 | + | Version: | 0.1.2 | | Author: | Ben McGinnes | | Author GPG Key: | DB4724E6FA4286C92B4E55C4321E4E2373590E5D | | Language: | Australian English, British English | @@ -247,7 +247,7 @@ =python=, =python2= and =python2.7=. For Python 3 it checks for these executables in this order: - =python3=, =python3.6=, =python3.5= and =python3.4=. + =python3=, =python3.6=, =python3.5=, =python3.4= and =python3.7=.[fn:4] *** Installing GPGME @@ -1777,3 +1777,7 @@ keyservers for "gnupg.org" produces over 400 results, the majority of which aren't actually at the gnupg.org domain, but just included a comment regarding the project in their key somewhere. + +[fn:4] As Python 3.7 is a very recent release, it is not given +priority over 3.6 yet, but will probably be prioritised by the release +of Python 3.7.2. diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index 2595073..0622b61 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -246,6 +246,7 @@ setup(name="gpg", 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Operating System :: POSIX', 'Operating System :: Microsoft :: Windows', 'Topic :: Communications :: Email', diff --git a/m4/python.m4 b/m4/python.m4 index 822b2dd..db7b482 100644 --- a/m4/python.m4 +++ b/m4/python.m4 @@ -39,8 +39,12 @@ AC_DEFUN([AM_PATH_PYTHON], m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python2 python2.7 dnl python dnl - python3 python3.0 python3.1 python3.2 python3.3 dnl - python3.4 python3.5 python3.6 python3.7 python3.8]) + dnl old listing was pointless since biundings only work from Python 3.4: + dnl python3 python3.0 python3.1 python3.2 python3.3 + dnl move 3.7 to the front once 3.7.1 or 3.7.2 is released: + dnl python3 python3.7 python3.6 python3.5 python3.4 python3.8]) + dnl until then: + python3 python3.6 python3.5 python3.4 python3.7 python3.8]) AC_ARG_VAR([PYTHON], [the Python interpreter]) ----------------------------------------------------------------------- Summary of changes: lang/python/README | 4 ++-- lang/python/README.org | 4 ++-- lang/python/docs/GPGMEpythonHOWTOen.org | 8 ++++++-- lang/python/setup.py.in | 1 + m4/python.m4 | 7 ++++--- 5 files changed, 15 insertions(+), 9 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org