From cvs at cvs.gnupg.org Fri Feb 1 09:00:07 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 01 Feb 2019 09:00:07 +0100 Subject: [git] gnupg-doc - branch, master, updated. 3b721c063430fe7010fdea837ca758b6aae9056e 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 3b721c063430fe7010fdea837ca758b6aae9056e (commit) from fb85cfe7f6df8bde8e942d97fb42d93630a7c3c8 (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 3b721c063430fe7010fdea837ca758b6aae9056e Author: Werner Koch Date: Fri Feb 1 08:59:56 2019 +0100 web: Change URL of g10 Code in the service page. diff --git a/web/service.org b/web/service.org index 07f533a..5f6cdfd 100644 --- a/web/service.org +++ b/web/service.org @@ -40,10 +40,10 @@ provide this list to enable you to contact service providers. The companies listed here provide mainly technical support and consulting. - - [[http://g10code.com][g10 Code GmbH]], D?sseldorf, Germany :: Offers customized - development, porting to new platforms, help with integrating - GnuPG into your own projects, code audits, and more. g10 Code - is owned and run by GnuPG's principal author. + - [[http://gnupg.com][g10 Code GmbH]], D?sseldorf, Germany :: Offers commercial grade + support, customized development, porting to new platforms, help + with integrating GnuPG into customer projects, code audits, and + more. g10^code is owned and run by GnuPG?s principal author. - [[http://josefsson.org/][Simon Josefsson Datakonsult]], Stockholm, Sweden :: Offers integration of OpenPGP technology in TLS, Kerberos, e-mail, and SASL. Does customized development, porting to new platforms, ----------------------------------------------------------------------- Summary of changes: web/service.org | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 1 11:54:11 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 01 Feb 2019 11:54:11 +0100 Subject: [git] gnupg-doc - branch, master, updated. 30a5a4deafeac28a461a2903a5deb2644f6ceeb0 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 30a5a4deafeac28a461a2903a5deb2644f6ceeb0 (commit) from 3b721c063430fe7010fdea837ca758b6aae9056e (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 30a5a4deafeac28a461a2903a5deb2644f6ceeb0 Author: Werner Koch Date: Fri Feb 1 11:54:00 2019 +0100 web: Try to fix sub-menus for touch screens They don't work with Fennec on my tablet, despite that FF's responsive design tool can't emulate that behaviour. diff --git a/web/share/gpgweb.el b/web/share/gpgweb.el index 8c968c9..8436472 100644 --- a/web/share/gpgweb.el +++ b/web/share/gpgweb.el @@ -185,11 +185,20 @@ if not available. If CUSTOM is true only a minimal header is set." (let ((item (car menu))) (when item (dotimes (i (1+ lvl)) (insert " ")) - (insert "
  • " (cadr item) "\n") + (if (caddr item) + (progn + (insert "
  • " (cadr item) "\n")) + (progn + (insert "
  • " (cadr item) "\n"))) (when (caddr item) (dotimes (i (1+ lvl)) (insert " ")) (insert "
      \n") diff --git a/web/share/site.css b/web/share/site.css index c075577..82afa8e 100644 --- a/web/share/site.css +++ b/web/share/site.css @@ -237,6 +237,13 @@ a:link { text-decoration: none; } +.topmenuitem { + padding: 10px; + color: #757575; + font-weight: bold; + text-decoration: none; +} + nav ul, ul ul.sub-menu { margin: 0; @@ -285,7 +292,7 @@ nav ul li:hover ul.sub-menu { z-index: 99; border-radius: 0px; position: absolute; - top: 37px; + top: 28px; left: 0; } nav ul ul li { ----------------------------------------------------------------------- Summary of changes: web/share/gpgweb.el | 19 ++++++++++++++----- web/share/site.css | 9 ++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 1 12:09:03 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 01 Feb 2019 12:09:03 +0100 Subject: [git] gnupg-doc - branch, master, updated. 2c267afb8c8199fd570fa74174a86b987725fdba 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 2c267afb8c8199fd570fa74174a86b987725fdba (commit) from 30a5a4deafeac28a461a2903a5deb2644f6ceeb0 (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 2c267afb8c8199fd570fa74174a86b987725fdba Author: Werner Koch Date: Fri Feb 1 12:09:00 2019 +0100 web: Fix top menu alignment. With this it again possible to select the sub-menu. Don't known when this regression started. We should move to a simpler menu system. diff --git a/web/share/site.css b/web/share/site.css index 82afa8e..3643846 100644 --- a/web/share/site.css +++ b/web/share/site.css @@ -292,7 +292,7 @@ nav ul li:hover ul.sub-menu { z-index: 99; border-radius: 0px; position: absolute; - top: 28px; + /*top: 28px;*/ left: 0; } nav ul ul li { ----------------------------------------------------------------------- Summary of changes: web/share/site.css | 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 Mon Feb 4 11:50:47 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 04 Feb 2019 11:50:47 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.35-3-g21dd885 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 "Error codes used by GnuPG et al.". The branch, master has been updated via 21dd885eecdee13da1689519e2fc50fcf64f6ef2 (commit) from d8b64613d992fd3b7bf13eb299db21a307c8bfa1 (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 21dd885eecdee13da1689519e2fc50fcf64f6ef2 Author: Werner Koch Date: Mon Feb 4 11:50:17 2019 +0100 build: Fix for Microsoft MSVC. * src/gpgrt-int.h (_gpgrt_functions_w32_pollable): Declare with extern so that strict toolchains don't get confused. -- GnuPG-bug-id: 4356 Signed-off-by: Werner Koch diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index 08496b2..c6188e1 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -473,8 +473,8 @@ const char *_gpgrt_fname_get (gpgrt_stream_t stream); #if HAVE_W32_SYSTEM -/* Prototypes for w32-estream.c. */ -struct cookie_io_functions_s _gpgrt_functions_w32_pollable; +/* Prototypes for w32-estream.c. */ +extern struct cookie_io_functions_s _gpgrt_functions_w32_pollable; int _gpgrt_w32_pollable_create (void *_GPGRT__RESTRICT *_GPGRT__RESTRICT cookie, unsigned int modeflags, struct cookie_io_functions_s next_functions, ----------------------------------------------------------------------- Summary of changes: src/gpgrt-int.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 6 09:04:13 2019 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 06 Feb 2019 09:04:13 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.12-20-g9109bb9 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 9109bb9919f84d5472b7e62e84b961414a79d3c2 (commit) via 7f4c3eb0a039621c564b6095ab5f810524843157 (commit) from 900ae94797ed3cafe1a31aed8aa009696c9da9f8 (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 9109bb9919f84d5472b7e62e84b961414a79d3c2 Author: NIIBE Yutaka Date: Mon Jan 28 12:58:13 2019 +0900 agent: Clear bogus pinentry cache, when it causes an error. * agent/agent.h (PINENTRY_STATUS_*): Expose to public. (struct pin_entry_info_s): Add status. * agent/call-pinentry.c (agent_askpin): Clearing the ->status before the loop, let the assuan_transact set ->status. When failure with PINENTRY_STATUS_PASSWORD_FROM_CACHE, it returns soon. * agent/findkey.c (unprotect): Clear the pinentry cache, when it causes an error. -- Cherry-picked from master commit of: 02a2633a7f0b7d91aa48ea615fb3a0edfd6ed6bb Debian-bug-id: 919856 GnuPG-bug-id: 4348 Signed-off-by: NIIBE Yutaka diff --git a/agent/agent.h b/agent/agent.h index 2b045f8..58dd7df 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -265,6 +265,14 @@ struct server_control_s }; +/* Status of pinentry. */ +enum + { + PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0, + PINENTRY_STATUS_PIN_REPEATED = 1 << 8, + PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9 + }; + /* Information pertaining to pinentry requests. */ struct pin_entry_info_s { @@ -274,7 +282,8 @@ struct pin_entry_info_s int failed_tries; /* Number of tries so far failed. */ int with_qualitybar; /* Set if the quality bar should be displayed. */ int with_repeat; /* Request repetition of the passphrase. */ - int repeat_okay; /* Repetition worked. */ + int repeat_okay; /* Repetition worked. */ + unsigned int status; /* Status. */ gpg_error_t (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */ void *check_cb_arg; /* optional argument which might be of use in the CB */ diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index b68d0a8..1f3bd52 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -891,13 +891,6 @@ setup_qualitybar (ctrl_t ctrl) return 0; } -enum - { - PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0, - PINENTRY_STATUS_PIN_REPEATED = 1 << 8, - PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9 - }; - /* Check the button_info line for a close action. Also check for the PIN_REPEATED flag. */ static gpg_error_t @@ -962,7 +955,6 @@ agent_askpin (ctrl_t ctrl, const char *errtext = NULL; int is_pin = 0; int saveflag; - unsigned int pinentry_status; if (opt.batch) return 0; /* fixme: we should return BAD PIN */ @@ -1073,6 +1065,7 @@ agent_askpin (ctrl_t ctrl, pininfo->with_repeat = 0; /* Pinentry does not support it. */ } pininfo->repeat_okay = 0; + pininfo->status = 0; for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++) { @@ -1106,10 +1099,9 @@ agent_askpin (ctrl_t ctrl, saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); assuan_begin_confidential (entry_ctx); - pinentry_status = 0; rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, inq_quality, entry_ctx, - pinentry_status_cb, &pinentry_status); + pinentry_status_cb, &pininfo->status); assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and @@ -1121,7 +1113,7 @@ agent_askpin (ctrl_t ctrl, /* Change error code in case the window close button was clicked to cancel the operation. */ - if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON) + if ((pininfo->status & PINENTRY_STATUS_CLOSE_BUTTON) && gpg_err_code (rc) == GPG_ERR_CANCELED) rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED); @@ -1148,12 +1140,19 @@ agent_askpin (ctrl_t ctrl, /* More checks by utilizing the optional callback. */ pininfo->cb_errtext = NULL; rc = pininfo->check_cb (pininfo); - if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE - && pininfo->cb_errtext) - errtext = pininfo->cb_errtext; - else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE - || gpg_err_code (rc) == GPG_ERR_BAD_PIN) - errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase")); + /* When pinentry cache causes an error, return now. */ + if (rc + && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) + return unlock_pinentry (ctrl, rc); + + if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE) + { + if (pininfo->cb_errtext) + errtext = pininfo->cb_errtext; + else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE + || gpg_err_code (rc) == GPG_ERR_BAD_PIN) + errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase")); + } else if (rc) return unlock_pinentry (ctrl, rc); } @@ -1161,12 +1160,12 @@ agent_askpin (ctrl_t ctrl, if (!errtext) { if (pininfo->with_repeat - && (pinentry_status & PINENTRY_STATUS_PIN_REPEATED)) + && (pininfo->status & PINENTRY_STATUS_PIN_REPEATED)) pininfo->repeat_okay = 1; return unlock_pinentry (ctrl, 0); /* okay, got a PIN or passphrase */ } - if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) + if ((pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) /* The password was read from the cache. Don't count this against the retry count. */ pininfo->failed_tries --; diff --git a/agent/findkey.c b/agent/findkey.c index 78c3b1a..89a18fa 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -632,7 +632,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, pi->check_cb_arg = &arg; rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode); - if (!rc) + if (rc) + { + if ((pi->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) + { + log_error ("Clearing pinentry cache which caused error %s\n", + gpg_strerror (rc)); + + agent_clear_passphrase (ctrl, hexgrip, cache_mode); + } + } + else { assert (arg.unprotected_key); if (arg.change_required) commit 7f4c3eb0a039621c564b6095ab5f810524843157 Author: NIIBE Yutaka Date: Fri Jan 25 10:15:39 2019 +0900 dirmngr: Fix initialization of assuan's nPth hook. * dirmngr/dirmngr.c (main): Move assuan_set_system_hooks to... (thread_init): ... here. -- Cherry picked master commit of: 1f8817475f59ede3f28f57edc10ba56bbdd08b49 Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 55c7a49..667308c 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -802,6 +802,7 @@ static void thread_init (void) { npth_init (); + assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); /* Now with NPth running we can set the logging callback. Our @@ -877,7 +878,6 @@ main (int argc, char **argv) assuan_set_malloc_hooks (&malloc_hooks); assuan_set_assuan_log_prefix (log_get_prefix (NULL)); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug, dirmngr_assuan_log_monitor); ----------------------------------------------------------------------- Summary of changes: agent/agent.h | 11 ++++++++++- agent/call-pinentry.c | 37 ++++++++++++++++++------------------- agent/findkey.c | 12 +++++++++++- dirmngr/dirmngr.c | 2 +- 4 files changed, 40 insertions(+), 22 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 6 09:16:36 2019 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 06 Feb 2019 09:16:36 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.12-21-gc16685b 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 c16685b2f5021105ef0560cb3db68ef43bcdb9c1 (commit) from 9109bb9919f84d5472b7e62e84b961414a79d3c2 (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 c16685b2f5021105ef0560cb3db68ef43bcdb9c1 Author: NIIBE Yutaka Date: Wed Feb 6 17:15:25 2019 +0900 po: Update Japanese translation. Signed-off-by: NIIBE Yutaka diff --git a/po/ja.po b/po/ja.po index a17e88d..baee865 100644 --- a/po/ja.po +++ b/po/ja.po @@ -8,9 +8,9 @@ # msgid "" msgstr "" -"Project-Id-Version: gnupg 2.2.9\n" +"Project-Id-Version: gnupg 2.2.13\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2018-09-18 09:58+0900\n" +"PO-Revision-Date: 2019-02-06 17:14+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -203,9 +203,11 @@ msgstr "PUK" msgid "Reset Code" msgstr "????????" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." -msgstr "%s%%0A%%0A??????????????????????" +msgid "Push ACK button on card/token." +msgstr "???/?????ACK????????????" + +msgid "Use the reader's pinpad for input." +msgstr "??????????????????????" msgid "Repeat this Reset Code" msgstr "???????????????????????" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 6 09:47:12 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Feb 2019 09:47:12 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-353-ge9e876c 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 e9e876cb5572670322aa1d3462d64c75c03974d9 (commit) via 3231ecdafd71ac47b734469b07170756979ede72 (commit) from 1c0fa3e6f74692d5e9b5f08cda523f0fcec305eb (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 e9e876cb5572670322aa1d3462d64c75c03974d9 Author: Werner Koch Date: Wed Feb 6 09:45:54 2019 +0100 scd: Implement PIN changing and unblocking for PIV cards. * scd/app-piv.c: Some refactoring (do_change_chv): Implement. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index d34ff7d..42f16de 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -20,6 +20,24 @@ /* Some notes: * - Specs for PIV are at http://dx.doi.org/10.6028/NIST.SP.800-73-4 * + * - Access control matrix: + * | Action | 9B | PIN | PUK | | + * |--------------+-----+-----+-----+------------------------------| + * | Generate key | yes | | | | + * | Change 9B | yes | | | | + * | Change retry | yes | yes | | Yubikey only | + * | Import key | yes | | | | + * | Import cert | yes | | | | + * | Change CHUID | yes | | | | + * | Reset card | | | | PIN and PUK in blocked state | + * | Verify PIN | | yes | | | + * | Sign data | | yes | | | + * | Decrypt data | | yes | | | + * | Change PIN | | yes | | | + * | Change PUK | | | yes | | + * | Unblock PIN | | | yes | New PIN required | + * |---------------------------------------------------------------| + * (9B indicates the 24 byte PIV Card Application Administration Key) */ #include @@ -389,10 +407,10 @@ dump_all_do (int slot) /* Parse the key reference KEYREFSTR which is expected to hold a key - * reference for a PIN object. Return the one octet keyref or -1 for + * reference for a CHV object. Return the one octet keyref or -1 for * an invalid reference. */ static int -parse_pin_keyref (const char *keyrefstr) +parse_chv_keyref (const char *keyrefstr) { if (!keyrefstr) return -1; @@ -457,7 +475,7 @@ get_chv_status (app_t app, const char *keyrefstr) int result; int keyref; - keyref = parse_pin_keyref (keyrefstr); + keyref = parse_chv_keyref (keyrefstr); if (!keyrefstr) return -1; @@ -467,7 +485,7 @@ get_chv_status (app_t app, const char *keyrefstr) apdu[3] = keyref; if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) result = -5; /* No need to verification. */ - else if (sw == 0x6a88) + else if (sw == 0x6a88 || sw == 0x6a80) result = -2; /* No such PIN. */ else if (sw == 0x6983) result = -3; /* PIN is blocked. */ @@ -540,7 +558,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) } else if (table[idx].special == -4) /* CHV-STATUS */ { - int tmp[3]; + int tmp[4]; tmp[0] = get_chv_status (app, "PIV.00"); tmp[1] = get_chv_status (app, "PIV.80"); @@ -1177,40 +1195,29 @@ make_prompt (app_t app, int remaining, const char *firstline) } -/* Verify the Application PIN KEYREF. */ +/* Helper for verify_chv to ask for the PIN and to prepare/pad it. On + * success the result is stored at (R_PIN,R_PINLEN). */ static gpg_error_t -verify_pin (app_t app, int keyref, - gpg_error_t (*pincb)(void*,const char *,char **), void *pincb_arg) +ask_and_prepare_chv (app_t app, int keyref, int ask_new, int remaining, + gpg_error_t (*pincb)(void*,const char *,char **), + void *pincb_arg, char **r_pin, unsigned int *r_pinlen) { gpg_error_t err; - unsigned char apdu[4]; - unsigned int sw; - int remaining; const char *label; char *prompt; char *pinvalue = NULL; unsigned int pinlen; - char pinbuffer[8]; + char *pinbuffer = NULL; int minlen, maxlen, padding, onlydigits; - /* First check whether a verify is at all needed. This is done with - * P1 being 0 and no Lc and command data send. */ - apdu[0] = 0x00; - apdu[1] = ISO7816_VERIFY; - apdu[2] = 0x00; - apdu[3] = keyref; - if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) - { - /* No need to verification. */ - return 0; /* All fine. */ - } - if ((sw & 0xfff0) == 0x63C0) - remaining = (sw & 0x000f); /* PIN has REMAINING tries left. */ - else + *r_pin = NULL; + *r_pinlen = 0; + + if (ask_new) remaining = -1; if (remaining != -1) - log_debug ("piv: PIN %2X has %d attempts left\n", keyref, remaining); + log_debug ("piv: CHV %02X has %d attempts left\n", keyref, remaining); switch (keyref) { @@ -1219,21 +1226,24 @@ verify_pin (app_t app, int keyref, maxlen = 8; padding = 1; onlydigits = 1; - label = _("||Please enter the Global-PIN of your PIV card"); + label = (ask_new? _("|N|Please enter the new Global-PIN") + /**/ : _("||Please enter the Global-PIN of your PIV card")); break; case 0x80: minlen = 6; maxlen = 8; padding = 1; onlydigits = 1; - label = _("||Please enter the PIN of your PIV card"); + label = (ask_new? _("|N|Please enter the new PIN") + /**/ : _("||Please enter the PIN of your PIV card")); break; case 0x81: minlen = 8; maxlen = 8; padding = 0; onlydigits = 0; - label = _("||Please enter the Unblocking Key of your PIV card"); + label = (ask_new? _("|N|Please enter the new Unblocking Key") + /**/ :_("||Please enter the Unblocking Key of your PIV card")); break; case 0x96: @@ -1245,8 +1255,6 @@ verify_pin (app_t app, int keyref, default: return gpg_error (GPG_ERR_INV_ID); } - log_assert (sizeof pinbuffer >= maxlen); - /* Ask for the PIN. */ prompt = make_prompt (app, remaining, label); @@ -1282,21 +1290,72 @@ verify_pin (app_t app, int keyref, xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } + + pinbuffer = xtrymalloc_secure (maxlen); + if (!pinbuffer) + { + err = gpg_error_from_syserror (); + wipememory (pinvalue, pinlen); + xfree (pinvalue); + return err; + } + memcpy (pinbuffer, pinvalue, pinlen); + wipememory (pinvalue, pinlen); + xfree (pinvalue); if (padding) { memset (pinbuffer + pinlen, 0xff, maxlen - pinlen); - wipememory (pinvalue, pinlen); pinlen = maxlen; } + + *r_pin = pinbuffer; + *r_pinlen = pinlen; + + return 0; +} + + +/* Verify the card holder verification identified by KEYREF. This is + * either the Appication PIN or the Global PIN. */ +static gpg_error_t +verify_chv (app_t app, int keyref, + gpg_error_t (*pincb)(void*,const char *,char **), void *pincb_arg) +{ + gpg_error_t err; + unsigned char apdu[4]; + unsigned int sw; + int remaining; + char *pin = NULL; + unsigned int pinlen; + + /* First check whether a verify is at all needed. This is done with + * P1 being 0 and no Lc and command data send. */ + apdu[0] = 0x00; + apdu[1] = ISO7816_VERIFY; + apdu[2] = 0x00; + apdu[3] = keyref; + if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) + { + /* No need to verification. */ + return 0; /* All fine. */ + } + if ((sw & 0xfff0) == 0x63C0) + remaining = (sw & 0x000f); /* PIN has REMAINING tries left. */ else - wipememory (pinvalue, pinlen); - xfree (pinvalue); + remaining = -1; - err = iso7816_verify (app->slot, keyref, pinbuffer, pinlen); - wipememory (pinbuffer, pinlen); + err = ask_and_prepare_chv (app, keyref, 0, remaining, pincb, pincb_arg, + &pin, &pinlen); if (err) - log_error ("PIN %02X verification failed: %s\n", keyref,gpg_strerror (err)); + return err; + + err = iso7816_verify (app->slot, keyref, pin, pinlen); + wipememory (pin, pinlen); + xfree (pin); + if (err) + log_error ("CHV %02X verification failed: %s\n", + keyref, gpg_strerror (err)); return err; } @@ -1309,40 +1368,41 @@ verify_pin (app_t app, int keyref, * PIV.81 - The PIN Unblocking key * The supported flags are: * APP_CHANGE_FLAG_CLEAR Clear the PIN verification state. + * APP_CHANGE_FLAG_RESET Reset a PIN using the PUK. Only + * allowed with PIV.80. */ static gpg_error_t -do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr, +do_change_chv (app_t app, ctrl_t ctrl, const char *pwidstr, unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { gpg_error_t err; - int keyref; + int keyref, targetkeyref; unsigned char apdu[4]; - - char *newpin = NULL; + unsigned int sw; + int remaining; char *oldpin = NULL; - /* size_t newpinlen; */ - /* size_t oldpinlen; */ - /* const char *newdesc; */ - /* int pwid; */ - pininfo_t pininfo; + unsigned int oldpinlen; + char *newpin = NULL; + unsigned int newpinlen; (void)ctrl; - (void)pincb; - (void)pincb_arg; - /* The minimum and maximum lengths are enforced by PIV. */ - memset (&pininfo, 0, sizeof pininfo); - pininfo.minlen = 6; - pininfo.maxlen = 8; + /* Check for unknown flags. */ + if ((flags & ~(APP_CHANGE_FLAG_CLEAR|APP_CHANGE_FLAG_RESET))) + { + err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + goto leave; + } - keyref = parse_pin_keyref (pwidstr); + /* Parse the keyref. */ + targetkeyref = keyref = parse_chv_keyref (pwidstr); if (keyref == -1) - return gpg_error (GPG_ERR_INV_ID); - - if ((flags & ~APP_CHANGE_FLAG_CLEAR)) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + { + err = gpg_error (GPG_ERR_INV_ID); + goto leave; + } /* First see whether the special --clear mode has been requested. */ if ((flags & APP_CHANGE_FLAG_CLEAR)) @@ -1355,7 +1415,82 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr, goto leave; } - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* Prepare reset mode. */ + if ((flags & APP_CHANGE_FLAG_RESET)) + { + if (keyref == 0x81) + { + err = gpg_error (GPG_ERR_INV_ID); /* Can't reset the PUK. */ + goto leave; + } + /* Set the keyref to the PUK and keep the TARGETKEYREF. */ + keyref = 0x81; + } + + /* Get the remaining tries count. This is done by using the check + * for verified state feature. */ + apdu[0] = 0x00; + apdu[1] = ISO7816_VERIFY; + apdu[2] = 0x00; + apdu[3] = keyref; + if (!iso7816_apdu_direct (app->slot, apdu, 4, 0, &sw, NULL, NULL)) + remaining = -1; /* Already verified, thus full number of tries. */ + else if ((sw & 0xfff0) == 0x63C0) + remaining = (sw & 0x000f); /* PIN has REMAINING tries left. */ + else + remaining = -1; + + /* Ask for the old pin or puk. */ + err = ask_and_prepare_chv (app, keyref, 0, remaining, pincb, pincb_arg, + &oldpin, &oldpinlen); + if (err) + return err; + + /* Verify the old pin so that we don't prompt for the new pin if the + * old is wrong. This is not possible for the PUK, though. */ + if (keyref != 0x81) + { + err = iso7816_verify (app->slot, keyref, oldpin, oldpinlen); + if (err) + { + log_error ("CHV %02X verification failed: %s\n", + keyref, gpg_strerror (err)); + goto leave; + } + } + + /* Ask for the new pin. */ + err = ask_and_prepare_chv (app, targetkeyref, 1, -1, pincb, pincb_arg, + &newpin, &newpinlen); + if (err) + return err; + + if ((flags & APP_CHANGE_FLAG_RESET)) + { + char *buf = xtrymalloc_secure (oldpinlen + newpinlen); + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (buf, oldpin, oldpinlen); + memcpy (buf+oldpinlen, newpin, newpinlen); + err = iso7816_reset_retry_counter_with_rc (app->slot, targetkeyref, + buf, oldpinlen+newpinlen); + xfree (buf); + if (err) + log_error ("resetting CHV %02X using CHV %02X failed: %s\n", + targetkeyref, keyref, gpg_strerror (err)); + } + else + { + err = iso7816_change_reference_data (app->slot, keyref, + oldpin, oldpinlen, + newpin, newpinlen); + if (err) + log_error ("CHV %02X changing PIN failed: %s\n", + keyref, gpg_strerror (err)); + } leave: xfree (oldpin); @@ -1365,19 +1500,19 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr, /* Perform a simple verify operation for the PIN specified by PWIDSTR. - * For valid values see do_change_pin. */ + * For valid values see do_change_chv. */ static gpg_error_t -do_check_pin (app_t app, const char *pwidstr, +do_check_chv (app_t app, const char *pwidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { int keyref; - keyref = parse_pin_keyref (pwidstr); + keyref = parse_chv_keyref (pwidstr); if (keyref == -1) return gpg_error (GPG_ERR_INV_ID); - return verify_pin (app, keyref, pincb, pincb_arg); + return verify_chv (app, keyref, pincb, pincb_arg); } @@ -1492,7 +1627,7 @@ do_auth (app_t app, const char *keyidstr, } /* Now verify the Application PIN. */ - err = verify_pin (app, 0x80, pincb, pincb_arg); + err = verify_chv (app, 0x80, pincb, pincb_arg); if (err) return err; @@ -1675,8 +1810,8 @@ app_select_piv (app_t app) /* app->fnc.sign = do_sign; */ app->fnc.auth = do_auth; /* app->fnc.decipher = do_decipher; */ - app->fnc.change_pin = do_change_pin; - app->fnc.check_pin = do_check_pin; + app->fnc.change_pin = do_change_chv; + app->fnc.check_pin = do_check_chv; leave: diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 1c4413b..fd7aa9a 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -899,7 +899,7 @@ list_piv (card_info_t info, estream_t fp) switch (info->chvinfo[i]) { case -1: s = "[error]"; break; - case -2: s = "-"; break; /* No such PIN */ + case -2: s = "-"; break; /* No such PIN or info not available. */ case -3: s = "[blocked]"; break; case -5: s = "[verified]"; break; default: s = "[?]"; break; @@ -950,15 +950,21 @@ static gpg_error_t cmd_verify (card_info_t info, char *argstr) { gpg_error_t err; + const char *pinref; if (!info) return print_help ("verify [chvid]", 0); - if (info->apptype == APP_TYPE_OPENPGP) - err = scd_checkpin (info->serialno); + if (*argstr) + pinref = argstr; + else if (info->apptype == APP_TYPE_OPENPGP) + pinref = info->serialno; + else if (info->apptype == APP_TYPE_PIV) + pinref = "PIV.80"; else - err = scd_checkpin (argstr); + return gpg_error (GPG_ERR_MISSING_VALUE); + err = scd_checkpin (pinref); if (err) log_error ("verify failed: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); @@ -1845,30 +1851,48 @@ cmd_generate (card_info_t info) /* Sub-menu to change a PIN. The presented options may depend on the * the ALLOW_ADMIN flag. */ static gpg_error_t -cmd_passwd (card_info_t info, int allow_admin) +cmd_passwd (card_info_t info, int allow_admin, char *argstr) { gpg_error_t err; char *answer = NULL; + const char *pinref; if (!info) return print_help - ("PASSWD\n\n" + ("PASSWD [PINREF]\n\n" "Menu to change or unblock the PINs. Note that the\n" "presented menu options depend on the type of card\n" - "and whether the admin mode is enabled.", + "and whether the admin mode is enabled. For OpenPGP\n" + "and PIV cards defaults for PINREF are available.", 0); - /* Convenience message because we did this in gpg --card-edit too. */ - if (info->apptype == APP_TYPE_OPENPGP) - log_info (_("OpenPGP card no. %s detected\n"), + if (opt.interactive || opt.verbose) + log_info (_("%s card no. %s detected\n"), + app_type_string (info->apptype), info->dispserialno? info->dispserialno : info->serialno); - if (!allow_admin) + if (!allow_admin || info->apptype != APP_TYPE_OPENPGP) { - err = scd_change_pin ("OPENPGP.1", 0); + if (*argstr) + pinref = argstr; + else if (info->apptype == APP_TYPE_OPENPGP) + pinref = "OPENPGP.1"; + else if (info->apptype == APP_TYPE_PIV) + pinref = "PIV.80"; + else + { + err = gpg_error (GPG_ERR_MISSING_VALUE); + goto leave; + } + err = scd_change_pin (pinref, 0); if (err) goto leave; - log_info ("PIN changed.\n"); + + if (info->apptype == APP_TYPE_PIV + && !ascii_strcasecmp (pinref, "PIV.81")) + log_info ("PUK changed.\n"); + else + log_info ("PIN changed.\n"); } else if (info->apptype == APP_TYPE_OPENPGP) { @@ -1959,23 +1983,43 @@ cmd_unblock (card_info_t info) "command can be used to set a new PIN.", 0); - if (info->apptype == APP_TYPE_OPENPGP) - log_info (_("OpenPGP card no. %s detected\n"), + if (opt.interactive || opt.verbose) + log_info (_("%s card no. %s detected\n"), + app_type_string (info->apptype), info->dispserialno? info->dispserialno : info->serialno); - if (info->apptype == APP_TYPE_OPENPGP && !info->is_v2) - log_error (_("This command is only available for version 2 cards\n")); - else if (info->apptype == APP_TYPE_OPENPGP && !info->chvinfo[1]) - log_error (_("Reset Code not or not anymore available\n")); - else if (info->apptype == APP_TYPE_OPENPGP) + if (info->apptype == APP_TYPE_OPENPGP) { - err = scd_change_pin ("OPENPGP.2", 0); + if (!info->is_v2) + { + log_error (_("This command is only available for version 2 cards\n")); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + } + else if (!info->chvinfo[1]) + { + log_error (_("Reset Code not or not anymore available\n")); + err = gpg_error (GPG_ERR_PIN_BLOCKED); + } + else + { + err = scd_change_pin ("OPENPGP.2", 0); + if (!err) + log_info ("PIN changed.\n"); + } + } + else if (info->apptype == APP_TYPE_PIV) + { + /* Unblock the Application PIN. */ + err = scd_change_pin ("PIV.80", 1); if (!err) - log_info ("PIN changed.\n"); + log_info ("PIN unblocked and changed.\n"); } else - log_info ("Unblocking not yet supported for '%s'\n", - app_type_string (info->apptype)); + { + log_info ("Unblocking not yet supported for '%s'\n", + app_type_string (info->apptype)); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } return err; } @@ -2079,15 +2123,15 @@ cmd_factoryreset (card_info_t info) goto leave; } + if (opt.interactive || opt.verbose) + log_info (_("%s card no. %s detected\n"), + app_type_string (info->apptype), + info->dispserialno? info->dispserialno : info->serialno); + if (!termstate || is_yubikey) { - if (is_yubikey) - log_info (_("Yubikey no. %s with PIV application detected\n"), - info->dispserialno? info->dispserialno : info->serialno); - else + if (!is_yubikey) { - log_info (_("OpenPGP card no. %s detected\n"), - info->dispserialno? info->dispserialno : info->serialno); if (!(info->status_indicator == 3 || info->status_indicator == 5)) { /* Note: We won't see status-indicator 3 here because it @@ -2865,7 +2909,7 @@ dispatch_command (card_info_t info, const char *orig_command) case cmdREADCERT: err = cmd_readcert (info, argstr); break; case cmdFORCESIG: err = cmd_forcesig (info); break; case cmdGENERATE: err = cmd_generate (info); break; - case cmdPASSWD: err = cmd_passwd (info, 1); break; + case cmdPASSWD: err = cmd_passwd (info, 1, argstr); break; case cmdUNBLOCK: err = cmd_unblock (info); break; case cmdFACTORYRESET: err = cmd_factoryreset (info); break; case cmdKDFSETUP: err = cmd_kdfsetup (info, argstr); break; @@ -3131,7 +3175,7 @@ interactive_loop (void) case cmdREADCERT: err = cmd_readcert (info, argstr); break; case cmdFORCESIG: err = cmd_forcesig (info); break; case cmdGENERATE: err = cmd_generate (info); break; - case cmdPASSWD: err = cmd_passwd (info, allow_admin); break; + case cmdPASSWD: err = cmd_passwd (info, allow_admin, argstr); break; case cmdUNBLOCK: err = cmd_unblock (info); break; case cmdFACTORYRESET: err = cmd_factoryreset (info); commit 3231ecdafd71ac47b734469b07170756979ede72 Author: Werner Koch Date: Tue Feb 5 14:48:49 2019 +0100 scd: Allow standard keyref scheme for app-openpgp. * scd/app-openpgp.c (do_change_pin): Allow prefixing the CHVNO with "OPENPGP." * tools/card-call-scd.c (scd_change_pin): Change API to use strings. * tools/gpg-card-tool.c (cmd_passwd): Adjust for change. (cmd_unblock): Ditto. -- The generic keyref allows for better error detection in case a keyref is send to a wrong card. Signed-off-by: Werner Koch diff --git a/doc/wks.texi b/doc/wks.texi index a0b2a34..f132b31 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -124,7 +124,7 @@ Requires installation of that command. @item --with-colons @opindex with-colons This option has currently only an effect on the @option{--supported} -command. If it is used all arguimenst on the command line are taken +command. If it is used all arguments on the command line are taken as domain names and tested for WKD support. The output format is one line per domain with colon delimited fields. The currently specified fields are (future versions may specify additional fields): diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index dbc51be..72ed80a 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2583,6 +2583,8 @@ do_writecert (app_t app, ctrl_t ctrl, - 2 1 Verify CHV2 and set a new CHV1 and CHV2. - 2 2 Verify Reset Code and set a new PW1. - 3 any Verify CHV3/PW3 and set a new CHV3/PW3. + + The CHVNO can be prefixed with "OPENPGP.". */ static gpg_error_t do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, @@ -2591,7 +2593,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, void *pincb_arg) { int rc = 0; - int chvno = atoi (chvnostr); + int chvno; char *resetcode = NULL; char *oldpinvalue = NULL; char *pinvalue = NULL; @@ -2605,6 +2607,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, (void)ctrl; + if (digitp (chvnostr)) + chvno = atoi (chvnostr); + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.1")) + chvno = 1; + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.2")) + chvno = 2; + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.3")) + chvno = 3; + else + return gpg_error (GPG_ERR_INV_ID); + memset (&pininfo, 0, sizeof pininfo); pininfo.fixedlen = -1; pininfo.minlen = minlen; diff --git a/scd/iso7816.c b/scd/iso7816.c index c8a2138..69009c4 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -346,6 +346,7 @@ iso7816_change_reference_data (int slot, int chvno, sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA, oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); + wipememory (buf, oldchvlen+newchvlen); xfree (buf); return map_sw (sw); diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index c51282f..7add56d 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -1368,28 +1368,23 @@ scd_cardlist (strlist_t *result) * 101: Set a new PIN and reset the retry counter * 102: For v1 cars: Same as 101. * For v2 cards: Set a new Reset Code. - * SERIALNO is not used. */ gpg_error_t -scd_change_pin (int chvno) +scd_change_pin (const char *pinref, int reset_mode) { gpg_error_t err; char line[ASSUAN_LINELENGTH]; - const char *reset = ""; struct default_inq_parm_s dfltparm; memset (&dfltparm, 0, sizeof dfltparm); - if (chvno >= 100) - reset = "--reset"; - chvno %= 100; - err = start_agent (0); if (err) return err; dfltparm.ctx = agent_ctx; - snprintf (line, sizeof line, "SCD PASSWD %s %d", reset, chvno); + snprintf (line, sizeof line, "SCD PASSWD%s %s", + reset_mode? " --reset":"", pinref); err = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &dfltparm, diff --git a/tools/card-tool.h b/tools/card-tool.h index 9aca813..2707b3e 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -212,7 +212,7 @@ gpg_error_t scd_serialno (char **r_serialno, const char *demand); gpg_error_t scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen); gpg_error_t scd_cardlist (strlist_t *result); -gpg_error_t scd_change_pin (int chvno); +gpg_error_t scd_change_pin (const char *pinref, int reset_mode); gpg_error_t scd_checkpin (const char *serialno); unsigned long agent_get_s2k_count (void); diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 243ee55..1c4413b 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -1865,7 +1865,7 @@ cmd_passwd (card_info_t info, int allow_admin) if (!allow_admin) { - err = scd_change_pin (1); + err = scd_change_pin ("OPENPGP.1", 0); if (err) goto leave; log_info ("PIN changed.\n"); @@ -1896,7 +1896,7 @@ cmd_passwd (card_info_t info, int allow_admin) if (*answer == '1') { /* Change PIN (same as the direct thing in non-admin mode). */ - err = scd_change_pin (1); + err = scd_change_pin ("OPENPGP.1", 0); if (err) log_error ("Error changing the PIN: %s\n", gpg_strerror (err)); else @@ -1905,7 +1905,7 @@ cmd_passwd (card_info_t info, int allow_admin) else if (*answer == '2') { /* Unblock PIN by setting a new PIN. */ - err = scd_change_pin (101); + err = scd_change_pin ("OPENPGP.1", 1); if (err) log_error ("Error unblocking the PIN: %s\n", gpg_strerror(err)); else @@ -1914,7 +1914,7 @@ cmd_passwd (card_info_t info, int allow_admin) else if (*answer == '3') { /* Change Admin PIN. */ - err = scd_change_pin (3); + err = scd_change_pin ("OPENPGP.3", 0); if (err) log_error ("Error changing the PIN: %s\n", gpg_strerror (err)); else @@ -1923,7 +1923,7 @@ cmd_passwd (card_info_t info, int allow_admin) else if (*answer == '4') { /* Set a new Reset Code. */ - err = scd_change_pin (102); + err = scd_change_pin ("OPENPGP.2", 1); if (err) log_error ("Error setting the Reset Code: %s\n", gpg_strerror (err)); @@ -1969,7 +1969,7 @@ cmd_unblock (card_info_t info) log_error (_("Reset Code not or not anymore available\n")); else if (info->apptype == APP_TYPE_OPENPGP) { - err = scd_change_pin (2); + err = scd_change_pin ("OPENPGP.2", 0); if (!err) log_info ("PIN changed.\n"); } ----------------------------------------------------------------------- Summary of changes: doc/wks.texi | 2 +- scd/app-openpgp.c | 15 ++- scd/app-piv.c | 267 +++++++++++++++++++++++++++++++++++++------------- scd/iso7816.c | 1 + tools/card-call-scd.c | 11 +-- tools/card-tool.h | 2 +- tools/gpg-card-tool.c | 116 +++++++++++++++------- 7 files changed, 301 insertions(+), 113 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 6 10:37:09 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Feb 2019 10:37:09 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-354-g6c581cc 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 6c581cc468d7a1b860632b7a465d71224c6e4999 (commit) from e9e876cb5572670322aa1d3462d64c75c03974d9 (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 6c581cc468d7a1b860632b7a465d71224c6e4999 Author: Werner Koch Date: Wed Feb 6 10:37:03 2019 +0100 doc: Add basic man page for the gpg-card-tool. -- diff --git a/doc/Makefile.am b/doc/Makefile.am index cb69cd9..19b3825 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -69,7 +69,7 @@ nobase_dist_doc_DATA = FAQ DETAILS HACKING DCO TRANSLATE OpenPGP KEYSERVER \ gnupg_TEXINFOS = \ gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi instguide.texi \ tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \ - sysnotes.texi dirmngr.texi wks.texi \ + sysnotes.texi dirmngr.texi wks.texi card-tool.texi \ gnupg-module-overview.svg \ gnupg-card-architecture.fig \ howtos.texi howto-create-a-server-cert.texi @@ -89,12 +89,13 @@ YAT2M_OPTIONS = -I $(srcdir) \ --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard 2.2" myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \ - dirmngr.texi scdaemon.texi tools.texi wks.texi + dirmngr.texi scdaemon.texi tools.texi wks.texi \ + card-tool.texi myman_pages = gpgsm.1 gpg-agent.1 dirmngr.8 scdaemon.1 \ watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \ gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 gpgtar.1 \ applygnupgdefaults.8 gpg-wks-client.1 gpg-wks-server.1 \ - dirmngr-client.1 + dirmngr-client.1 gpg-card-tool.1 if USE_GPG2_HACK myman_pages += gpg2.1 gpgv2.1 else diff --git a/doc/card-tool.texi b/doc/card-tool.texi new file mode 100644 index 0000000..b84f207 --- /dev/null +++ b/doc/card-tool.texi @@ -0,0 +1,126 @@ + at c card-tool.texi - man page for gpg-card-tool + at c Copyright (C) 2019 g10 Code GmbH + at c This is part of the GnuPG manual. + at c For copying conditions, see the file GnuPG.texi. + + at include defs.inc + + at node Smart Card Tool + at chapter Smart Card Tool + +GnuPG comes with tool to administrate smart cards and USB tokens. This +tool is an extension of the @option{--edit-key} command available with + at command{gpg}. + + at menu +* gpg-card-tool:: Administrate smart cards. + at end menu + + at c + at c GPG-CARD-TOOL + at c + at manpage gpg-card-tool.1 + at node gpg-card-tool + at section Administrate smart cards. + at ifset manverb +.B gpg-card-tool +\- Administrate Smart Cards + at end ifset + + at mansect synopsis + at ifset manverb +.B gpg-card-tool +.RI [ options ] +.br +.B gpg-card-tool +.RI [ options ] +.I command +.RI { +.B -- +.I command +.RI } + at end ifset + + at mansect description +The @command{gpg-card-tool} is used to administrate smart cards and USB +tokens. It provides a superset of features from @command{gpg +--card-edit} an can be considered a frontend to @command{scdaemon} +which is a daemon started by @command{gpg-agent} to handle smart +cards. + +If @command{gpg-card-tool} is invoked without commands an interactive +mode is used. + +If @command{gpg-card-tool} is invoked with one or more commands the +same commands as available in the interactive mode are run from the +command line. These commands need to be delimited with a double-dash. +If a double-dash or a shell specific character is required as part of +a command the entire command needs to be put in quotes. If one of +those commands returns an error the remaining commands are mot anymore +run unless the command was prefixed with a single dash. + +A list of commands is available by using the command @code{help} and a +detailed description of each command is printed by using @code{help +COMMAND}. + + + at mansect options + at noindent + at command{gpg-card-tool} understands these options: + + at table @gnupgtabopt + + at item --with-colons + at opindex with-colons +This option has currently no effect. + + at item --status-fd @var{n} + at opindex status-fd +Write special status strings to the file descriptor @var{n}. This +program returns only the status messages SUCCESS or FAILURE which are +helpful when the caller uses a double fork approach and can't easily +get the return code of the process. + + at item --verbose + at opindex verbose +Enable extra informational output. + + at item --quiet + at opindex quiet +Disable almost all informational output. + + at item --version + at opindex version +Print version of the program and exit. + + at item --help + at opindex help +Display a brief help page and exit. + + at item --no-autostart + at opindex no-autostart +Do not start the gpg-agent if it has not yet been started and its +service is required. This option is mostly useful on machines where +the connection to gpg-agent has been redirected to another machines. + + at item --agent-program @var{file} + at opindex agent-program +Specify the agent program to be started if none is running. The +default value is determined by running @command{gpgconf} with the +option @option{--list-dirs}. + + at item --gpg-program @var{file} + at opindex gpg-program +Specify a non-default gpg binary to be used by certain commands. + + at item --gpgsm-program @var{file} + at opindex gpgsm-program +Specify a non-default gpgsm binary to be used by certain commands. + + at end table + + + at mansect see also + at ifset isman + at command{scdaemon}(1) + at end ifset diff --git a/doc/gnupg.texi b/doc/gnupg.texi index 3364148..6210486 100644 --- a/doc/gnupg.texi +++ b/doc/gnupg.texi @@ -142,15 +142,16 @@ the administration and the architecture. * Specify a User ID:: How to Specify a User Id. * Trust Values:: How GnuPG displays trust values. -* Helper Tools:: Description of small helper tools -* Web Key Service:: Tools for the Web Key Service +* Smart Card Tool:: Tool to administrate smart cards. +* Helper Tools:: Description of small helper tools. +* Web Key Service:: Tools for the Web Key Service. * Howtos:: How to do certain things. * System Notes:: Notes pertaining to certain OSes. -* Debugging:: How to solve problems +* Debugging:: How to solve problems. * Copying:: GNU General Public License says - how you can copy and share GnuPG + how you can copy and share GnuPG. * Contributors:: People who have contributed to GnuPG. * Glossary:: Short description of terms used. @@ -186,6 +187,7 @@ the administration and the architecture. @cindex trust values @include trust-values.texi + at include card-tool.texi @include tools.texi @include wks.texi @@ -237,5 +239,3 @@ the administration and the architecture. @bye - - ----------------------------------------------------------------------- Summary of changes: doc/Makefile.am | 7 +-- doc/card-tool.texi | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/gnupg.texi | 12 ++--- 3 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 doc/card-tool.texi hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 6 20:48:22 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 06 Feb 2019 20:48:22 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-357-gb5b1f72 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 b5b1f721582df9d0379cb68b4faeceed32a56e49 (commit) via 9a9cb0257aebb1480b999fdf9d90904083eb8e3c (commit) via c26af8ac263ea006ed32e110a09271e4bfbf1f37 (commit) from 6c581cc468d7a1b860632b7a465d71224c6e4999 (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 b5b1f721582df9d0379cb68b4faeceed32a56e49 Author: Werner Koch Date: Wed Feb 6 20:47:07 2019 +0100 scd: Add genkey command to app-piv (rsa-only) * scd/app-piv.c (struct genkey_result_s): new. (struct app_local_s): add member genkey_results. (do_deinit): Free that one. (flush_cached_data): Extend to delete all items. (keyref_from_dobj): New. (do_readkey): New. (do_auth): Use keyref_from_dobj. (does_key_exist): New. (genkey_parse_rsa): New. (do_genkey): New. -- We need to extend the GENKEY in command.c to support other algos. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index 42f16de..cfc4a27 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -38,6 +38,7 @@ * | Unblock PIN | | | yes | New PIN required | * |---------------------------------------------------------------| * (9B indicates the 24 byte PIV Card Application Administration Key) + * */ #include @@ -152,11 +153,22 @@ struct cache_s { }; +/* A cache item used by genkey. */ +struct genkey_result_s { + struct genkey_result_s *next; + int keyref; + gcry_sexp_t s_pkey; +}; + + /* Object with application specific data. */ struct app_local_s { /* A linked list with cached DOs. */ struct cache_s *cache; + /* A list with results from recent genkey operations. */ + struct genkey_result_s *genkey_results; + /* Various flags. */ struct { @@ -181,12 +193,19 @@ do_deinit (app_t app) if (app && app->app_local) { struct cache_s *c, *c2; + struct genkey_result_s *gr, *gr2; for (c = app->app_local->cache; c; c = c2) { c2 = c->next; xfree (c); } + for (gr = app->app_local->genkey_results; gr; gr = gr2) + { + gr2 = gr->next; + gcry_sexp_release (gr->s_pkey); + xfree (gr); + } xfree (app->app_local); app->app_local = NULL; @@ -284,14 +303,15 @@ get_cached_data (app_t app, int tag, } -/* Remove data object described by TAG from the cache. */ +/* Remove data object described by TAG from the cache. If TAG is 0 + * all cache iterms are flushed. */ static void flush_cached_data (app_t app, int tag) { struct cache_s *c, *cprev; for (c=app->app_local->cache, cprev=NULL; c; cprev=c, c = c->next) - if (c->tag == tag) + if (c->tag == tag || !tag) { if (cprev) cprev->next = c->next; @@ -860,7 +880,7 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags) } -/* Core of do-readcert which fetches the certificate based on the +/* Core of do_readcert which fetches the certificate based on the * given tag and returns it in a freshly allocated buffer stored at * R_CERT and the length of the certificate stored at R_CERTLEN. */ static gpg_error_t @@ -1010,6 +1030,17 @@ find_dobj_by_keyref (app_t app, const char *keyref) } +/* Return the keyref from DOBJ as an integer. If it does not exist, + * return -1. */ +static int +keyref_from_dobj (data_object_t dobj) +{ + if (!dobj || !hexdigitp (dobj->keyref) || !hexdigitp (dobj->keyref+1)) + return -1; + return xtoi_2 (dobj->keyref); +} + + /* Read a certificate from the card and returned in a freshly * allocated buffer stored at R_CERT and the length of the certificate * stored at R_CERTLEN. CERTID is either the OID of the cert's @@ -1031,6 +1062,70 @@ do_readcert (app_t app, const char *certid, } +/* Return a public key in a freshly allocated buffer. This will only + * work for a freshly generated key as long as no reset of the + * application has been performed. This is because we return a cached + * result from key generation. If no cached result is available, the + * error GPG_ERR_UNSUPPORTED_OPERATION is returned so that the higher + * layer can then to get the key by reading the matching certificate. + * On success a canonical encoded S-expression with the public key is + * stored at (R_PK,R_PKLEN); the caller must release that buffer. On + * error R_PK and R_PKLEN are not changed and an error code is + * returned. + */ +static gpg_error_t +do_readkey (app_t app, int advanced, const char *keyrefstr, + unsigned char **r_pk, size_t *r_pklen) +{ + gpg_error_t err; + data_object_t dobj; + int keyref; + struct genkey_result_s *gres; + unsigned char *pk = NULL; + size_t pklen; + + dobj = find_dobj_by_keyref (app, keyrefstr); + if ((keyref = keyref_from_dobj (dobj)) == -1) + { + err = gpg_error (GPG_ERR_INV_ID); + goto leave; + } + for (gres = app->app_local->genkey_results; gres; gres = gres->next) + if (gres->keyref == keyref) + break; + if (!gres || !gres->s_pkey) + { + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + + err = make_canon_sexp (gres->s_pkey, &pk, &pklen); + if (err) + goto leave; + if (advanced) + { + /* FIXME: How ugly - we should move that to command.c */ + char *p = canon_sexp_to_string (pk, pklen); + if (!p) + { + err = gpg_error_from_syserror (); + goto leave; + } + xfree (pk); + pk = p; + pklen = strlen (pk); + } + + *r_pk = pk; + pk = NULL; + *r_pklen = pklen; + + leave: + xfree (pk); + return err; +} + + /* Given a data object DOBJ return the corresponding PIV algorithm and * store it at R_ALGO. The algorithm is taken from the corresponding * certificate or from a cache. */ @@ -1553,12 +1648,11 @@ do_auth (app_t app, const char *keyidstr, * make sense for X.509 certs? */ dobj = find_dobj_by_keyref (app, keyidstr); - if (!dobj) + if ((keyref = keyref_from_dobj (dobj)) == -1) { err = gpg_error (GPG_ERR_INV_ID); goto leave; } - keyref = xtoi_2 (dobj->keyref); err = get_key_algorithm_by_dobj (app, dobj, &algo); if (err) @@ -1714,6 +1808,260 @@ do_auth (app_t app, const char *keyidstr, } +/* Check whether a key for DOBJ already exists. We detect this by + * reading the certificate described by DOBJ. If FORCE is TRUE a + * diagnositic will be printed but no error returned if the key + * already exists. The flag GENERATING is used to select a + * diagnositic. */ +static gpg_error_t +does_key_exist (app_t app, data_object_t dobj, int generating, int force) +{ + void *relptr; + unsigned char *buffer; + size_t buflen; + int found; + + relptr = get_one_do (app, dobj->tag, &buffer, &buflen, NULL); + found = (relptr && buflen); + xfree (relptr); + + if (found && !force) + { + log_error ("piv: %s", _("key already exists\n")); + return gpg_error (GPG_ERR_EEXIST); + } + + if (found) + log_info ("piv: %s", _("existing key will be replaced\n")); + else if (generating) + log_info ("piv: %s", _("generating new key\n")); + else + log_info ("piv: %s", _("writing new key\n")); + return 0; +} + + +/* Parse an RSA response object, consisting of the content of tag + * 0x7f49, into a gcrypt s-expresstion object and store that R_SEXP. + * On error NULL is stored at R_SEXP. */ +static gpg_error_t +genkey_parse_rsa (const unsigned char *data, size_t datalen, + gcry_sexp_t *r_sexp) +{ + gpg_error_t err; + const unsigned char *m, *e; + unsigned char *mbuf = NULL; + unsigned char *ebuf = NULL; + size_t mlen, elen; + + *r_sexp = NULL; + + m = find_tlv (data, datalen, 0x0081, &mlen); + if (!m) + { + log_error (_("response does not contain the RSA modulus\n")); + err = gpg_error (GPG_ERR_CARD); + goto leave; + } + + e = find_tlv (data, datalen, 0x0082, &elen); + if (!e) + { + log_error (_("response does not contain the RSA public exponent\n")); + err = gpg_error (GPG_ERR_CARD); + goto leave; + } + + for (; mlen && !*m; mlen--, m++) /* Strip leading zeroes */ + ; + for (; elen && !*e; elen--, e++) /* Strip leading zeroes */ + ; + + mbuf = xtrymalloc (mlen + 1); + if (!mbuf) + { + err = gpg_error_from_syserror (); + goto leave; + } + /* Prepend numbers with a 0 if needed. */ + if (mlen && (*m & 0x80)) + { + *mbuf = 0; + memcpy (mbuf+1, m, mlen); + mlen++; + } + else + memcpy (mbuf, m, mlen); + + ebuf = xtrymalloc (elen + 1); + if (!ebuf) + { + err = gpg_error_from_syserror (); + goto leave; + } + /* Prepend numbers with a 0 if needed. */ + if (elen && (*e & 0x80)) + { + *ebuf = 0; + memcpy (ebuf+1, e, elen); + elen++; + } + else + memcpy (ebuf, e, elen); + + err = gcry_sexp_build (r_sexp, NULL, "(public-key(rsa(n%b)(e%b)))", + (int)mlen, mbuf, (int)elen, ebuf); + + leave: + xfree (mbuf); + xfree (ebuf); + return err; +} + + +/* Create a new keypair for KEYREF. If KEYTYPE is NULL a default + * keytype is selected, else it may be one of the strings: + * "rsa2048", "nistp256, or "nistp384". + * + * Supported FLAGS are: + * APP_GENKEY_FLAG_FORCE Overwrite existing key. + * + * Note that CREATETIME is not used for PIV cards. + * + * Because there seems to be no way to read the public key we need to + * retrieve it from a certificate. The GnuPG system however requires + * the use of app_readkey to fetch the public key from the card to + * create the certificate; to support this we temporary store the + * generated public key in the local context for use by app_readkey. + */ +static gpg_error_t +do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype, + unsigned int flags, time_t createtime, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg) +{ + gpg_error_t err; + data_object_t dobj; + unsigned char *buffer = NULL; + size_t buflen; + int force = !!(flags & APP_GENKEY_FLAG_FORCE); + int mechanism; + time_t start_at; + int keyref; + unsigned char tmpl[5]; + size_t tmpllen; + const unsigned char *keydata; + size_t keydatalen; + gcry_sexp_t s_pkey = NULL; + struct genkey_result_s *gres; + + (void)ctrl; + (void)createtime; + (void)pincb; + (void)pincb_arg; + + if (!keytype) + keytype = "rsa2048"; + + if (!strcmp (keytype, "rsa2048")) + mechanism = PIV_ALGORITHM_RSA; + else if (!strcmp (keytype, "nistp256")) + mechanism = PIV_ALGORITHM_ECC_P256; + else if (!strcmp (keytype, "nistp384")) + mechanism = PIV_ALGORITHM_ECC_P384; + else + return gpg_error (GPG_ERR_UNKNOWN_CURVE); + + /* We flush the cache to increase the I/O traffic before a key + * generation. This _might_ help the card to gather more entropy + * and is anyway a prerequisite for does_key_exist. */ + flush_cached_data (app, 0); + + /* Check whether a key already exists. */ + dobj = find_dobj_by_keyref (app, keyrefstr); + if ((keyref = keyref_from_dobj (dobj)) == -1) + { + err = gpg_error (GPG_ERR_INV_ID); + goto leave; + } + err = does_key_exist (app, dobj, 1, force); + if (err) + goto leave; + + + /* FIXME: Check that the authentication has already been done. */ + + + + /* Create the key. */ + log_info (_("please wait while key is being generated ...\n")); + start_at = time (NULL); + tmpl[0] = 0xac; + tmpl[1] = 3; + tmpl[2] = 0x80; + tmpl[3] = 1; + tmpl[4] = mechanism; + tmpllen = 5; + err = iso7816_generate_keypair (app->slot, 0, 0, keyref, + tmpl, tmpllen, 0, &buffer, &buflen); + if (err) + { + log_error (_("generating key failed\n")); + return gpg_error (GPG_ERR_CARD); + } + + { + int nsecs = (int)(time (NULL) - start_at); + log_info (ngettext("key generation completed (%d second)\n", + "key generation completed (%d seconds)\n", + nsecs), nsecs); + } + + /* Parse the result and store it as an s-expression in a dedicated + * cache for later retrieval by app_readkey. */ + keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); + if (!keydata || !keydatalen) + { + err = gpg_error (GPG_ERR_CARD); + log_error (_("response does not contain the public key data\n")); + goto leave; + } + + if (mechanism == PIV_ALGORITHM_RSA) + err = genkey_parse_rsa (keydata, keydatalen, &s_pkey); + else + err = gpg_error (GPG_ERR_BUG); + if (err) + goto leave; + + for (gres = app->app_local->genkey_results; gres; gres = gres->next) + if (gres->keyref == keyref) + break; + if (!gres) + { + gres = xtrycalloc (1, sizeof *gres); + if (!gres) + { + err = gpg_error_from_syserror (); + goto leave; + } + gres->keyref = keyref; + gres->next = app->app_local->genkey_results; + app->app_local->genkey_results = gres; + } + else + gcry_sexp_release (gres->s_pkey); + gres->s_pkey = s_pkey; + s_pkey = NULL; + + + leave: + gcry_sexp_release (s_pkey); + xfree (buffer); + return err; +} + + /* Select the PIV application on the card in SLOT. This function must * be used before any other PIV application functions. */ gpg_error_t @@ -1801,12 +2149,12 @@ app_select_piv (app_t app) app->fnc.deinit = do_deinit; app->fnc.learn_status = do_learn_status; app->fnc.readcert = do_readcert; - app->fnc.readkey = NULL; + app->fnc.readkey = do_readkey; app->fnc.getattr = do_getattr; app->fnc.setattr = do_setattr; /* app->fnc.writecert = do_writecert; */ /* app->fnc.writekey = do_writekey; */ - /* app->fnc.genkey = do_genkey; */ + app->fnc.genkey = do_genkey; /* app->fnc.sign = do_sign; */ app->fnc.auth = do_auth; /* app->fnc.decipher = do_decipher; */ commit 9a9cb0257aebb1480b999fdf9d90904083eb8e3c Author: Werner Koch Date: Wed Feb 6 14:07:42 2019 +0100 scd: Make app_genkey and supporting ISO function more flexible. * scd/app.c (app_genkey): Add arg keytype. * scd/app-common.h (struct app_ctx_s): Fitto for the genkey member. * scd/command.c (cmd_genkey): Adjust for change. * scd/iso7816.c (do_generate_keypair): Replace arg read_only by new args p1 and p2. (iso7816_read_public_key): Adjust for this. (iso7816_generate_keypair): Add new args p1 and p2. * scd/app-openpgp.c (do_genkey): Adjust for changes. -- The OpenPGP card creates keys according to parameters read from a data object. Other cards we are about to implement require a direct specification of the requested keytype. This patch implements the required changes. Signed-off-by: Werner Koch diff --git a/scd/app-common.h b/scd/app-common.h index d8b301c..e9d167e 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -106,8 +106,8 @@ struct app_ctx_s { void *pincb_arg, const unsigned char *pk, size_t pklen); gpg_error_t (*genkey) (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - time_t createtime, + const char *keyref, const char *keytype, + unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t (*change_pin) (app_t app, ctrl_t ctrl, @@ -178,8 +178,8 @@ gpg_error_t app_writekey (app_t app, ctrl_t ctrl, void *pincb_arg, const unsigned char *keydata, size_t keydatalen); gpg_error_t app_genkey (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - time_t createtime, + const char *keynostr, const char *keytype, + unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 72ed80a..ae87d19 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -4086,8 +4086,8 @@ do_writekey (app_t app, ctrl_t ctrl, /* Handle the GENKEY command. */ static gpg_error_t -do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, - time_t createtime, +do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, const char *keytype, + unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -4103,6 +4103,8 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, int exmode = 0; int le_value = 256; /* Use legacy value. */ + (void)keytype; /* Ignored for OpenPGP cards. */ + if (keyno < 0 || keyno > 2) return gpg_error (GPG_ERR_INV_ID); @@ -4151,7 +4153,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, log_info (_("please wait while key is being generated ...\n")); start_at = time (NULL); - err = iso7816_generate_keypair (app->slot, exmode, + err = iso7816_generate_keypair (app->slot, exmode, 0x80, 0, (keyno == 0? "\xB6" : keyno == 1? "\xB8" : "\xA4"), 2, le_value, &buffer, &buflen); diff --git a/scd/app.c b/scd/app.c index c6c1f84..2e2729e 100644 --- a/scd/app.c +++ b/scd/app.c @@ -939,8 +939,8 @@ app_writekey (app_t app, ctrl_t ctrl, /* Perform a SETATTR operation. */ gpg_error_t -app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, - time_t createtime, +app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, + const char *keytype, unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -955,7 +955,7 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, err = lock_app (app, ctrl); if (err) return err; - err = app->fnc.genkey (app, ctrl, keynostr, flags, + err = app->fnc.genkey (app, ctrl, keynostr, keytype, flags, createtime, pincb, pincb_arg); unlock_app (app); if (opt.verbose) diff --git a/scd/command.c b/scd/command.c index fb0ba98..8fd6ba5 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1190,7 +1190,8 @@ cmd_genkey (assuan_context_t ctx, char *line) keyno = xtrystrdup (keyno); if (!keyno) return out_of_core (); - rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, + rc = app_genkey (ctrl->app_ctx, ctrl, keyno, NULL, + force? APP_GENKEY_FLAG_FORCE : 0, timestamp, pin_cb, ctx); xfree (keyno); diff --git a/scd/iso7816.c b/scd/iso7816.c index 69009c4..758de5b 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -709,7 +709,7 @@ iso7816_general_authenticate (int slot, int extended_mode, returned. In that case a value of -1 uses a large default (e.g. 4096 bytes), a value larger 256 used that value. */ static gpg_error_t -do_generate_keypair (int slot, int extended_mode, int read_only, +do_generate_keypair (int slot, int extended_mode, int p1, int p2, const char *data, size_t datalen, int le, unsigned char **result, size_t *resultlen) { @@ -721,7 +721,7 @@ do_generate_keypair (int slot, int extended_mode, int read_only, *resultlen = 0; sw = apdu_send_le (slot, extended_mode, - 0x00, CMD_GENERATE_KEYPAIR, read_only? 0x81:0x80, 0, + 0x00, CMD_GENERATE_KEYPAIR, p1, p2, datalen, data, le >= 0 && le < 256? 256:le, result, resultlen); @@ -739,12 +739,12 @@ do_generate_keypair (int slot, int extended_mode, int read_only, gpg_error_t -iso7816_generate_keypair (int slot, int extended_mode, +iso7816_generate_keypair (int slot, int extended_mode, int p1, int p2, const char *data, size_t datalen, int le, unsigned char **result, size_t *resultlen) { - return do_generate_keypair (slot, extended_mode, 0, + return do_generate_keypair (slot, extended_mode, p1, p2, data, datalen, le, result, resultlen); } @@ -755,7 +755,7 @@ iso7816_read_public_key (int slot, int extended_mode, int le, unsigned char **result, size_t *resultlen) { - return do_generate_keypair (slot, extended_mode, 1, + return do_generate_keypair (slot, extended_mode, 0x81, 0, data, datalen, le, result, resultlen); } diff --git a/scd/iso7816.h b/scd/iso7816.h index 4a366e6..df5d25f 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -112,9 +112,11 @@ gpg_error_t iso7816_general_authenticate (int slot, int extended_mode, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_generate_keypair (int slot, int extended_mode, - const char *data, size_t datalen, - int le, - unsigned char **result, size_t *resultlen); + int p1, int p2, + const char *data, size_t datalen, + int le, + unsigned char **result, + size_t *resultlen); gpg_error_t iso7816_read_public_key (int slot, int extended_mode, const char *data, size_t datalen, int le, commit c26af8ac263ea006ed32e110a09271e4bfbf1f37 Author: Werner Koch Date: Wed Feb 6 12:24:30 2019 +0100 scd: Fix parameter name of app_change_key. * scd/app-common.h (APP_GENKEY_FLAG_FORCE): New. * scd/app.c (app_change_pin): Rename arg reset_mode to flags and change from int to unsigned int. -- This is basically a documentation fix. Signed-off-by: Werner Koch diff --git a/scd/app-common.h b/scd/app-common.h index 98d8464..d8b301c 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -25,11 +25,14 @@ #include #include - +/* Flags used with app_change_pin. */ #define APP_CHANGE_FLAG_RESET 1 /* PIN Reset mode. */ #define APP_CHANGE_FLAG_NULLPIN 2 /* NULL PIN mode. */ #define APP_CHANGE_FLAG_CLEAR 4 /* Clear the given PIN. */ +/* Flags used with app_genkey. */ +#define APP_GENKEY_FLAG_FORCE 1 /* Force overwriting existing key. */ + /* Bit flags set by the decipher function into R_INFO. */ #define APP_DECIPHER_INFO_NOPAD 1 /* Padding has been removed. */ @@ -182,9 +185,9 @@ gpg_error_t app_genkey (app_t app, ctrl_t ctrl, gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer); gpg_error_t app_change_pin (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, - gpg_error_t (*pincb)(void*, const char *, char **), - void *pincb_arg); + const char *chvnostr, unsigned int flags, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg); gpg_error_t app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); diff --git a/scd/app.c b/scd/app.c index c79a174..c6c1f84 100644 --- a/scd/app.c +++ b/scd/app.c @@ -988,7 +988,8 @@ app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer) /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */ gpg_error_t -app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, +app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, + unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -1003,8 +1004,7 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, err = lock_app (app, ctrl); if (err) return err; - err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, - pincb, pincb_arg); + err = app->fnc.change_pin (app, ctrl, chvnostr, flags, pincb, pincb_arg); unlock_app (app); if (opt.verbose) log_info ("operation change_pin result: %s\n", gpg_strerror (err)); ----------------------------------------------------------------------- Summary of changes: scd/app-common.h | 19 +-- scd/app-openpgp.c | 8 +- scd/app-piv.c | 362 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- scd/app.c | 12 +- scd/command.c | 3 +- scd/iso7816.c | 10 +- scd/iso7816.h | 8 +- 7 files changed, 389 insertions(+), 33 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 7 11:05:55 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Feb 2019 11:05:55 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-359-gfcec5b4 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 fcec5b40e589b2ef201efb89f22a952feb4a9069 (commit) via 090b5f804aee41a36a9ee1fbf0976109970d810d (commit) from b5b1f721582df9d0379cb68b4faeceed32a56e49 (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 fcec5b40e589b2ef201efb89f22a952feb4a9069 Author: Werner Koch Date: Thu Feb 7 11:05:22 2019 +0100 card: Support reading and writing PIV certificates * scd/app-piv.c (add_tlv): New. (put_data): New. (do_writecert): New. (do_setattr): Remove usused special mode 0. * tools/gpg-card-tool.c (cmd_writecert): Allow other cards than OPENPGP. (cmd_readcert): Ditto. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index cfc4a27..59f2725 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -426,6 +426,157 @@ dump_all_do (int slot) } +/* Create a TLV tag and value and store it at BUFFER. Return the + * length of tag and length. A LENGTH greater than 65535 is + * truncated. TAG must be less or equal to 2^16. If BUFFER is NULL, + * only the required length is computed. */ +static size_t +add_tlv (unsigned char *buffer, unsigned int tag, size_t length) +{ + if (length > 0xffff) + length = 0xffff; + + if (buffer) + { + unsigned char *p = buffer; + + if (tag > 0xff) + *p++ = tag >> 8; + *p++ = tag; + if (length < 128) + *p++ = length; + else if (length < 256) + { + *p++ = 0x81; + *p++ = length; + } + else + { + *p++ = 0x82; + *p++ = length >> 8; + *p++ = length; + } + + return p - buffer; + } + else + { + size_t n = 0; + + if (tag > 0xff) + n++; + n++; + if (length < 128) + n++; + else if (length < 256) + n += 2; + else + n += 3; + return n; + } +} + + +/* Wrapper around iso7816_put_data_odd which also sets the tag into + * the '5C' data object. The varargs are tuples of (int,size_t,void) + * with the tag, the length and the actual data. A (0,0,NULL) tuple + * terminates the list. Up to 10 tuples are supported. */ +static gpg_error_t +put_data (int slot, unsigned int tag, ...) +{ + gpg_error_t err; + va_list arg_ptr; + struct { + int tag; + size_t len; + const void *data; + } argv[10]; + int i, argc; + unsigned char data5c[5]; + size_t data5clen; + unsigned char *data = NULL; + size_t datalen; + unsigned char *p; + size_t n; + + /* Collect all args. Check that length is <= 2^16 to match the + * behaviour of add_tlv. */ + va_start (arg_ptr, tag); + argc = 0; + while (((argv[argc].tag = va_arg (arg_ptr, int)))) + { + argv[argc].len = va_arg (arg_ptr, size_t); + argv[argc].data = va_arg (arg_ptr, const void *); + if (argc >= DIM (argv)-1 || argv[argc].len > 0xffff) + { + va_end (arg_ptr); + return GPG_ERR_EINVAL; + } + argc++; + } + va_end (arg_ptr); + + /* Build the TLV with the tag to be updated. */ + data5c[0] = 0x5c; /* Tag list */ + if (tag <= 0xff) + { + data5c[1] = 1; + data5c[2] = tag; + data5clen = 3; + } + else if (tag <= 0xffff) + { + data5c[1] = 2; + data5c[2] = (tag >> 8); + data5c[3] = tag; + data5clen = 4; + } + else + { + data5c[1] = 3; + data5c[2] = (tag >> 16); + data5c[3] = (tag >> 8); + data5c[4] = tag; + data5clen = 5; + } + + /* Compute the required buffer length and allocate the buffer. */ + n = 0; + for (i=0; i < argc; i++) + { + n += add_tlv (NULL, argv[i].tag, argv[i].len); + n += argv[i].len; + } + datalen = data5clen + add_tlv (NULL, 0x53, n) + n; + data = xtrymalloc (datalen); + if (!data) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Copy that data to the buffer. */ + p = data; + memcpy (p, data5c, data5clen); + p += data5clen; + p += add_tlv (p, 0x53, n); + for (i=0; i < argc; i++) + { + p += add_tlv (p, argv[i].tag, argv[i].len); + memcpy (p, argv[i].data, argv[i].len); + p += argv[i].len; + } + log_assert ( data + datalen == p ); + log_printhex (data, datalen, "Put data"); + err = iso7816_put_data_odd (slot, -1 /* use command chaining */, + 0x3fff, data, datalen); + + leave: + xfree (data); + return err; +} + + /* Parse the key reference KEYREFSTR which is expected to hold a key * reference for a CHV object. Return the one octet keyref or -1 for * an invalid reference. */ @@ -802,13 +953,6 @@ do_setattr (app_t app, const char *name, switch (table[idx].special) { - case 0: - err = iso7816_put_data (app->slot, 0, table[idx].tag, value, valuelen); - if (err) - log_error ("failed to set '%s': %s\n", - table[idx].name, gpg_strerror (err)); - break; - case 1: err = auth_adm_key (app, value, valuelen); break; @@ -2062,6 +2206,45 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype, } +/* Write the certificate (CERT,CERTLEN) to the card at CERTREFSTR. + * CERTREFSTR is either the OID of the certificate's container data + * object or of the form "PIV.". */ +static gpg_error_t +do_writecert (app_t app, ctrl_t ctrl, + const char *certrefstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const unsigned char *cert, size_t certlen) +{ + gpg_error_t err; + data_object_t dobj; + + (void)ctrl; + (void)pincb; /* Not used; instead authentication is needed. */ + (void)pincb_arg; + + dobj = find_dobj_by_keyref (app, certrefstr); + if (!dobj || !*dobj->keyref) + return gpg_error (GPG_ERR_INV_ID); + + /* FIXME: Check that the authentication has already been done. */ + + flush_cached_data (app, dobj->tag); + + err = put_data (app->slot, dobj->tag, + (int)0x70, (size_t)certlen, cert,/* Certificate */ + (int)0x71, (size_t)1, "", /* No compress */ + (int)0xfe, (size_t)0, "", /* Empty LRC. */ + (int)0, (size_t)0, NULL); + if (err) + log_error ("piv: failed to write cert to %s: %s\n", + dobj->keyref, gpg_strerror (err)); + + + return err; +} + + /* Select the PIV application on the card in SLOT. This function must * be used before any other PIV application functions. */ gpg_error_t @@ -2152,7 +2335,7 @@ app_select_piv (app_t app) app->fnc.readkey = do_readkey; app->fnc.getattr = do_getattr; app->fnc.setattr = do_setattr; - /* app->fnc.writecert = do_writecert; */ + app->fnc.writecert = do_writecert; /* app->fnc.writekey = do_writekey; */ app->fnc.genkey = do_genkey; /* app->fnc.sign = do_sign; */ diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 08248f7..9170132 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -1551,36 +1551,41 @@ cmd_writecert (card_info_t info, char *argstr) { gpg_error_t err; int opt_clear; - int do_no; + char *certref_buffer = NULL; + char *certref; char *data = NULL; size_t datalen; if (!info) return print_help - ("WRITECERT [--clear] 3 < FILE\n\n" + ("WRITECERT [--clear] CERTREF < FILE\n\n" "Write a certificate for key 3. Unless --clear is given\n" - "the file argement is mandatory. The option --clear removes\n" + "the file argument is mandatory. The option --clear removes\n" "the certificate from the card.", - APP_TYPE_OPENPGP, 0); + APP_TYPE_OPENPGP, APP_TYPE_PIV, 0); opt_clear = has_leading_option (argstr, "--clear"); argstr = skip_options (argstr); - if (digitp (argstr)) + certref = argstr; + if ((argstr = strchr (certref, ' '))) { - do_no = atoi (argstr); - while (digitp (argstr)) - argstr++; - while (spacep (argstr)) - argstr++; + *argstr++ = 0; + trim_spaces (certref); + trim_spaces (argstr); } - else - do_no = 0; + else /* Let argstr point to an empty string. */ + argstr = certref + strlen (certref); - if (do_no != 3) + if (info->apptype == APP_TYPE_OPENPGP) { - err = gpg_error (GPG_ERR_INV_ARG); - goto leave; + if (ascii_strcasecmp (certref, "OPENPGP.3") && strcmp (certref, "3")) + { + err = gpg_error (GPG_ERR_INV_ID); + log_error ("Error: CERTREF must be \"3\" or \"OPENPGP.3\"\n"); + goto leave; + } + certref = certref_buffer = xstrdup ("OPENPGP.3"); } if (opt_clear) @@ -1602,10 +1607,11 @@ cmd_writecert (card_info_t info, char *argstr) goto leave; } - err = scd_writecert ("OPENPGP.3", data, datalen); + err = scd_writecert (certref, data, datalen); leave: xfree (data); + xfree (certref_buffer); return err; } @@ -1614,37 +1620,42 @@ static gpg_error_t cmd_readcert (card_info_t info, char *argstr) { gpg_error_t err; - int do_no; + char *certref_buffer = NULL; + char *certref; void *data = NULL; size_t datalen; const char *fname; if (!info) return print_help - ("READCERT 3 > FILE\n\n" + ("READCERT CERTREF > FILE\n\n" "Read the certificate for key 3 and store it in FILE.", - APP_TYPE_OPENPGP, 0); + APP_TYPE_OPENPGP, APP_TYPE_PIV, 0); argstr = skip_options (argstr); - if (digitp (argstr)) + certref = argstr; + if ((argstr = strchr (certref, ' '))) { - do_no = atoi (argstr); - while (digitp (argstr)) - argstr++; - while (spacep (argstr)) - argstr++; + *argstr++ = 0; + trim_spaces (certref); + trim_spaces (argstr); } - else - do_no = 0; + else /* Let argstr point to an empty string. */ + argstr = certref + strlen (certref); - if (do_no != 3) + if (info->apptype == APP_TYPE_OPENPGP) { - err = gpg_error (GPG_ERR_INV_ARG); - goto leave; + if (ascii_strcasecmp (certref, "OPENPGP.3") && strcmp (certref, "3")) + { + err = gpg_error (GPG_ERR_INV_ID); + log_error ("Error: CERTREF must be \"3\" or \"OPENPGP.3\"\n"); + goto leave; + } + certref = certref_buffer = xstrdup ("OPENPGP.3"); } - if (*argstr == '>') /* Read it from a file */ + if (*argstr == '>') /* Write it to a file */ { for (argstr++; spacep (argstr); argstr++) ; @@ -1656,7 +1667,7 @@ cmd_readcert (card_info_t info, char *argstr) goto leave; } - err = scd_readcert ("OPENPGP.3", &data, &datalen); + err = scd_readcert (certref, &data, &datalen); if (err) goto leave; @@ -1664,6 +1675,7 @@ cmd_readcert (card_info_t info, char *argstr) leave: xfree (data); + xfree (certref_buffer); return err; } commit 090b5f804aee41a36a9ee1fbf0976109970d810d Author: Werner Koch Date: Thu Feb 7 08:16:02 2019 +0100 card: Add readline completion for help arguments -- diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index fd7aa9a..08248f7 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -3249,9 +3249,12 @@ command_completion (const char *text, int start, int end) (void)end; /* If we are at the start of a line, we try and command-complete. - * If not, just do nothing for now. */ + * If not, just do nothing for now. The support for help completion + * needs to be more smarter. */ if (!start) return rl_completion_matches (text, command_generator); + else if (start == 5 && !ascii_strncasecmp (rl_line_buffer, "help ", 5)) + return rl_completion_matches (text, command_generator); rl_attempted_completion_over = 1; ----------------------------------------------------------------------- Summary of changes: scd/app-piv.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++-- tools/gpg-card-tool.c | 81 +++++++++++--------- 2 files changed, 239 insertions(+), 41 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 7 16:28:32 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Feb 2019 16:28:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-361-gdf6ba6d 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 df6ba6dfd235fddb7645bc16573da1a6a7e6b49d (commit) via 5bf1212000f48243642ace0f708fd27446879b9e (commit) from fcec5b40e589b2ef201efb89f22a952feb4a9069 (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 df6ba6dfd235fddb7645bc16573da1a6a7e6b49d Author: Werner Koch Date: Thu Feb 7 16:28:03 2019 +0100 card: Fix a NULL-ptr deref in key listings. * tools/card-tool-keys.c (get_matching_keys): Fix segv. * tools/gpg-card-tool.c (main): Init info. Signed-off-by: Werner Koch diff --git a/tools/card-tool-keys.c b/tools/card-tool-keys.c index e9edf98..4e057ad 100644 --- a/tools/card-tool-keys.c +++ b/tools/card-tool-keys.c @@ -214,9 +214,12 @@ get_matching_keys (const unsigned char *keygrip, int protocol, err = get_matching_keys (keygrip, GNUPG_PROTOCOL_OPENPGP, &kb); if (!err || gpg_err_code (err) == GPG_ERR_NO_PUBKEY) { - *keyblock_tail = kb; - keyblock_tail = &kb->next; - kb = NULL; + if (!err) + { + *keyblock_tail = kb; + keyblock_tail = &kb->next; + kb = NULL; + } err = get_matching_keys (keygrip, GNUPG_PROTOCOL_CMS, &kb); if (!err) { diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 9170132..0dbf2b2 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -309,7 +309,7 @@ main (int argc, char **argv) } else { - struct card_info_s info_buffer; + struct card_info_s info_buffer = { 0 }; card_info_t info = &info_buffer; err = 0; @@ -2968,7 +2968,7 @@ interactive_loop (void) int redisplay = 1; /* Whether to redisplay the main info. */ int allow_admin = 0; /* Whether admin commands are allowed. */ char *help_arg = NULL; /* Argument of the HELP command. */ - struct card_info_s info_buffer; + struct card_info_s info_buffer = { 0 }; card_info_t info = &info_buffer; char *p; int i; commit 5bf1212000f48243642ace0f708fd27446879b9e Author: Werner Koch Date: Thu Feb 7 16:13:21 2019 +0100 scd: Store a new PIV public key in the certificate DO. * scd/app-piv.c (struct genkey_result_s): Remove type and all users. (send_keypair_and_cert_info): Print certinfo only if we got a cert.. (readcert_by_tag): Add arg r_mechanism and implement reading of public keys. (get_keygrip_by_tag): Use a public key to compute the keygrip. (do_readcert): Make sure to only return a certificate. (do_readkey): Read public key from the DO if a certificate is missing. (get_key_algorithm_by_dobj): Get the algorithm also from a public key. (does_key_exist): String changes. (do_genkey): Remove result caching and store public key in the DO. -- This removes the result cache and instead stores the public key in the certificate object. This allows to properly list public keys at any time after generating a key and before a new certificate is stored there. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index 59f2725..f4eb918 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -39,6 +39,12 @@ * |---------------------------------------------------------------| * (9B indicates the 24 byte PIV Card Application Administration Key) * + * - When generating a key we store the created public key in the + * corresponding data object, so that gpg and gpgsm are able to get + * the public key, create a certificate and store that then in that + * data object. That is not standard compliant but due to the use + * of other tags, it should not harm. See do_genkey for the actual + * used tag structure. */ #include @@ -153,22 +159,11 @@ struct cache_s { }; -/* A cache item used by genkey. */ -struct genkey_result_s { - struct genkey_result_s *next; - int keyref; - gcry_sexp_t s_pkey; -}; - - /* Object with application specific data. */ struct app_local_s { /* A linked list with cached DOs. */ struct cache_s *cache; - /* A list with results from recent genkey operations. */ - struct genkey_result_s *genkey_results; - /* Various flags. */ struct { @@ -180,7 +175,9 @@ struct app_local_s { /***** Local prototypes *****/ static gpg_error_t get_keygrip_by_tag (app_t app, unsigned int tag, - char **r_keygripstr); + char **r_keygripstr, int *got_cert); +static gpg_error_t genkey_parse_rsa (const unsigned char *data, size_t datalen, + gcry_sexp_t *r_sexp); @@ -193,19 +190,12 @@ do_deinit (app_t app) if (app && app->app_local) { struct cache_s *c, *c2; - struct genkey_result_s *gr, *gr2; for (c = app->app_local->cache; c; c = c2) { c2 = c->next; xfree (c); } - for (gr = app->app_local->genkey_results; gr; gr = gr2) - { - gr2 = gr->next; - gcry_sexp_release (gr->s_pkey); - xfree (gr); - } xfree (app->app_local); app->app_local = NULL; @@ -567,7 +557,6 @@ put_data (int slot, unsigned int tag, ...) p += argv[i].len; } log_assert ( data + datalen == p ); - log_printhex (data, datalen, "Put data"); err = iso7816_put_data_odd (slot, -1 /* use command chaining */, 0x3fff, data, datalen); @@ -978,9 +967,10 @@ send_keypair_and_cert_info (app_t app, ctrl_t ctrl, data_object_t dobj, { gpg_error_t err = 0; char *keygripstr = NULL; + int got_cert; char idbuf[50]; - err = get_keygrip_by_tag (app, dobj->tag, &keygripstr); + err = get_keygrip_by_tag (app, dobj->tag, &keygripstr, &got_cert); if (err) goto leave; @@ -989,7 +979,7 @@ send_keypair_and_cert_info (app_t app, ctrl_t ctrl, data_object_t dobj, keygripstr, strlen (keygripstr), idbuf, strlen (idbuf), NULL, (size_t)0); - if (!only_keypair) + if (!only_keypair && got_cert) { /* All certificates are of type 100 (Regular X.509 Cert). */ send_status_info (ctrl, "CERTINFO", @@ -1026,20 +1016,24 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags) /* Core of do_readcert which fetches the certificate based on the * given tag and returns it in a freshly allocated buffer stored at - * R_CERT and the length of the certificate stored at R_CERTLEN. */ + * R_CERT and the length of the certificate stored at R_CERTLEN. If + * on success a non-zero value is stored at R_MECHANISM, the returned + * data is not certificate but a public key (in the format used by the + * container '7f49'. */ static gpg_error_t readcert_by_tag (app_t app, unsigned int tag, - unsigned char **r_cert, size_t *r_certlen) + unsigned char **r_cert, size_t *r_certlen, int *r_mechanism) { gpg_error_t err; unsigned char *buffer; size_t buflen; void *relptr; - const unsigned char *s; - size_t n; + const unsigned char *s, *s2; + size_t n, n2; *r_cert = NULL; *r_certlen = 0; + *r_mechanism = 0; relptr = get_one_do (app, tag, &buffer, &buflen, NULL); if (!relptr || !buflen) @@ -1049,36 +1043,61 @@ readcert_by_tag (app_t app, unsigned int tag, } s = find_tlv (buffer, buflen, 0x71, &n); - if (!s || n != 1) - { - log_error ("piv: no or invalid CertInfo in 0x%X\n", tag); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - goto leave; - } - if (*s == 0x01) + if (!s) { - log_error ("piv: gzip compression not yet supported (tag 0x%X)\n", tag); - err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING); - goto leave; + /* No certificate; check whether a public key has been stored + * using our own scheme. */ + s = find_tlv (buffer, buflen, 0x7f49, &n); + if (!s || !n) + { + log_error ("piv: No public key in 0x%X\n", tag); + err = gpg_error (GPG_ERR_NO_PUBKEY); + goto leave; + } + s2 = find_tlv (buffer, buflen, 0x80, &n2); + if (!s2 || n2 != 1 || !*s2) + { + log_error ("piv: No mechanism for public key in 0x%X\n", tag); + err = gpg_error (GPG_ERR_NO_PUBKEY); + goto leave; + } + *r_mechanism = *s2; } - if (*s) + else { - log_error ("piv: invalid CertInfo 0x%02x in 0x%X\n", *s, tag); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - goto leave; - } + if (n != 1) + { + log_error ("piv: invalid CertInfo in 0x%X\n", tag); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto leave; + } + if (*s == 0x01) + { + log_error ("piv: gzip compression not yet supported (tag 0x%X)\n", + tag); + err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING); + goto leave; + } + if (*s) + { + log_error ("piv: invalid CertInfo 0x%02x in 0x%X\n", *s, tag); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto leave; + } - /* Note: We don't check that the LRC octet has a length of zero as - * required by the specs. */ + /* Note: We don't check that the LRC octet has a length of zero + * as required by the specs. */ - /* Get the cert from the container. */ - s = find_tlv (buffer, buflen, 0x70, &n); - if (!s || !n) - { - err = gpg_error (GPG_ERR_NOT_FOUND); - goto leave; + /* Get the cert from the container. */ + s = find_tlv (buffer, buflen, 0x70, &n); + if (!s || !n) + { + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } } + /* The next is common for certificate and public key. */ if (!(*r_cert = xtrymalloc (n))) { err = gpg_error_from_syserror (); @@ -1095,17 +1114,22 @@ readcert_by_tag (app_t app, unsigned int tag, } -/* Get the keygrip of a key from the certificate stored at TAG. - * Caller must free the string at R_KEYGRIPSTR. */ +/* Get the keygrip in hex format of a key from the certificate stored + * at TAG. Caller must free the string at R_KEYGRIPSTR. */ static gpg_error_t -get_keygrip_by_tag (app_t app, unsigned int tag, char **r_keygripstr) +get_keygrip_by_tag (app_t app, unsigned int tag, + char **r_keygripstr, int *r_got_cert) { gpg_error_t err; unsigned char *certbuf = NULL; size_t certbuflen; + int mechanism; + gcry_sexp_t s_pkey = NULL; ksba_cert_t cert = NULL; + unsigned char grip[KEYGRIP_LEN]; - *r_keygripstr = xtrymalloc (40+1); + *r_got_cert = 0; + *r_keygripstr = xtrymalloc (2*KEYGRIP_LEN+1); if (!r_keygripstr) { err = gpg_error_from_syserror (); @@ -1113,21 +1137,41 @@ get_keygrip_by_tag (app_t app, unsigned int tag, char **r_keygripstr) } /* We need to get the public key from the certificate. */ - err = readcert_by_tag (app, tag, &certbuf, &certbuflen); + err = readcert_by_tag (app, tag, &certbuf, &certbuflen, &mechanism); if (err) goto leave; + if (mechanism) /* Compute keygrip from public key. */ + { + if (mechanism == PIV_ALGORITHM_RSA) + err = genkey_parse_rsa (certbuf, certbuflen, &s_pkey); + else + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + if (err) + goto leave; - /* Compute the keygrip. */ - err = ksba_cert_new (&cert); - if (err) - goto leave; - err = ksba_cert_init_from_mem (cert, certbuf, certbuflen); - if (err) - goto leave; - err = app_help_get_keygrip_string (cert, *r_keygripstr); + if (!gcry_pk_get_keygrip (s_pkey, grip)) + { + log_error ("piv: error computing keygrip\n"); + err = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + bin2hex (grip, sizeof grip, *r_keygripstr); + } + else /* Compute keygrip from certificate. */ + { + *r_got_cert = 0; + err = ksba_cert_new (&cert); + if (err) + goto leave; + err = ksba_cert_init_from_mem (cert, certbuf, certbuflen); + if (err) + goto leave; + err = app_help_get_keygrip_string (cert, *r_keygripstr); + } leave: + gcry_sexp_release (s_pkey); ksba_cert_release (cert); xfree (certbuf); if (err) @@ -1193,7 +1237,9 @@ static gpg_error_t do_readcert (app_t app, const char *certid, unsigned char **r_cert, size_t *r_certlen) { + gpg_error_t err; data_object_t dobj; + int mechanism; *r_cert = NULL; *r_certlen = 0; @@ -1202,7 +1248,16 @@ do_readcert (app_t app, const char *certid, if (!dobj) return gpg_error (GPG_ERR_INV_ID); - return readcert_by_tag (app, dobj->tag, r_cert, r_certlen); + err = readcert_by_tag (app, dobj->tag, r_cert, r_certlen, &mechanism); + if (!err && mechanism) + { + /* Well, no certificate but a public key - we don't want it. */ + xfree (*r_cert); + *r_cert = NULL; + *r_certlen = 0; + err = gpg_error (GPG_ERR_NOT_FOUND); + } + return err; } @@ -1212,7 +1267,7 @@ do_readcert (app_t app, const char *certid, * result from key generation. If no cached result is available, the * error GPG_ERR_UNSUPPORTED_OPERATION is returned so that the higher * layer can then to get the key by reading the matching certificate. - * On success a canonical encoded S-expression with the public key is + * On success a canonical encoded s-expression with the public key is * stored at (R_PK,R_PKLEN); the caller must release that buffer. On * error R_PK and R_PKLEN are not changed and an error code is * returned. @@ -1224,7 +1279,10 @@ do_readkey (app_t app, int advanced, const char *keyrefstr, gpg_error_t err; data_object_t dobj; int keyref; - struct genkey_result_s *gres; + unsigned char *cert = NULL; + size_t certlen; + int mechanism; + gcry_sexp_t s_pkey = NULL; unsigned char *pk = NULL; size_t pklen; @@ -1234,16 +1292,28 @@ do_readkey (app_t app, int advanced, const char *keyrefstr, err = gpg_error (GPG_ERR_INV_ID); goto leave; } - for (gres = app->app_local->genkey_results; gres; gres = gres->next) - if (gres->keyref == keyref) - break; - if (!gres || !gres->s_pkey) + + err = readcert_by_tag (app, dobj->tag, &cert, &certlen, &mechanism); + if (err) + goto leave; + if (!mechanism) { - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* We got a certificate. Let the upper layer handle the + * extraction of the key. FIXME: It would be better to have a + * shared fucntion to dothis here. */ + err = gpg_error (GPG_ERR_NOT_FOUND); goto leave; } - err = make_canon_sexp (gres->s_pkey, &pk, &pklen); + /* Convert the public key into the expected s-expression. */ + if (mechanism == PIV_ALGORITHM_RSA) + err = genkey_parse_rsa (cert, certlen, &s_pkey); + else + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + if (err) + goto leave; + + err = make_canon_sexp (s_pkey, &pk, &pklen); if (err) goto leave; if (advanced) @@ -1265,7 +1335,9 @@ do_readkey (app_t app, int advanced, const char *keyrefstr, *r_pklen = pklen; leave: + gcry_sexp_release (s_pkey); xfree (pk); + xfree (cert); return err; } @@ -1279,6 +1351,7 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo) gpg_error_t err; unsigned char *certbuf = NULL; size_t certbuflen; + int mechanism; ksba_cert_t cert = NULL; ksba_sexp_t k_pkey = NULL; gcry_sexp_t s_pkey = NULL; @@ -1290,9 +1363,28 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo) *r_algo = 0; - err = readcert_by_tag (app, dobj->tag, &certbuf, &certbuflen); + err = readcert_by_tag (app, dobj->tag, &certbuf, &certbuflen, &mechanism); if (err) goto leave; + if (mechanism) + { + /* A public key was found. That makes it easy. */ + switch (mechanism) + { + case PIV_ALGORITHM_RSA: + case PIV_ALGORITHM_ECC_P256: + case PIV_ALGORITHM_ECC_P384: + *r_algo = mechanism; + break; + + default: + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + log_error ("piv: unknown mechanism %d in public key at %s\n", + mechanism, dobj->keyref); + break; + } + goto leave; + } err = ksba_cert_new (&cert); if (err) @@ -1971,22 +2063,22 @@ does_key_exist (app_t app, data_object_t dobj, int generating, int force) if (found && !force) { - log_error ("piv: %s", _("key already exists\n")); + log_error (_("key already exists\n")); return gpg_error (GPG_ERR_EEXIST); } if (found) - log_info ("piv: %s", _("existing key will be replaced\n")); + log_info (_("existing key will be replaced\n")); else if (generating) - log_info ("piv: %s", _("generating new key\n")); + log_info (_("generating new key\n")); else - log_info ("piv: %s", _("writing new key\n")); + log_info (_("writing new key\n")); return 0; } /* Parse an RSA response object, consisting of the content of tag - * 0x7f49, into a gcrypt s-expresstion object and store that R_SEXP. + * 0x7f49, into a gcrypt s-expression object and store that R_SEXP. * On error NULL is stored at R_SEXP. */ static gpg_error_t genkey_parse_rsa (const unsigned char *data, size_t datalen, @@ -2096,8 +2188,6 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype, size_t tmpllen; const unsigned char *keydata; size_t keydatalen; - gcry_sexp_t s_pkey = NULL; - struct genkey_result_s *gres; (void)ctrl; (void)createtime; @@ -2151,7 +2241,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype, if (err) { log_error (_("generating key failed\n")); - return gpg_error (GPG_ERR_CARD); + return err; } { @@ -2171,36 +2261,20 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype, goto leave; } - if (mechanism == PIV_ALGORITHM_RSA) - err = genkey_parse_rsa (keydata, keydatalen, &s_pkey); - else - err = gpg_error (GPG_ERR_BUG); + tmpl[0] = mechanism; + flush_cached_data (app, dobj->tag); + err = put_data (app->slot, dobj->tag, + (int)0x80, (size_t)1, tmpl, + (int)0x7f49, (size_t)keydatalen, keydata, + (int)0, (size_t)0, NULL); if (err) - goto leave; - - for (gres = app->app_local->genkey_results; gres; gres = gres->next) - if (gres->keyref == keyref) - break; - if (!gres) { - gres = xtrycalloc (1, sizeof *gres); - if (!gres) - { - err = gpg_error_from_syserror (); - goto leave; - } - gres->keyref = keyref; - gres->next = app->app_local->genkey_results; - app->app_local->genkey_results = gres; + log_error ("piv: failed to write key to the cert DO %s: %s\n", + dobj->keyref, gpg_strerror (err)); + goto leave; } - else - gcry_sexp_release (gres->s_pkey); - gres->s_pkey = s_pkey; - s_pkey = NULL; - leave: - gcry_sexp_release (s_pkey); xfree (buffer); return err; } @@ -2230,7 +2304,6 @@ do_writecert (app_t app, ctrl_t ctrl, /* FIXME: Check that the authentication has already been done. */ flush_cached_data (app, dobj->tag); - err = put_data (app->slot, dobj->tag, (int)0x70, (size_t)certlen, cert,/* Certificate */ (int)0x71, (size_t)1, "", /* No compress */ diff --git a/scd/command.c b/scd/command.c index 8fd6ba5..127fb5d 100644 --- a/scd/command.c +++ b/scd/command.c @@ -544,7 +544,8 @@ cmd_readkey (assuan_context_t ctx, char *line) goto leave; } - if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION) + if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION + && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) log_error ("app_readkey failed: %s\n", gpg_strerror (rc)); else { ----------------------------------------------------------------------- Summary of changes: scd/app-piv.c | 285 +++++++++++++++++++++++++++++++------------------ scd/command.c | 3 +- tools/card-tool-keys.c | 9 +- tools/gpg-card-tool.c | 4 +- 4 files changed, 189 insertions(+), 112 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 7 20:29:22 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 07 Feb 2019 20:29:22 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-362-gb79bc87 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 b79bc877f2ad4d08e7de377cf4bf616b981b3c5f (commit) from df6ba6dfd235fddb7645bc16573da1a6a7e6b49d (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 b79bc877f2ad4d08e7de377cf4bf616b981b3c5f Author: Werner Koch Date: Thu Feb 7 20:28:43 2019 +0100 card: Print the used algorithm of all keys. * tools/card-call-scd.c (scd_readkey): New. * tools/card-tool-misc.c (pubkey_algo_string): New. * tools/gpg-card-tool.c (list_one_kinfo): Print the algo. -- It is convenient to see the actual algorithm of keys even if no certificate has yet been created. Signed-off-by: Werner Koch diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 7add56d..0d6dabf 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -1299,6 +1299,45 @@ scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen) +/* Send a READKEY command to the SCdaemon. On success a new + * s-expression is stored at R_RESULT. */ +gpg_error_t +scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + membuf_t data; + unsigned char *buf; + size_t len, buflen; + + *r_result = NULL; + err = start_agent (0); + if (err) + return err; + + init_membuf (&data, 1024); + snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr); + err = assuan_transact (agent_ctx, line, + put_membuf_cb, &data, + NULL, NULL, + NULL, NULL); + if (err) + { + xfree (get_membuf (&data, &len)); + return err; + } + buf = get_membuf (&data, &buflen); + if (!buf) + return gpg_error_from_syserror (); + + err = gcry_sexp_new (r_result, buf, buflen, 0); + xfree (buf); + + return err; +} + + + /* Callback function for card_cardlist. */ static gpg_error_t card_cardlist_cb (void *opaque, const char *line) diff --git a/tools/card-tool-misc.c b/tools/card-tool-misc.c index 06fcb67..5e0461c 100644 --- a/tools/card-tool-misc.c +++ b/tools/card-tool-misc.c @@ -77,3 +77,61 @@ hex_to_buffer (const char *string, size_t *r_length) *r_length = n; return buffer; } + + + +/* Given the public key S_PKEY, return a new buffer with a descriptive + * string for its algorithm. This function always returns a string. */ +char * +pubkey_algo_string (gcry_sexp_t s_pkey) +{ + const char *prefix; + gcry_sexp_t l1; + char *algoname; + int algo; + char *result; + + l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); + if (!l1) + return xstrdup ("E_no_key"); + { + gcry_sexp_t l_tmp = gcry_sexp_cadr (l1); + gcry_sexp_release (l1); + l1 = l_tmp; + } + algoname = gcry_sexp_nth_string (l1, 0); + gcry_sexp_release (l1); + if (!algoname) + return xstrdup ("E_no_algo"); + + algo = gcry_pk_map_name (algoname); + switch (algo) + { + case GCRY_PK_RSA: prefix = "rsa"; break; + case GCRY_PK_ELG: prefix = "elg"; break; + case GCRY_PK_DSA: prefix = "dsa"; break; + case GCRY_PK_ECC: prefix = ""; break; + default: prefix = NULL; break; + } + + if (prefix && *prefix) + result = xasprintf ("%s%u", prefix, gcry_pk_get_nbits (s_pkey)); + else if (prefix) + { + const char *curve = gcry_pk_get_curve (s_pkey, 0, NULL); + const char *name = openpgp_oid_to_curve + (openpgp_curve_to_oid (curve, NULL), 0); + + if (name) + result = xstrdup (name); + else if (curve) + result = xasprintf ("X_%s", curve); + else + result = xstrdup ("E_unknown"); + } + else + result = xasprintf ("X_algo_%d", algo); + + xfree (algoname); + return result; +} diff --git a/tools/card-tool.h b/tools/card-tool.h index 2707b3e..c121e88 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -192,6 +192,7 @@ gpg_error_t test_get_matching_keys (const char *hexgrip); /*-- card-tool-misc.c --*/ key_info_t find_kinfo (card_info_t info, const char *keyref); void *hex_to_buffer (const char *string, size_t *r_length); +char *pubkey_algo_string (gcry_sexp_t s_pkey); /*-- card-call-scd.c --*/ @@ -211,6 +212,7 @@ gpg_error_t scd_genkey (int keyno, int force, u32 *createtime); gpg_error_t scd_serialno (char **r_serialno, const char *demand); gpg_error_t scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen); +gpg_error_t scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result); gpg_error_t scd_cardlist (strlist_t *result); gpg_error_t scd_change_pin (const char *pinref, int reset_mode); gpg_error_t scd_checkpin (const char *serialno); diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 0dbf2b2..71ce13f 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -620,6 +620,7 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp) userid_t uid; key_info_t ki; const char *s; + gcry_sexp_t s_pkey; if (firstkinfo && kinfo) { @@ -630,6 +631,14 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp) goto leave; } print_keygrip (fp, kinfo->grip); + if (!scd_readkey (kinfo->keyref, &s_pkey)) + { + char *tmp = pubkey_algo_string (s_pkey); + tty_fprintf (fp, " algorithm ..: %s\n", tmp); + xfree (tmp); + gcry_sexp_release (s_pkey); + s_pkey = NULL; + } if (kinfo->fprlen && kinfo->created) { ----------------------------------------------------------------------- Summary of changes: tools/card-call-scd.c | 39 +++++++++++++++++++++++++++++++++ tools/card-tool-misc.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/card-tool.h | 2 ++ tools/gpg-card-tool.c | 9 ++++++++ 4 files changed, 108 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 8 11:58:52 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Feb 2019 11:58:52 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-365-ga1cb4a9 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 a1cb4a940f308ba21ecc002b044efccf0c547784 (commit) via b349adc5c0d00d2fc405a45bd078f1580b5610cc (commit) via e2f18023b3b3b7e55b35218f65e37448d1011172 (commit) from b79bc877f2ad4d08e7de377cf4bf616b981b3c5f (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 a1cb4a940f308ba21ecc002b044efccf0c547784 Author: Werner Koch Date: Fri Feb 8 11:58:27 2019 +0100 card: Make "generate" work for PIV cards. * tools/card-call-scd.c (scd_genkey_cb): Make createtime optional. (scd_genkey_cb): Ditto. Add arg algo. * tools/gpg-card-tool.c (cmd_generate): Add options and factor card specific code out to ... (generate_openpgp, generate_generic): new functions. -- This patch keeps the interactive OpenPGP mode but adds a pure command line mode for other cards; in particular PIV cards. What we still need to do is: a) Add an interactive mode for PIV cards b) Add a command line mode for OpenPGP cards. Signed-off-by: Werner Koch diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 0d6dabf..97fb6d9 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -202,7 +202,7 @@ app_type_string (app_type_t app_type) case APP_TYPE_OPENPGP: result = "OpenPGP"; break; case APP_TYPE_NKS: result = "NetKey"; break; case APP_TYPE_DINSIG: result = "DINSIG"; break; - case APP_TYPE_P15: result = "PKCS#15"; break; + case APP_TYPE_P15: result = "P15"; break; case APP_TYPE_GELDKARTE: result = "Geldkarte"; break; case APP_TYPE_SC_HSM: result = "SC-HSM"; break; case APP_TYPE_PIV: result = "PIV"; break; @@ -1174,7 +1174,8 @@ scd_genkey_cb (void *opaque, const char *line) if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen)) { - *createtime = (u32)strtoul (line, NULL, 10); + if (createtime) + *createtime = (u32)strtoul (line, NULL, 10); } else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen)) { @@ -1190,7 +1191,7 @@ scd_genkey_cb (void *opaque, const char *line) * SCDEAMON. On success, creation time is stored back to * CREATETIME. */ gpg_error_t -scd_genkey (int keyno, int force, u32 *createtime) +scd_genkey (const char *keyref, int force, const char *algo, u32 *createtime) { gpg_error_t err; char line[ASSUAN_LINELENGTH]; @@ -1203,15 +1204,17 @@ scd_genkey (int keyno, int force, u32 *createtime) if (err) return err; - if (*createtime) + if (createtime && *createtime) epoch2isotime (tbuf, *createtime); else *tbuf = 0; - snprintf (line, sizeof line, "SCD GENKEY %s%s %s %d", + snprintf (line, sizeof line, "SCD GENKEY %s%s %s %s%s -- %s", *tbuf? "--timestamp=":"", tbuf, force? "--force":"", - keyno); + algo? "--algo=":"", + algo? algo:"", + keyref); dfltparm.ctx = agent_ctx; err = assuan_transact (agent_ctx, line, diff --git a/tools/card-tool.h b/tools/card-tool.h index c121e88..9daf7e4 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -208,7 +208,8 @@ gpg_error_t scd_writecert (const char *certidstr, const unsigned char *certdata, size_t certdatalen); gpg_error_t scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen); -gpg_error_t scd_genkey (int keyno, int force, u32 *createtime); +gpg_error_t scd_genkey (const char *keyref, int force, const char *algo, + u32 *createtime); gpg_error_t scd_serialno (char **r_serialno, const char *demand); gpg_error_t scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen); diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 71ce13f..93153b1 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -1722,7 +1722,8 @@ cmd_forcesig (card_info_t info) } -/* Helper for cmd_generate. Noe that either 0 or 1 is stored at + +/* Helper for cmd_generate_openpgp. Noe that either 0 or 1 is stored at * FORCED_CHV1. */ static gpg_error_t check_pin_for_key_operation (card_info_t info, int *forced_chv1) @@ -1754,7 +1755,7 @@ check_pin_for_key_operation (card_info_t info, int *forced_chv1) } -/* Helper for cmd_generate. */ +/* Helper for cmd_generate_openpgp. */ static void restore_forced_chv1 (int *forced_chv1) { @@ -1775,8 +1776,9 @@ restore_forced_chv1 (int *forced_chv1) } +/* Implementation of cmd_generate for OpenPGP cards. */ static gpg_error_t -cmd_generate (card_info_t info) +generate_openpgp (card_info_t info) { gpg_error_t err; int forced_chv1 = -1; @@ -1784,18 +1786,6 @@ cmd_generate (card_info_t info) char *answer = NULL; key_info_t kinfo1, kinfo2, kinfo3; - if (!info) - return print_help - ("GENERATE\n\n" - "Menu to generate a new keys.", - APP_TYPE_OPENPGP, 0); - - if (info->apptype != APP_TYPE_OPENPGP) - { - log_info ("Note: This is an OpenPGP only command.\n"); - return gpg_error (GPG_ERR_NOT_SUPPORTED); - } - if (info->extcap.ki) { xfree (answer); @@ -1811,7 +1801,6 @@ cmd_generate (card_info_t info) else want_backup = 0; - kinfo1 = find_kinfo (info, "OPENPGP.1"); kinfo2 = find_kinfo (info, "OPENPGP.2"); kinfo3 = find_kinfo (info, "OPENPGP.3"); @@ -1860,6 +1849,7 @@ cmd_generate (card_info_t info) * gpg. We might also first create the keys on the card and then * tell gpg to use them to create the OpenPGP keyblock. */ /* generate_keypair (ctrl, 1, NULL, info.serialno, want_backup); */ + (void)want_backup; err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); leave: @@ -1869,6 +1859,126 @@ cmd_generate (card_info_t info) } +/* Generic implementation of cmd_generate. */ +static gpg_error_t +generate_generic (card_info_t info, const char *keyref, int force, + const char *algo) +{ + gpg_error_t err; + + (void)info; + + err = scd_genkey (keyref, force, algo, NULL); + + return err; +} + + +static gpg_error_t +cmd_generate (card_info_t info, char *argstr) +{ + static char * const valid_algos[] = + { "rsa2048", "rsa3072", "rsa4096", + "nistp256", "nistp384", "nistp521", + "ed25519", "cv25519", + NULL + }; + gpg_error_t err; + int opt_force; + char *opt_algo = NULL; /* Malloced. */ + char *keyref_buffer = NULL; /* Malloced. */ + char *keyref; /* Points into argstr or keyref_buffer. */ + int i; + + if (!info) + return print_help + ("GENERATE [--force] [--algo=ALGO] KEYREF\n\n" + "Create a new key on a card. For OpenPGP cards are menu is used\n" + "and KEYREF is ignored. Use --force to overwrite an existing key.", + APP_TYPE_OPENPGP, APP_TYPE_PIV, 0); + + if (opt.interactive || opt.verbose) + log_info (_("%s card no. %s detected\n"), + app_type_string (info->apptype), + info->dispserialno? info->dispserialno : info->serialno); + + opt_force = has_leading_option (argstr, "--force"); + err = get_option_value (argstr, "--algo", &opt_algo); + if (err) + goto leave; + argstr = skip_options (argstr); + + keyref = argstr; + if ((argstr = strchr (keyref, ' '))) + { + *argstr++ = 0; + trim_spaces (keyref); + trim_spaces (argstr); + } + else /* Let argstr point to an empty string. */ + argstr = keyref + strlen (keyref); + + if (!*keyref) + keyref = NULL; + + if (*argstr) + { + /* Extra arguments found. */ + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (opt_algo) + { + for (i=0; valid_algos[i]; i++) + if (!strcmp (valid_algos[i], opt_algo)) + break; + if (!valid_algos[i]) + { + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + log_info ("Invalid algorithm '%s' given. Use one:\n", opt_algo); + for (i=0; valid_algos[i]; i++) + if (!(i%5)) + log_info (" %s%s", valid_algos[i], valid_algos[i+1]?",":"."); + else + log_printf (" %s%s", valid_algos[i], valid_algos[i+1]?",":"."); + log_info ("Note that the card may not support all of them.\n"); + goto leave; + } + } + + /* Upcase the keyref; if it misses the cardtype, prepend it. */ + if (keyref) + { + if (!strchr (keyref, '.')) + keyref_buffer = xstrconcat (app_type_string (info->apptype), ".", + keyref, NULL); + else + keyref_buffer = xstrdup (keyref); + ascii_strupr (keyref_buffer); + keyref = keyref_buffer; + } + + /* Divert to dedicated functions. */ + if (info->apptype == APP_TYPE_OPENPGP) + { + if (opt_force || opt_algo || keyref) + log_info ("Note: Options are ignored for OpenPGP cards.\n"); + err = generate_openpgp (info); + } + else if (!keyref) + err = gpg_error (GPG_ERR_INV_ID); + else + err = generate_generic (info, keyref, opt_force, opt_algo); + + leave: + xfree (opt_algo); + xfree (keyref_buffer); + return err; +} + + + /* Sub-menu to change a PIN. The presented options may depend on the * the ALLOW_ADMIN flag. */ static gpg_error_t @@ -2572,6 +2682,8 @@ ask_card_keyattr (int keyno, const struct key_attr *current, curve = current->curve; } + (void)curve; + (void)algo; err = GPG_ERR_NOT_IMPLEMENTED; goto leave; /* FIXME: We need to mve the ask_cure code out to common or @@ -2929,7 +3041,7 @@ dispatch_command (card_info_t info, const char *orig_command) case cmdWRITECERT: err = cmd_writecert (info, argstr); break; case cmdREADCERT: err = cmd_readcert (info, argstr); break; case cmdFORCESIG: err = cmd_forcesig (info); break; - case cmdGENERATE: err = cmd_generate (info); break; + case cmdGENERATE: err = cmd_generate (info, argstr); break; case cmdPASSWD: err = cmd_passwd (info, 1, argstr); break; case cmdUNBLOCK: err = cmd_unblock (info); break; case cmdFACTORYRESET: err = cmd_factoryreset (info); break; @@ -3195,7 +3307,7 @@ interactive_loop (void) case cmdWRITECERT: err = cmd_writecert (info, argstr); break; case cmdREADCERT: err = cmd_readcert (info, argstr); break; case cmdFORCESIG: err = cmd_forcesig (info); break; - case cmdGENERATE: err = cmd_generate (info); break; + case cmdGENERATE: err = cmd_generate (info, argstr); break; case cmdPASSWD: err = cmd_passwd (info, allow_admin, argstr); break; case cmdUNBLOCK: err = cmd_unblock (info); break; case cmdFACTORYRESET: commit b349adc5c0d00d2fc405a45bd078f1580b5610cc Author: Werner Koch Date: Fri Feb 8 11:53:34 2019 +0100 scd: Allow generating ECC curves on PIV cards. * scd/app-piv.c (genkey_parse_ecc): New. (get_keygrip_by_tag): Call that one. (do_readkey): Call that one. * scd/command.c (cmd_genkey): Add option --algo. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index f4eb918..4387b3a 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -178,6 +178,8 @@ static gpg_error_t get_keygrip_by_tag (app_t app, unsigned int tag, char **r_keygripstr, int *got_cert); static gpg_error_t genkey_parse_rsa (const unsigned char *data, size_t datalen, gcry_sexp_t *r_sexp); +static gpg_error_t genkey_parse_ecc (const unsigned char *data, size_t datalen, + int mechanism, gcry_sexp_t *r_sexp); @@ -1144,6 +1146,9 @@ get_keygrip_by_tag (app_t app, unsigned int tag, { if (mechanism == PIV_ALGORITHM_RSA) err = genkey_parse_rsa (certbuf, certbuflen, &s_pkey); + else if (mechanism == PIV_ALGORITHM_ECC_P256 + || mechanism == PIV_ALGORITHM_ECC_P384) + err = genkey_parse_ecc (certbuf, certbuflen, mechanism, &s_pkey); else err = gpg_error (GPG_ERR_PUBKEY_ALGO); if (err) @@ -1308,6 +1313,9 @@ do_readkey (app_t app, int advanced, const char *keyrefstr, /* Convert the public key into the expected s-expression. */ if (mechanism == PIV_ALGORITHM_RSA) err = genkey_parse_rsa (cert, certlen, &s_pkey); + else if (mechanism == PIV_ALGORITHM_ECC_P256 + || mechanism == PIV_ALGORITHM_ECC_P384) + err = genkey_parse_ecc (cert, certlen, mechanism, &s_pkey); else err = gpg_error (GPG_ERR_PUBKEY_ALGO); if (err) @@ -2155,6 +2163,48 @@ genkey_parse_rsa (const unsigned char *data, size_t datalen, } +/* Parse an ECC response object, consisting of the content of tag + * 0x7f49, into a gcrypt s-expression object and store that R_SEXP. + * On error NULL is stored at R_SEXP. MECHANISM specifies the + * curve. */ +static gpg_error_t +genkey_parse_ecc (const unsigned char *data, size_t datalen, int mechanism, + gcry_sexp_t *r_sexp) +{ + gpg_error_t err; + const unsigned char *ecc_q; + size_t ecc_qlen; + const char *curve; + + *r_sexp = NULL; + + ecc_q = find_tlv (data, datalen, 0x0086, &ecc_qlen); + if (!ecc_q) + { + log_error (_("response does not contain the EC public key\n")); + err = gpg_error (GPG_ERR_CARD); + goto leave; + } + + if (mechanism == PIV_ALGORITHM_ECC_P256) + curve = "nistp256"; + else if (mechanism == PIV_ALGORITHM_ECC_P384) + curve = "nistp384"; + else + { + err = gpg_error (GPG_ERR_BUG); /* Call with wrong parameters. */ + goto leave; + } + + + err = gcry_sexp_build (r_sexp, NULL, "(public-key(ecc(curve%s)(q%b)))", + curve, (int)ecc_qlen, ecc_q); + + leave: + return err; +} + + /* Create a new keypair for KEYREF. If KEYTYPE is NULL a default * keytype is selected, else it may be one of the strings: * "rsa2048", "nistp256, or "nistp384". @@ -2303,6 +2353,9 @@ do_writecert (app_t app, ctrl_t ctrl, /* FIXME: Check that the authentication has already been done. */ + /* FIXME: Check that the public key parameters from the certificate + * match an already stored key. */ + flush_cached_data (app, dobj->tag); err = put_data (app->slot, dobj->tag, (int)0x70, (size_t)certlen, cert,/* Certificate */ diff --git a/scd/command.c b/scd/command.c index 127fb5d..237faf0 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1126,10 +1126,10 @@ cmd_writekey (assuan_context_t ctx, char *line) static const char hlp_genkey[] = - "GENKEY [--force] [--timestamp=] \n" + "GENKEY [--force] [--timestamp=] \n" "\n" - "Generate a key on-card identified by NO, which is application\n" - "specific. Return values are application specific. For OpenPGP\n" + "Generate a key on-card identified by , which is application\n" + "specific. Return values are also application specific. For OpenPGP\n" "cards 3 status lines are returned:\n" "\n" " S KEY-FPR \n" @@ -1154,10 +1154,12 @@ static gpg_error_t cmd_genkey (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int rc; - char *keyno; + gpg_error_t err; + char *keyref_buffer = NULL; + char *keyref; int force; const char *s; + char *opt_algo = NULL; time_t timestamp; force = has_option (line, "--force"); @@ -1173,30 +1175,38 @@ cmd_genkey (assuan_context_t ctx, char *line) else timestamp = 0; + err = get_option_value (line, "--algo", &opt_algo); + if (err) + goto leave; line = skip_options (line); if (!*line) return set_error (GPG_ERR_ASS_PARAMETER, "no key number given"); - keyno = line; + keyref = line; while (*line && !spacep (line)) line++; *line = 0; - if ((rc = open_card (ctrl))) - return rc; + if ((err = open_card (ctrl))) + goto leave; if (!ctrl->app_ctx) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - keyno = xtrystrdup (keyno); - if (!keyno) - return out_of_core (); - rc = app_genkey (ctrl->app_ctx, ctrl, keyno, NULL, - force? APP_GENKEY_FLAG_FORCE : 0, - timestamp, pin_cb, ctx); - xfree (keyno); + keyref = keyref_buffer = xtrystrdup (keyref); + if (!keyref) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = app_genkey (ctrl->app_ctx, ctrl, keyref, opt_algo, + force? APP_GENKEY_FLAG_FORCE : 0, + timestamp, pin_cb, ctx); - return rc; + leave: + xfree (keyref_buffer); + xfree (opt_algo); + return err; } commit e2f18023b3b3b7e55b35218f65e37448d1011172 Author: Werner Koch Date: Fri Feb 8 09:32:55 2019 +0100 common: New functions get_option_value and ascii_strupr. * common/server-help.c (get_option_value): New. * common/stringhelp.c (ascii_strupr): New. Signed-off-by: Werner Koch diff --git a/common/server-help.c b/common/server-help.c index 53a888a..e5a69e0 100644 --- a/common/server-help.c +++ b/common/server-help.c @@ -30,8 +30,22 @@ #include #include -#include "server-help.h" #include "util.h" +#include "server-help.h" + + +static GPGRT_INLINE gpg_error_t +my_error (int e) +{ + return gpg_err_make (default_errsource, (e)); +} + +static GPGRT_INLINE gpg_error_t +my_error_from_syserror (void) +{ + return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); +} + /* Skip over options in LINE. @@ -114,6 +128,40 @@ has_option_name (const char *line, const char *name) } +/* Parse an option with the format "--NAME=VALUE" which must occur in + * LINE before a double-dash. LINE is written to but not modified by + * this function. If the option is found and has a value the value is + * stored as a malloced string at R_VALUE. If the option was not + * found or an error occurred NULL is stored there. Note that + * currently the value must be a string without any space; we may + * eventually update this function to allow for a quoted value. */ +gpg_error_t +get_option_value (char *line, const char *name, char **r_value) +{ + char *p, *pend; + int c; + + *r_value = NULL; + + p = (char*)has_option_name (line, name); + if (!p || p >= skip_options (line)) + return 0; + + if (*p != '=' || !p[1] || spacep (p+1)) + return my_error (GPG_ERR_INV_ARG); + p++; + for (pend = p; *pend && !spacep (pend); pend++) + ; + c = *pend; + *pend = 0; + *r_value = xtrystrdup (p); + *pend = c; + if (!p) + return my_error_from_syserror (); + return 0; +} + + /* Return a pointer to the argument of the option with NAME. If such an option is not given, NULL is returned. */ char * diff --git a/common/server-help.h b/common/server-help.h index 9e3d7ad..9d2f4cf 100644 --- a/common/server-help.h +++ b/common/server-help.h @@ -55,6 +55,14 @@ int has_leading_option (const char *line, const char *name); or a space. */ const char *has_option_name (const char *line, const char *name); +/* Same as has_option_name but ignores all options after a "--" and + * does not return a const char ptr. */ +char *has_leading_option_name (char *line, const char *name); + +/* Parse an option with the format "--NAME=VALUE" and return the value + * as a malloced string. */ +gpg_error_t get_option_value (char *line, const char *name, char **r_value); + /* Return a pointer to the argument of the option with NAME. If such an option is not given, NULL is returned. */ char *option_value (const char *line, const char *name); diff --git a/common/stringhelp.c b/common/stringhelp.c index 751e571..dd17116 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -810,6 +810,19 @@ ascii_strlwr (char *s) return s; } +/* Upcase all ASCII characters in S. */ +char * +ascii_strupr (char *s) +{ + char *p = s; + + for (p=s; *p; p++ ) + if (isascii (*p) && *p >= 'a' && *p <= 'z') + *p &= ~0x20; + + return s; +} + int ascii_strcasecmp( const char *a, const char *b ) { diff --git a/common/stringhelp.h b/common/stringhelp.h index 5b07af9..7df6c76 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -76,6 +76,7 @@ int ascii_islower (int c); int ascii_toupper (int c); int ascii_tolower (int c); char *ascii_strlwr (char *s); +char *ascii_strupr (char *s); int ascii_strcasecmp( const char *a, const char *b ); int ascii_strncasecmp (const char *a, const char *b, size_t n); int ascii_memcasecmp( const void *a, const void *b, size_t n ); ----------------------------------------------------------------------- Summary of changes: common/server-help.c | 50 ++++++++++++++++- common/server-help.h | 8 +++ common/stringhelp.c | 13 +++++ common/stringhelp.h | 1 + scd/app-piv.c | 53 ++++++++++++++++++ scd/command.c | 42 ++++++++------ tools/card-call-scd.c | 15 +++-- tools/card-tool.h | 3 +- tools/gpg-card-tool.c | 148 ++++++++++++++++++++++++++++++++++++++++++++------ 9 files changed, 291 insertions(+), 42 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 8 12:35:52 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Feb 2019 12:35:52 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-367-g0328976 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 0328976c94adc2c518c7a7763a35319a0000c5e2 (commit) via 03bf8e967adb2dd13329ba1089deb419d49e55c0 (commit) from a1cb4a940f308ba21ecc002b044efccf0c547784 (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 0328976c94adc2c518c7a7763a35319a0000c5e2 Author: Werner Koch Date: Fri Feb 8 12:35:26 2019 +0100 sm: In --gen-key with "key from card" show also the algorithm. * sm/certreqgen-ui.c (gpgsm_gencertreq_tty): Get and show algo. -- This extends the prompt to show something like Serial number of the card: FF020001008A77F6 Available keys: (1) 4130F84FA3704F4645924AEC3FFA48AD26D33656 PIV.9A nistp384 (2) AB2988FB8C227BCD5175BF92F66AA3A95AE83214 PIV.9E rsa2048 (3) DB7DDAEAA88534BA45CCD7A9B761425103EA2090 PIV.9C rsa2048 (4) BABB48C3D80ACCF9839F101DF2910966C8B988DF PIV.9D nistp256 Your selection? 1 Having the algorithm here is helpful in particular because right now we support only RSA with X.509. Take care: PIV card based certificate creation does not yet work. Signed-off-by: Werner Koch diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index f64baf3..70e5739 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -244,7 +244,27 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) { tty_printf (_("Available keys:\n")); for (count=1,sl=keypairlist; sl; sl = sl->next, count++) - tty_printf (" (%d) %s\n", count, sl->d); + { + ksba_sexp_t pkey; + gcry_sexp_t s_pkey; + char *algostr = NULL; + const char *keyref; + + keyref = strchr (sl->d, ' '); + if (keyref) + { + keyref++; + if (!gpgsm_agent_readkey (ctrl, 1, keyref, &pkey)) + { + if (!gcry_sexp_new (&s_pkey, pkey, 0, 0)) + algostr = pubkey_algo_string (s_pkey); + gcry_sexp_release (s_pkey); + } + xfree (pkey); + } + tty_printf (" (%d) %s %s\n", count, sl->d, algostr); + xfree (algostr); + } xfree (answer); answer = tty_get (_("Your selection? ")); tty_kill_prompt (); commit 03bf8e967adb2dd13329ba1089deb419d49e55c0 Author: Werner Koch Date: Fri Feb 8 12:10:45 2019 +0100 common: Provide function to get public key algo names in our format. * tools/card-tool-misc.c (pubkey_algo_string): Move to ... * common/sexputil.c (pubkey_algo_string): here. -- The new gpg format for public key algorithms is useful at other places as well. Thus we make this new function available. Note that the code we use in gpg is not based on s-expressions and thus a new function was required. Signed-off-by: Werner Koch diff --git a/common/sexputil.c b/common/sexputil.c index 02e52d0..d3020e1 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -577,3 +577,61 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen) gcry_sexp_release (sexp); return algo; } + + +/* Given the public key S_PKEY, return a new buffer with a descriptive + * string for its algorithm. This function may return NULL on memory + * error. */ +char * +pubkey_algo_string (gcry_sexp_t s_pkey) +{ + const char *prefix; + gcry_sexp_t l1; + char *algoname; + int algo; + char *result; + + l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); + if (!l1) + return xtrystrdup ("E_no_key"); + { + gcry_sexp_t l_tmp = gcry_sexp_cadr (l1); + gcry_sexp_release (l1); + l1 = l_tmp; + } + algoname = gcry_sexp_nth_string (l1, 0); + gcry_sexp_release (l1); + if (!algoname) + return xtrystrdup ("E_no_algo"); + + algo = gcry_pk_map_name (algoname); + switch (algo) + { + case GCRY_PK_RSA: prefix = "rsa"; break; + case GCRY_PK_ELG: prefix = "elg"; break; + case GCRY_PK_DSA: prefix = "dsa"; break; + case GCRY_PK_ECC: prefix = ""; break; + default: prefix = NULL; break; + } + + if (prefix && *prefix) + result = xtryasprintf ("%s%u", prefix, gcry_pk_get_nbits (s_pkey)); + else if (prefix) + { + const char *curve = gcry_pk_get_curve (s_pkey, 0, NULL); + const char *name = openpgp_oid_to_curve + (openpgp_curve_to_oid (curve, NULL), 0); + + if (name) + result = xtrystrdup (name); + else if (curve) + result = xtryasprintf ("X_%s", curve); + else + result = xtrystrdup ("E_unknown"); + } + else + result = xtryasprintf ("X_algo_%d", algo); + + xfree (algoname); + return result; +} diff --git a/common/util.h b/common/util.h index 863f9e3..d5bb225 100644 --- a/common/util.h +++ b/common/util.h @@ -189,6 +189,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, int get_pk_algo_from_key (gcry_sexp_t key); int get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen); +char *pubkey_algo_string (gcry_sexp_t s_pkey); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); diff --git a/tools/card-tool-misc.c b/tools/card-tool-misc.c index 5e0461c..06fcb67 100644 --- a/tools/card-tool-misc.c +++ b/tools/card-tool-misc.c @@ -77,61 +77,3 @@ hex_to_buffer (const char *string, size_t *r_length) *r_length = n; return buffer; } - - - -/* Given the public key S_PKEY, return a new buffer with a descriptive - * string for its algorithm. This function always returns a string. */ -char * -pubkey_algo_string (gcry_sexp_t s_pkey) -{ - const char *prefix; - gcry_sexp_t l1; - char *algoname; - int algo; - char *result; - - l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); - if (!l1) - return xstrdup ("E_no_key"); - { - gcry_sexp_t l_tmp = gcry_sexp_cadr (l1); - gcry_sexp_release (l1); - l1 = l_tmp; - } - algoname = gcry_sexp_nth_string (l1, 0); - gcry_sexp_release (l1); - if (!algoname) - return xstrdup ("E_no_algo"); - - algo = gcry_pk_map_name (algoname); - switch (algo) - { - case GCRY_PK_RSA: prefix = "rsa"; break; - case GCRY_PK_ELG: prefix = "elg"; break; - case GCRY_PK_DSA: prefix = "dsa"; break; - case GCRY_PK_ECC: prefix = ""; break; - default: prefix = NULL; break; - } - - if (prefix && *prefix) - result = xasprintf ("%s%u", prefix, gcry_pk_get_nbits (s_pkey)); - else if (prefix) - { - const char *curve = gcry_pk_get_curve (s_pkey, 0, NULL); - const char *name = openpgp_oid_to_curve - (openpgp_curve_to_oid (curve, NULL), 0); - - if (name) - result = xstrdup (name); - else if (curve) - result = xasprintf ("X_%s", curve); - else - result = xstrdup ("E_unknown"); - } - else - result = xasprintf ("X_algo_%d", algo); - - xfree (algoname); - return result; -} diff --git a/tools/card-tool.h b/tools/card-tool.h index 9daf7e4..f49f253 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -192,8 +192,6 @@ gpg_error_t test_get_matching_keys (const char *hexgrip); /*-- card-tool-misc.c --*/ key_info_t find_kinfo (card_info_t info, const char *keyref); void *hex_to_buffer (const char *string, size_t *r_length); -char *pubkey_algo_string (gcry_sexp_t s_pkey); - /*-- card-call-scd.c --*/ void release_card_info (card_info_t info); ----------------------------------------------------------------------- Summary of changes: common/sexputil.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ common/util.h | 1 + sm/certreqgen-ui.c | 22 ++++++++++++++++++- tools/card-tool-misc.c | 58 -------------------------------------------------- tools/card-tool.h | 2 -- 5 files changed, 80 insertions(+), 61 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 8 17:06:15 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 08 Feb 2019 17:06:15 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-368-g53beea5 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 53beea56afecde76f0f4ca93fc50ca59298a093e (commit) from 0328976c94adc2c518c7a7763a35319a0000c5e2 (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 53beea56afecde76f0f4ca93fc50ca59298a093e Author: Werner Koch Date: Fri Feb 8 16:46:52 2019 +0100 scd: Implement RSA signing for PIV cards. * scd/app-piv.c (concat_tlv_list): New. (get_key_algorithm_by_dobj): Rename args for clarity. (do_auth): factor all code out to ... (do_sign): new. Implement RSA signing. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index 4387b3a..1d70db5 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -469,6 +469,107 @@ add_tlv (unsigned char *buffer, unsigned int tag, size_t length) } +/* Function to build a list of TLV and return the result in a mallcoed + * buffer. The varargs are tuples of (int,size_t,void) each with the + * tag, the length and the actual data. A (0,0,NULL) tuple terminates + * the list. Up to 10 tuples are supported. */ +static gpg_error_t +concat_tlv_list (unsigned char **r_result, size_t *r_resultlen, ...) +{ + gpg_error_t err; + va_list arg_ptr; + struct { + int tag; + unsigned int len; + unsigned int contlen; + const void *data; + } argv[10]; + int i, j, argc; + unsigned char *data = NULL; + size_t datalen; + unsigned char *p; + size_t n; + + *r_result = NULL; + *r_resultlen = 0; + + /* Collect all args. Check that length is <= 2^16 to match the + * behaviour of add_tlv. */ + va_start (arg_ptr, r_resultlen); + argc = 0; + while (((argv[argc].tag = va_arg (arg_ptr, int)))) + { + argv[argc].len = va_arg (arg_ptr, size_t); + argv[argc].contlen = 0; + argv[argc].data = va_arg (arg_ptr, const void *); + if (argc >= DIM (argv)-1 || argv[argc].len > 0xffff) + { + va_end (arg_ptr); + err = gpg_error (GPG_ERR_EINVAL); + goto leave; + } + argc++; + } + va_end (arg_ptr); + + /* Compute the required buffer length and allocate the buffer. */ + datalen = 0; + for (i=0; i < argc; i++) + { + if (!argv[i].len && !argv[i].data) + { + /* Constructed tag. Compute its length. Note that we + * currently allow only one constructed tag in the list. */ + for (n=0, j = i + 1; j < argc; j++) + { + log_assert (!(!argv[j].len && !argv[j].data)); + n += add_tlv (NULL, argv[j].tag, argv[j].len); + n += argv[j].len; + } + argv[i].contlen = n; + datalen += add_tlv (NULL, argv[i].tag, n); + } + else + { + datalen += add_tlv (NULL, argv[i].tag, argv[i].len); + datalen += argv[i].len; + } + } + data = xtrymalloc (datalen); + if (!data) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Copy that data to the buffer. */ + p = data; + for (i=0; i < argc; i++) + { + if (!argv[i].len && !argv[i].data) + { + /* Constructed tag. */ + p += add_tlv (p, argv[i].tag, argv[i].contlen); + } + else + { + p += add_tlv (p, argv[i].tag, argv[i].len); + memcpy (p, argv[i].data, argv[i].len); + p += argv[i].len; + } + } + log_assert ( data + datalen == p ); + *r_result = data; + data = NULL; + *r_resultlen = datalen; + err = 0; + + leave: + xfree (data); + return err; +} + + /* Wrapper around iso7816_put_data_odd which also sets the tag into * the '5C' data object. The varargs are tuples of (int,size_t,void) * with the tag, the length and the actual data. A (0,0,NULL) tuple @@ -1354,7 +1455,7 @@ do_readkey (app_t app, int advanced, const char *keyrefstr, * store it at R_ALGO. The algorithm is taken from the corresponding * certificate or from a cache. */ static gpg_error_t -get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo) +get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_mechanism) { gpg_error_t err; unsigned char *certbuf = NULL; @@ -1369,7 +1470,7 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo) size_t n; const char *curve_name; - *r_algo = 0; + *r_mechanism = 0; err = readcert_by_tag (app, dobj->tag, &certbuf, &certbuflen, &mechanism); if (err) @@ -1382,7 +1483,7 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo) case PIV_ALGORITHM_RSA: case PIV_ALGORITHM_ECC_P256: case PIV_ALGORITHM_ECC_P384: - *r_algo = mechanism; + *r_mechanism = mechanism; break; default: @@ -1468,7 +1569,7 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_algo) dobj->keyref, algoname, gpg_strerror (err)); goto leave; } - *r_algo = algo; + *r_mechanism = algo; leave: gcry_free (algoname); @@ -1862,10 +1963,11 @@ do_check_chv (app_t app, const char *pwidstr, * stored there and an error code returned. For ECDSA the result is * the simple concatenation of R and S without any DER encoding. R * and S are left extended with zeroes to make sure they have an equal - * length. + * length. If HASHALGO is not zero, the function prepends the hash's + * OID to the indata or checks that it is consistent. */ static gpg_error_t -do_auth (app_t app, const char *keyidstr, +do_sign (app_t app, const char *keyidstr, int hashalgo, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *indata_arg, size_t indatalen, @@ -1874,13 +1976,16 @@ do_auth (app_t app, const char *keyidstr, const unsigned char *indata = indata_arg; gpg_error_t err; data_object_t dobj; - unsigned char tmpl[2+2+2+128]; - size_t tmpllen; + unsigned char oidbuf[64]; + size_t oidbuflen; unsigned char *outdata = NULL; size_t outdatalen; const unsigned char *s; size_t n; - int keyref, algo; + int keyref, mechanism; + unsigned char *indata_buffer = NULL; /* Malloced helper. */ + unsigned char *apdudata = NULL; + size_t apdudatalen; if (!keyidstr || !*keyidstr) { @@ -1888,9 +1993,6 @@ do_auth (app_t app, const char *keyidstr, goto leave; } - /* Fixme: Shall we support the KEYID/FINGERPRINT syntax? Does it - * make sense for X.509 certs? */ - dobj = find_dobj_by_keyref (app, keyidstr); if ((keyref = keyref_from_dobj (dobj)) == -1) { @@ -1898,69 +2000,141 @@ do_auth (app_t app, const char *keyidstr, goto leave; } - err = get_key_algorithm_by_dobj (app, dobj, &algo); + err = get_key_algorithm_by_dobj (app, dobj, &mechanism); if (err) goto leave; - /* We need to remove the ASN.1 prefix from INDATA. We use TEMPL as - * a temporary buffer for the OID. */ - if (algo == PIV_ALGORITHM_ECC_P256) + /* For ECC we need to remove the ASN.1 prefix from INDATA. For RSA + * we need to add the padding and possible also the ASN.1 prefix. */ + if (mechanism == PIV_ALGORITHM_ECC_P256 + || mechanism == PIV_ALGORITHM_ECC_P384) { - tmpllen = sizeof tmpl; - err = gcry_md_get_asnoid (GCRY_MD_SHA256, &tmpl, &tmpllen); - if (err) + int need_algo, need_digestlen; + + if (mechanism == PIV_ALGORITHM_ECC_P256) { - err = gpg_error (GPG_ERR_INTERNAL); - log_debug ("piv: no OID for hash algo %d\n", GCRY_MD_SHA256); - goto leave; + need_algo = GCRY_MD_SHA256; + need_digestlen = 32; } - if (indatalen != tmpllen + 32 || memcmp (indata, tmpl, tmpllen)) + else { - err = GPG_ERR_INV_VALUE; - log_error ("piv: bad formatted input for ECC-P256 auth\n"); + need_algo = GCRY_MD_SHA384; + need_digestlen = 48; + } + + if (hashalgo && hashalgo != need_algo) + { + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + log_error ("piv: hash algo %d does not match mechanism %d\n", + need_algo, mechanism); goto leave; } - indata +=tmpllen; - indatalen -= tmpllen; + + if (indatalen > need_digestlen) + { + oidbuflen = sizeof oidbuf; + err = gcry_md_get_asnoid (need_algo, &oidbuf, &oidbuflen); + if (err) + { + err = gpg_error (GPG_ERR_INTERNAL); + log_debug ("piv: no OID for hash algo %d\n", need_algo); + goto leave; + } + if (indatalen != oidbuflen + need_digestlen + || memcmp (indata, oidbuf, oidbuflen)) + { + err = gpg_error (GPG_ERR_INV_VALUE); + log_error ("piv: bad input for signing with mechanism %d\n", + mechanism); + goto leave; + } + indata += oidbuflen; + indatalen -= oidbuflen; + } } - else if (algo == PIV_ALGORITHM_ECC_P384) + else if (mechanism == PIV_ALGORITHM_RSA) { - tmpllen = sizeof tmpl; - err = gcry_md_get_asnoid (GCRY_MD_SHA384, &tmpl, &tmpllen); - if (err) + /* PIV requires 2048 bit RSA. */ + unsigned int framelen = 2048 / 8; + unsigned char *frame; + int i; + + oidbuflen = sizeof oidbuf; + if (!hashalgo) { - err = gpg_error (GPG_ERR_INTERNAL); - log_debug ("piv: no OID for hash algo %d\n", GCRY_MD_SHA384); + /* We assume that indata already has the required + * digestinfo; thus merely prepend the padding below. */ + } + else if ((err = gcry_md_get_asnoid (hashalgo, &oidbuf, &oidbuflen))) + { + log_debug ("piv: no OID for hash algo %d\n", hashalgo); goto leave; } - if (indatalen != tmpllen + 48 || memcmp (indata, tmpl, tmpllen)) + else { - err = GPG_ERR_INV_VALUE; - log_error ("piv: bad formatted input for ECC-P384 auth\n"); + unsigned int digestlen = gcry_md_get_algo_dlen (hashalgo); + + if (indatalen == digestlen) + { + /* Plain hash in INDATA; prepend the digestinfo. */ + indata_buffer = xtrymalloc (oidbuflen + indatalen); + if (!indata_buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (indata_buffer, oidbuf, oidbuflen); + memcpy (indata_buffer+oidbuflen, indata, indatalen); + indata = indata_buffer; + indatalen = oidbuflen + indatalen; + } + else if (indatalen == oidbuflen + digestlen + && !memcmp (indata, oidbuf, oidbuflen)) + ; /* Correct prefix. */ + else + { + err = gpg_error (GPG_ERR_INV_VALUE); + log_error ("piv: bad input for signing with RSA and hash %d\n", + hashalgo); + goto leave; + } + } + /* Now prepend the pkcs#v1.5 padding. We require at least 8 + * byte of padding and 3 extra bytes for the prefix and the + * delimiting nul. */ + if (!indatalen || indatalen + 8 + 4 > framelen) + { + err = gpg_error (GPG_ERR_INV_VALUE); + log_error ("piv: input does not fit into a %u bit PKCS#v1.5 frame\n", + 8*framelen); goto leave; } - indata += tmpllen; - indatalen -= tmpllen; - } - else if (algo == PIV_ALGORITHM_RSA) - { - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - log_error ("piv: FIXME: implement RSA authentication\n"); - goto leave; + frame = xtrymalloc (framelen); + if (!frame) + { + err = gpg_error_from_syserror (); + goto leave; + } + n = 0; + frame[n++] = 0; + frame[n++] = 1; /* Block type. */ + i = framelen - indatalen - 3 ; + memset (frame+n, 0xff, i); + n += i; + frame[n++] = 0; /* Delimiter. */ + memcpy (frame+n, indata, indatalen); + n += indatalen; + log_assert (n == framelen); + /* And now put it into the indata_buffer. */ + xfree (indata_buffer); + indata_buffer = frame; + indata = indata_buffer; + indatalen = framelen; } else { err = gpg_error (GPG_ERR_INTERNAL); - log_debug ("piv: unknown PIV algo %d from helper function\n", algo); - goto leave; - } - - /* Because we don't have a dynamic template builder we make sure - * that we can encode all lengths in one octet. FIXME: Use add_tls - * from app-openpgp as a base for an strconcat like function. */ - if (indatalen >= 100) - { - err = gpg_error (GPG_ERR_TOO_LARGE); + log_debug ("piv: unknown PIV mechanism %d while signing\n", mechanism); goto leave; } @@ -1970,19 +2144,18 @@ do_auth (app_t app, const char *keyidstr, return err; /* Build the Dynamic Authentication Template. */ - tmpl[0] = 0x7c; - tmpl[1] = indatalen + 4; - tmpl[2] = 0x82; /* Response. */ - tmpl[3] = 0; /* Must be 0 to get the tag in the answer. */ - tmpl[4] = 0x81; /* Challenge. */ - tmpl[5] = indatalen; - memcpy (tmpl+6, indata, indatalen); - tmpllen = indatalen + 6; + err = concat_tlv_list (&apdudata, &apdudatalen, + (int)0x7c, (size_t)0, NULL, /* Constructed. */ + (int)0x82, (size_t)0, "", + (int)0x81, (size_t)indatalen, indata, + (int)0, (size_t)0, NULL); + if (err) + goto leave; /* Note: the -1 requests command chaining. */ err = iso7816_general_authenticate (app->slot, -1, - algo, keyref, - tmpl, (int)tmpllen, 0, + mechanism, keyref, + apdudata, (int)apdudatalen, 0, &outdata, &outdatalen); if (err) goto leave; @@ -1991,42 +2164,50 @@ do_auth (app_t app, const char *keyidstr, if (outdatalen && *outdata == 0x7c && (s = find_tlv (outdata, outdatalen, 0x82, &n))) { - const unsigned char *rval, *sval; - size_t rlen, rlenx, slen, slenx, resultlen; - char *result; - /* The result of an ECDSA signature is - * SEQUENCE { r INTEGER, s INTEGER } - * We re-pack that by concatenating R and S and making sure that - * both have the same length. We simplify parsing by using - * find_tlv and not a proper DER parser. */ - s = find_tlv (s, n, 0x30, &n); - if (!s) - goto bad_der; - rval = find_tlv (s, n, 0x02, &rlen); - if (!rval) - goto bad_der; - log_assert (n >= (rval-s)+rlen); - sval = find_tlv (rval+rlen, n-((rval-s)+rlen), 0x02, &slen); - if (!rval) - goto bad_der; - rlenx = slenx = 0; - if (rlen > slen) - slenx = rlen - slen; - else if (slen > rlen) - rlenx = slen - rlen; - - resultlen = rlen + rlenx + slen + slenx; - result = xtrycalloc (1, resultlen); - if (!result) + if (mechanism == PIV_ALGORITHM_RSA) { - err = gpg_error_from_syserror (); - goto leave; + memmove (outdata, outdata + (s - outdata), n); + outdatalen = n; + } + else /* ECC */ + { + const unsigned char *rval, *sval; + size_t rlen, rlenx, slen, slenx, resultlen; + char *result; + /* The result of an ECDSA signature is + * SEQUENCE { r INTEGER, s INTEGER } + * We re-pack that by concatenating R and S and making sure + * that both have the same length. We simplify parsing by + * using find_tlv and not a proper DER parser. */ + s = find_tlv (s, n, 0x30, &n); + if (!s) + goto bad_der; + rval = find_tlv (s, n, 0x02, &rlen); + if (!rval) + goto bad_der; + log_assert (n >= (rval-s)+rlen); + sval = find_tlv (rval+rlen, n-((rval-s)+rlen), 0x02, &slen); + if (!rval) + goto bad_der; + rlenx = slenx = 0; + if (rlen > slen) + slenx = rlen - slen; + else if (slen > rlen) + rlenx = slen - rlen; + + resultlen = rlen + rlenx + slen + slenx; + result = xtrycalloc (1, resultlen); + if (!result) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (result + rlenx, rval, rlen); + memcpy (result + rlenx + rlen + slenx, sval, slen); + xfree (outdata); + outdata = result; + outdatalen = resultlen; } - memcpy (result + rlenx, rval, rlen); - memcpy (result + rlenx + rlen + slenx, sval, slen); - xfree (outdata); - outdata = result; - outdatalen = resultlen; } else { @@ -2048,10 +2229,29 @@ do_auth (app_t app, const char *keyidstr, *r_outdata = outdata; *r_outdatalen = outdatalen; } + xfree (apdudata); + xfree (indata_buffer); return err; } +/* AUTH for PIV cards is actually the same as SIGN. The difference + * between AUTH and SIGN is that AUTH expects that pkcs#1.5 padding + * for RSA has already been done (digestInfo part w/o the padding) + * whereas SIGN may accept a plain digest and does the padding if + * needed. This is also the reason why SIGN takes a hashalgo. */ +static gpg_error_t +do_auth (app_t app, const char *keyidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const void *indata, size_t indatalen, + unsigned char **r_outdata, size_t *r_outdatalen) +{ + return do_sign (app, keyidstr, 0, pincb, pincb_arg, indata, indatalen, + r_outdata, r_outdatalen); +} + + /* Check whether a key for DOBJ already exists. We detect this by * reading the certificate described by DOBJ. If FORCE is TRUE a * diagnositic will be printed but no error returned if the key @@ -2464,7 +2664,7 @@ app_select_piv (app_t app) app->fnc.writecert = do_writecert; /* app->fnc.writekey = do_writekey; */ app->fnc.genkey = do_genkey; - /* app->fnc.sign = do_sign; */ + app->fnc.sign = do_sign; app->fnc.auth = do_auth; /* app->fnc.decipher = do_decipher; */ app->fnc.change_pin = do_change_chv; ----------------------------------------------------------------------- Summary of changes: scd/app-piv.c | 398 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 299 insertions(+), 99 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 10 19:33:39 2019 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat) Date: Sun, 10 Feb 2019 19:33:39 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.1.0-14-g21f0883 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 21f0883059c84de7145d402877cd178fcfed44e3 (commit) via a60e4f8142159b3e2df10d8d725b9680be5b4616 (commit) from d0eaec8ef60be9b4d1aa5993c11d261a35202a2e (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 21f0883059c84de7145d402877cd178fcfed44e3 Author: Damien Goutte-Gattat Date: Thu Feb 7 23:03:03 2019 +0000 fltk: Handle '_' in button labels as keyboard shortcuts. * fltk/main.cxx (convert_accel_utf8): New method. (fltk_cmd_handler): Calls previous method to escape button labels. GnuPG-bug-id: 4336 Signed-off-by: Damien Goutte-Gattat Co-authored-by: Michael B?uerle diff --git a/fltk/main.cxx b/fltk/main.cxx index 5d226ed..2afad1c 100644 --- a/fltk/main.cxx +++ b/fltk/main.cxx @@ -78,6 +78,44 @@ static std::string escape_accel_utf8(const char *s) return result; } +// For button labels +// Accelerator '_' (used e.g. by GPG2) is converted to '&' (for FLTK) +// '&' is escaped as in escape_accel_utf8() +static std::string convert_accel_utf8(const char *s) +{ + static bool last_was_underscore = false; + std::string result; + if (NULL != s) + { + result.reserve(strlen(s)); + for (const char *p = s; *p; ++p) + { + // & => && + if ('&' == *p) + result.push_back(*p); + // _ => & (handle '__' as escaped underscore) + if ('_' == *p) + { + if (last_was_underscore) + { + result.push_back(*p); + last_was_underscore = false; + } + else + last_was_underscore = true; + } + else + { + if (last_was_underscore) + result.push_back('&'); + result.push_back(*p); + last_was_underscore = false; + } + } + } + return result; +} + class cancel_exception { @@ -111,8 +149,8 @@ static int fltk_cmd_handler(pinentry_t pe) // TODO: Add parent window to pinentry-fltk window //if (pe->parent_wid){} std::string title = !is_empty(pe->title)?pe->title:PGMNAME; - std::string ok = escape_accel_utf8(pe->ok?pe->ok:(pe->default_ok?pe->default_ok:OK_STRING)); - std::string cancel = escape_accel_utf8(pe->cancel?pe->cancel:(pe->default_cancel?pe->default_cancel:CANCEL_STRING)); + std::string ok = convert_accel_utf8(pe->ok?pe->ok:(pe->default_ok?pe->default_ok:OK_STRING)); + std::string cancel = convert_accel_utf8(pe->cancel?pe->cancel:(pe->default_cancel?pe->default_cancel:CANCEL_STRING)); if (!!pe->pin) // password (or confirmation) { commit a60e4f8142159b3e2df10d8d725b9680be5b4616 Author: Daniel Kahn Gillmor Date: Thu Feb 7 23:11:19 2019 +0000 fltk: Fix formatting escapes. * fltk/main.cxx (fltk_cmd_handler): Fix calls to fl_message() and fl_choice() functions. -- The fl_message and fl_choice functions expect a format string as their first argument; passing the message directly might cause a crash (or worse) if the message happens to contain formatting escape chars. GnuPG-bug-id: 4337 Signed-off-by: Damien Goutte-Gattat diff --git a/fltk/main.cxx b/fltk/main.cxx index 8e7e726..5d226ed 100644 --- a/fltk/main.cxx +++ b/fltk/main.cxx @@ -241,12 +241,12 @@ static int fltk_cmd_handler(pinentry_t pe) if (pe->one_button) { fl_ok = ok.c_str(); - fl_message(message); + fl_message("%s", message); result = 1; // OK } else if (pe->notok) { - switch (fl_choice(message, ok.c_str(), cancel.c_str(), pe->notok)) + switch (fl_choice("%s", ok.c_str(), cancel.c_str(), pe->notok, message)) { case 0: result = 1; break; case 2: result = 0; break; @@ -256,7 +256,7 @@ static int fltk_cmd_handler(pinentry_t pe) } else { - switch (fl_choice(message, ok.c_str(), cancel.c_str(), NULL)) + switch (fl_choice("%s", ok.c_str(), cancel.c_str(), NULL, message)) { case 0: result = 1; break; default: ----------------------------------------------------------------------- Summary of changes: fltk/main.cxx | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 10 20:39:04 2019 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Sun, 10 Feb 2019 20:39:04 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.12.0-129-g302d5ef 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 302d5ef52e095378231efd54677b5c315354ad78 (commit) from e005052f4d5b29beda2252f8042dbf5728f5e2aa (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 302d5ef52e095378231efd54677b5c315354ad78 Author: Ben McGinnes Date: Mon Feb 11 06:34:40 2019 +1100 python: examples * A rather obvious variant of the existing key import examples, except directed at Mailvelope's keyserver. * Yeah, Werner, I know ... but it exists because I used it and there's no harm in sharing. Tested-by: Ben McGinnes Signed-off-by: Ben McGinnes diff --git a/lang/python/examples/howto/import-mailvelope-keys.py b/lang/python/examples/howto/import-mailvelope-keys.py new file mode 100755 index 0000000..42a561d --- /dev/null +++ b/lang/python/examples/howto/import-mailvelope-keys.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, unicode_literals + +import gpg +import hkp4py +import sys + +# Copyright (C) 2019 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 License for 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 +# . + +print(""" +This script imports one or more public keys from the Mailvelope keyserver. +""") + +c = gpg.Context() +server = hkp4py.KeyServer("hkps://keys.mailvelope.com") +results = [] +keys = [] + +if len(sys.argv) > 2: + pattern = " ".join(sys.argv[1:]) +elif len(sys.argv) == 2: + pattern = sys.argv[1] +else: + pattern = input("Enter the pattern to search for keys or user IDs: ") + + +if pattern is not None: + try: + key = server.search(hex(int(pattern, 16))) + keyed = True + except ValueError as ve: + key = server.search(pattern) + keyed = False + + if key is not None: + keys.append(key[0]) + if keyed is True: + try: + fob = server.search(pattern) + except Exception as e: + fob = None + if fob is not None: + keys.append(fob[0]) + else: + pass + else: + pass + + for logrus in pattern.split(): + if logrus != pattern: + try: + key = server.search(hex(int(logrus, 16))) + hexed = True + except ValueError as ve: + key = server.search(logrus) + hexed = False + + if key is not None: + keys.append(key[0]) + if hexed is True: + try: + fob = server.search(logrus) + except Exception as e: + fob = None + if fob is not None: + keys.append(fob[0]) + else: + pass + else: + pass + else: + pass + else: + pass + + +if len(keys) > 0: + for key in keys: + import_result = c.key_import(key.key_blob) + results.append(import_result) + +for result in results: + 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: + print("No keys were imported or found.") ----------------------------------------------------------------------- Summary of changes: .../howto/{import-keys-hkp.py => import-mailvelope-keys.py} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) copy lang/python/examples/howto/{import-keys-hkp.py => import-mailvelope-keys.py} (95%) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 10 21:20:11 2019 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat) Date: Sun, 10 Feb 2019 21:20:11 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-1.1.0-15-g8f8d907 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 8f8d907f53b2749642ee273e2cec28f7d68f26ff (commit) from 21f0883059c84de7145d402877cd178fcfed44e3 (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 8f8d907f53b2749642ee273e2cec28f7d68f26ff Author: Damien Goutte-Gattat Date: Tue Nov 20 12:48:43 2018 +0000 build: Add --disable-doc option. * configure.ac (BUILD_DOC): Add new am_conditional. * Makefile.am: Skip doc subdir if BUILD_DOC is not set. GnuPG-bug-id: 4263 Signed-off-by: Damien Goutte-Gattat . diff --git a/Makefile.am b/Makefile.am index b8fd0e1..5d3e3d5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,10 +88,16 @@ else pinentry_efl = endif +if BUILD_DOC +doc = doc +else +doc = +endif + SUBDIRS = m4 secmem pinentry ${pinentry_curses} ${pinentry_tty} \ ${pinentry_emacs} ${pinentry_gtk_2} ${pinentry_gnome_3} \ ${pinentry_qt} ${pinentry_tqt} ${pinentry_w32} \ - ${pinentry_fltk} ${pinentry_efl} doc + ${pinentry_fltk} ${pinentry_efl} ${doc} install-exec-local: diff --git a/configure.ac b/configure.ac index 51a2313..a4d54da 100644 --- a/configure.ac +++ b/configure.ac @@ -754,6 +754,12 @@ AH_BOTTOM([ #endif /*GNUPG_CONFIG_H_INCLUDED*/ ]) +build_doc=yes +AC_ARG_ENABLE([doc], AC_HELP_STRING([--disable-doc], + [do not build the documentation]), + build_doc=$enableval, build_doc=yes) +AM_CONDITIONAL([BUILD_DOC], [test "x$build_doc" != xno]) + AC_CONFIG_FILES([ m4/Makefile ----------------------------------------------------------------------- Summary of changes: Makefile.am | 8 +++++++- configure.ac | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 09:06:18 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Feb 2019 09:06:18 +0100 Subject: [git] GPG-ERROR - branch, master, updated. gpgrt-1.35-4-g0318ce6 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 "Error codes used by GnuPG et al.". The branch, master has been updated via 0318ce6fbc756c4d3a9201472c7dcbedd91bf885 (commit) from 21dd885eecdee13da1689519e2fc50fcf64f6ef2 (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 0318ce6fbc756c4d3a9201472c7dcbedd91bf885 Author: Werner Koch Date: Mon Feb 11 08:44:50 2019 +0100 New error codes NO_AUTH and BAD_AUTH -- In particular for PIV cards ithe use of BAD_PIN sounds worong, thus we now use dedicated codes. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index f86b2a1..f7c043e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,12 @@ Noteworthy changes in version 1.36 (unreleased) [C26/A26/R_] ----------------------------------------------- + * Interface changes relative to the 1.34 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPG_ERR_NO_AUTH NEW. + GPG_ERR_BAD_AUTH NEW. + + Noteworthy changes in version 1.35 (2019-01-28) [C26/A26/R1] ----------------------------------------------- diff --git a/doc/errorref.txt b/doc/errorref.txt index 21d79ad..e62fe15 100644 --- a/doc/errorref.txt +++ b/doc/errorref.txt @@ -1058,6 +1058,15 @@ GPG_ERR_WRONG_NAME Wrong name NTBTLS: - Hostname does not match the certificate +GPG_ERR_NO_AUTH Not authenticated + + GnuPG: - A smartcard requires authentication + +GPG_ERR_BAD_AUTH Bad authentication + + GnuPG: - A smartcard could not be authenticated. For example + a wrong authentication key was used with a PIV card. + GPG_ERR_SYSTEM_BUG System bug detected The underlying operating system misbehaved. For example it wrote diff --git a/src/err-codes.h.in b/src/err-codes.h.in index 2667d71..33e79da 100644 --- a/src/err-codes.h.in +++ b/src/err-codes.h.in @@ -333,6 +333,8 @@ 311 GPG_ERR_ALREADY_FETCHED Already fetched 312 GPG_ERR_TRY_LATER Try again later 313 GPG_ERR_WRONG_NAME Wrong name +314 GPG_ERR_NO_AUTH Not authenticated +315 GPG_ERR_BAD_AUTH Bad authentication # This range is free for use. 666 GPG_ERR_SYSTEM_BUG System bug detected ----------------------------------------------------------------------- Summary of changes: NEWS | 6 ++++++ doc/errorref.txt | 9 +++++++++ src/err-codes.h.in | 2 ++ 3 files changed, 17 insertions(+) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 09:08:26 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Feb 2019 09:08:26 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-369-gb283869 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 b2838694402ce0cfc2ef70451bf0e6677b875ca9 (commit) from 53beea56afecde76f0f4ca93fc50ca59298a093e (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 b2838694402ce0cfc2ef70451bf0e6677b875ca9 Author: Werner Koch Date: Mon Feb 11 09:07:54 2019 +0100 scd: For PIV cards used NO_AUTH instead of BAD_PIN. * common/util.h (GPG_ERR_NO_AUTH, GPG_ERR_BAD_AUTH): Add replacement codes for gpgrt < 1.36. * scd/app-piv.c (auth_adm_key): (do_genkey, do_writecert): Use better error codes. Signed-off-by: Werner Koch diff --git a/common/util.h b/common/util.h index d5bb225..8895137 100644 --- a/common/util.h +++ b/common/util.h @@ -39,7 +39,10 @@ * libgpg-error version. Define them here. * Example: (#if GPG_ERROR_VERSION_NUMBER < 0x011500 // 1.21) */ - +#if GPG_ERROR_VERSION_NUMBER < 0x012400 /* 1.36 */ +#define GPG_ERR_NO_AUTH 314 +#define GPG_ERR_BAD_AUTH 315 +#endif /*GPG_ERROR_VERSION_NUMBER*/ /* Hash function used with libksba. */ #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) diff --git a/scd/app-piv.c b/scd/app-piv.c index 1d70db5..36086f5 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -890,6 +890,8 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen) PIV_ALGORITHM_3DES_ECB_0, 0x9B, tmpl, tmpllen, 0, &outdata, &outdatalen); + if (gpg_err_code (err) == GPG_ERR_BAD_PIN) + err = gpg_error (GPG_ERR_BAD_AUTH); if (err) goto leave; if (!(outdatalen && *outdata == 0x7c @@ -921,6 +923,8 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen) PIV_ALGORITHM_3DES_ECB_0, 0x9B, tmpl, tmpllen, 0, &outdata, &outdatalen); + if (gpg_err_code (err) == GPG_ERR_BAD_PIN) + err = gpg_error (GPG_ERR_BAD_AUTH); if (err) goto leave; if (!(outdatalen && *outdata == 0x7c @@ -937,7 +941,7 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen) goto leave; if (memcmp (witness, tmpl+14, 8)) { - err = gpg_error (GPG_ERR_BAD_SIGNATURE); + err = gpg_error (GPG_ERR_BAD_AUTH); goto leave; } @@ -993,6 +997,9 @@ set_adm_key (app_t app, const unsigned char *value, size_t valuelen) wipememory (apdu+8, 24); if (err) log_error ("piv: setting admin key failed; sw=%04x\n", sw); + /* A PIN is not required, thus use a better error code. */ + if (gpg_err_code (err) == GPG_ERR_BAD_PIN) + err = gpg_error (GPG_ERR_NO_AUTH); } else err = gpg_error (GPG_ERR_NOT_SUPPORTED); @@ -2490,6 +2497,9 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype, tmpl, tmpllen, 0, &buffer, &buflen); if (err) { + /* A PIN is not required, thus use a better error code. */ + if (gpg_err_code (err) == GPG_ERR_BAD_PIN) + err = gpg_error (GPG_ERR_NO_AUTH); log_error (_("generating key failed\n")); return err; } @@ -2562,6 +2572,9 @@ do_writecert (app_t app, ctrl_t ctrl, (int)0x71, (size_t)1, "", /* No compress */ (int)0xfe, (size_t)0, "", /* Empty LRC. */ (int)0, (size_t)0, NULL); + /* A PIN is not required, thus use a better error code. */ + if (gpg_err_code (err) == GPG_ERR_BAD_PIN) + err = gpg_error (GPG_ERR_NO_AUTH); if (err) log_error ("piv: failed to write cert to %s: %s\n", dobj->keyref, gpg_strerror (err)); ----------------------------------------------------------------------- Summary of changes: common/util.h | 5 ++++- scd/app-piv.c | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 11:04:05 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Feb 2019 11:04:05 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.12-28-gd1bee9d 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 d1bee9d1efa28fa9d35b7eed1e616c6362fd044e (commit) via d29d73264f607642281fb701a17015306c8fc4d7 (commit) via ee8d1a9e6c09b3ecc4b46f47b79358f78d458916 (commit) via 14816c798099925e47908e7ce415412d72fbe28e (commit) via c075274aac0ffd388df638548b75a7d90e7e929d (commit) via 6651a0640d0f1b4dd161210dc55974d9b93b7253 (commit) via 14ea581a1c040b53b0ad4c51136a7948363b1e4b (commit) from c16685b2f5021105ef0560cb3db68ef43bcdb9c1 (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 d1bee9d1efa28fa9d35b7eed1e616c6362fd044e Author: Werner Koch Date: Fri Feb 8 12:35:26 2019 +0100 sm: In --gen-key with "key from card" show also the algorithm. * sm/certreqgen-ui.c (gpgsm_gencertreq_tty): Get and show algo. -- This extends the prompt to show something like Serial number of the card: FF020001008A77F6 Available keys: (1) 4130F84FA3704F4645924AEC3FFA48AD26D33656 PIV.9A nistp384 (2) AB2988FB8C227BCD5175BF92F66AA3A95AE83214 PIV.9E rsa2048 (3) DB7DDAEAA88534BA45CCD7A9B761425103EA2090 PIV.9C rsa2048 (4) BABB48C3D80ACCF9839F101DF2910966C8B988DF PIV.9D nistp256 Your selection? 1 Having the algorithm here is helpful in particular because right now we support only RSA with X.509. Take care: PIV card based certificate creation does not yet work. Signed-off-by: Werner Koch (cherry picked from commit 0328976c94adc2c518c7a7763a35319a0000c5e2) Note that 2.2 does not support PIV cards, but the feature also works also with other cards. diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index 9772a3b..b131d7d 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -244,7 +244,27 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) { tty_printf (_("Available keys:\n")); for (count=1,sl=keypairlist; sl; sl = sl->next, count++) - tty_printf (" (%d) %s\n", count, sl->d); + { + ksba_sexp_t pkey; + gcry_sexp_t s_pkey; + char *algostr = NULL; + const char *keyref; + + keyref = strchr (sl->d, ' '); + if (keyref) + { + keyref++; + if (!gpgsm_agent_readkey (ctrl, 1, keyref, &pkey)) + { + if (!gcry_sexp_new (&s_pkey, pkey, 0, 0)) + algostr = pubkey_algo_string (s_pkey); + gcry_sexp_release (s_pkey); + } + xfree (pkey); + } + tty_printf (" (%d) %s %s\n", count, sl->d, algostr); + xfree (algostr); + } xfree (answer); answer = tty_get (_("Your selection? ")); tty_kill_prompt (); commit d29d73264f607642281fb701a17015306c8fc4d7 Author: Werner Koch Date: Fri Feb 8 12:10:45 2019 +0100 common: Provide function to get public key algo names in our format. * common/sexputil.c (pubkey_algo_string): New. -- The new gpg format for public key algorithms is useful at other places as well. Thus we make this new function available. Note that the code we use in gpg is not based on s-expressions and thus a new function was required. Signed-off-by: Werner Koch (cherry picked from commit 03bf8e967adb2dd13329ba1089deb419d49e55c0) Not yet used in 2.2 but will likely be needed by future backports. diff --git a/common/sexputil.c b/common/sexputil.c index f30790a..5e51f68 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -577,3 +577,61 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen) gcry_sexp_release (sexp); return algo; } + + +/* Given the public key S_PKEY, return a new buffer with a descriptive + * string for its algorithm. This function may return NULL on memory + * error. */ +char * +pubkey_algo_string (gcry_sexp_t s_pkey) +{ + const char *prefix; + gcry_sexp_t l1; + char *algoname; + int algo; + char *result; + + l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); + if (!l1) + return xtrystrdup ("E_no_key"); + { + gcry_sexp_t l_tmp = gcry_sexp_cadr (l1); + gcry_sexp_release (l1); + l1 = l_tmp; + } + algoname = gcry_sexp_nth_string (l1, 0); + gcry_sexp_release (l1); + if (!algoname) + return xtrystrdup ("E_no_algo"); + + algo = gcry_pk_map_name (algoname); + switch (algo) + { + case GCRY_PK_RSA: prefix = "rsa"; break; + case GCRY_PK_ELG: prefix = "elg"; break; + case GCRY_PK_DSA: prefix = "dsa"; break; + case GCRY_PK_ECC: prefix = ""; break; + default: prefix = NULL; break; + } + + if (prefix && *prefix) + result = xtryasprintf ("%s%u", prefix, gcry_pk_get_nbits (s_pkey)); + else if (prefix) + { + const char *curve = gcry_pk_get_curve (s_pkey, 0, NULL); + const char *name = openpgp_oid_to_curve + (openpgp_curve_to_oid (curve, NULL), 0); + + if (name) + result = xtrystrdup (name); + else if (curve) + result = xtryasprintf ("X_%s", curve); + else + result = xtrystrdup ("E_unknown"); + } + else + result = xtryasprintf ("X_algo_%d", algo); + + xfree (algoname); + return result; +} diff --git a/common/util.h b/common/util.h index 36f1b93..27f565b 100644 --- a/common/util.h +++ b/common/util.h @@ -199,6 +199,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, int get_pk_algo_from_key (gcry_sexp_t key); int get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen); +char *pubkey_algo_string (gcry_sexp_t s_pkey); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); commit ee8d1a9e6c09b3ecc4b46f47b79358f78d458916 Author: Werner Koch Date: Fri Feb 8 09:32:55 2019 +0100 common: New functions get_option_value and ascii_strupr. * common/server-help.c (get_option_value): New. * common/stringhelp.c (ascii_strupr): New. -- Signed-off-by: Werner Koch (cherry picked from commit e2f18023b3b3b7e55b35218f65e37448d1011172) This might come handy when we eventually backport other changes. diff --git a/common/server-help.c b/common/server-help.c index 53a888a..e5a69e0 100644 --- a/common/server-help.c +++ b/common/server-help.c @@ -30,8 +30,22 @@ #include #include -#include "server-help.h" #include "util.h" +#include "server-help.h" + + +static GPGRT_INLINE gpg_error_t +my_error (int e) +{ + return gpg_err_make (default_errsource, (e)); +} + +static GPGRT_INLINE gpg_error_t +my_error_from_syserror (void) +{ + return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); +} + /* Skip over options in LINE. @@ -114,6 +128,40 @@ has_option_name (const char *line, const char *name) } +/* Parse an option with the format "--NAME=VALUE" which must occur in + * LINE before a double-dash. LINE is written to but not modified by + * this function. If the option is found and has a value the value is + * stored as a malloced string at R_VALUE. If the option was not + * found or an error occurred NULL is stored there. Note that + * currently the value must be a string without any space; we may + * eventually update this function to allow for a quoted value. */ +gpg_error_t +get_option_value (char *line, const char *name, char **r_value) +{ + char *p, *pend; + int c; + + *r_value = NULL; + + p = (char*)has_option_name (line, name); + if (!p || p >= skip_options (line)) + return 0; + + if (*p != '=' || !p[1] || spacep (p+1)) + return my_error (GPG_ERR_INV_ARG); + p++; + for (pend = p; *pend && !spacep (pend); pend++) + ; + c = *pend; + *pend = 0; + *r_value = xtrystrdup (p); + *pend = c; + if (!p) + return my_error_from_syserror (); + return 0; +} + + /* Return a pointer to the argument of the option with NAME. If such an option is not given, NULL is returned. */ char * diff --git a/common/server-help.h b/common/server-help.h index 9e3d7ad..9d2f4cf 100644 --- a/common/server-help.h +++ b/common/server-help.h @@ -55,6 +55,14 @@ int has_leading_option (const char *line, const char *name); or a space. */ const char *has_option_name (const char *line, const char *name); +/* Same as has_option_name but ignores all options after a "--" and + * does not return a const char ptr. */ +char *has_leading_option_name (char *line, const char *name); + +/* Parse an option with the format "--NAME=VALUE" and return the value + * as a malloced string. */ +gpg_error_t get_option_value (char *line, const char *name, char **r_value); + /* Return a pointer to the argument of the option with NAME. If such an option is not given, NULL is returned. */ char *option_value (const char *line, const char *name); diff --git a/common/stringhelp.c b/common/stringhelp.c index 0abac8a..68fe997 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -810,6 +810,19 @@ ascii_strlwr (char *s) return s; } +/* Upcase all ASCII characters in S. */ +char * +ascii_strupr (char *s) +{ + char *p = s; + + for (p=s; *p; p++ ) + if (isascii (*p) && *p >= 'a' && *p <= 'z') + *p &= ~0x20; + + return s; +} + int ascii_strcasecmp( const char *a, const char *b ) { diff --git a/common/stringhelp.h b/common/stringhelp.h index 5b07af9..7df6c76 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -76,6 +76,7 @@ int ascii_islower (int c); int ascii_toupper (int c); int ascii_tolower (int c); char *ascii_strlwr (char *s); +char *ascii_strupr (char *s); int ascii_strcasecmp( const char *a, const char *b ); int ascii_strncasecmp (const char *a, const char *b, size_t n); int ascii_memcasecmp( const void *a, const void *b, size_t n ); commit 14816c798099925e47908e7ce415412d72fbe28e Author: Werner Koch Date: Wed Feb 6 14:07:42 2019 +0100 scd: Make app_genkey and supporting ISO function more flexible. * scd/app.c (app_genkey): Add arg keytype. * scd/app-common.h (struct app_ctx_s): Fitto for the genkey member. * scd/command.c (cmd_genkey): Adjust for change. * scd/iso7816.c (do_generate_keypair): Replace arg read_only by new args p1 and p2. (iso7816_read_public_key): Adjust for this. (iso7816_generate_keypair): Add new args p1 and p2. * scd/app-openpgp.c (do_genkey): Adjust for changes. -- The OpenPGP card creates keys according to parameters read from a data object. Other cards we are about to implement require a direct specification of the requested keytype. This patch implements the required changes. Signed-off-by: Werner Koch (cherry picked from commit 9a9cb0257aebb1480b999fdf9d90904083eb8e3c) diff --git a/scd/app-common.h b/scd/app-common.h index 4e3f432..2619823 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -105,8 +105,8 @@ struct app_ctx_s { void *pincb_arg, const unsigned char *pk, size_t pklen); gpg_error_t (*genkey) (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - time_t createtime, + const char *keyref, const char *keytype, + unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t (*change_pin) (app_t app, ctrl_t ctrl, @@ -177,8 +177,8 @@ gpg_error_t app_writekey (app_t app, ctrl_t ctrl, void *pincb_arg, const unsigned char *keydata, size_t keydatalen); gpg_error_t app_genkey (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - time_t createtime, + const char *keynostr, const char *keytype, + unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index db206f5..4792653 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -4035,8 +4035,8 @@ do_writekey (app_t app, ctrl_t ctrl, /* Handle the GENKEY command. */ static gpg_error_t -do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, - time_t createtime, +do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, const char *keytype, + unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -4052,6 +4052,8 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, int exmode = 0; int le_value = 256; /* Use legacy value. */ + (void)keytype; /* Ignored for OpenPGP cards. */ + if (keyno < 0 || keyno > 2) return gpg_error (GPG_ERR_INV_ID); @@ -4100,7 +4102,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, log_info (_("please wait while key is being generated ...\n")); start_at = time (NULL); - err = iso7816_generate_keypair (app->slot, exmode, + err = iso7816_generate_keypair (app->slot, exmode, 0x80, 0, (keyno == 0? "\xB6" : keyno == 1? "\xB8" : "\xA4"), 2, le_value, &buffer, &buflen); diff --git a/scd/app.c b/scd/app.c index 6391c3b..ac9a658 100644 --- a/scd/app.c +++ b/scd/app.c @@ -865,8 +865,8 @@ app_writekey (app_t app, ctrl_t ctrl, /* Perform a SETATTR operation. */ gpg_error_t -app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, - time_t createtime, +app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, + const char *keytype, unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -881,7 +881,7 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, err = lock_app (app, ctrl); if (err) return err; - err = app->fnc.genkey (app, ctrl, keynostr, flags, + err = app->fnc.genkey (app, ctrl, keynostr, keytype, flags, createtime, pincb, pincb_arg); unlock_app (app); if (opt.verbose) diff --git a/scd/command.c b/scd/command.c index ec6793a..1dfa652 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1138,7 +1138,8 @@ cmd_genkey (assuan_context_t ctx, char *line) keyno = xtrystrdup (keyno); if (!keyno) return out_of_core (); - rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, + rc = app_genkey (ctrl->app_ctx, ctrl, keyno, NULL, + force? APP_GENKEY_FLAG_FORCE : 0, timestamp, pin_cb, ctx); xfree (keyno); diff --git a/scd/iso7816.c b/scd/iso7816.c index b7819bf..e8b517e 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -629,7 +629,7 @@ iso7816_general_authenticate (int slot, int extended_mode, returned. In that case a value of -1 uses a large default (e.g. 4096 bytes), a value larger 256 used that value. */ static gpg_error_t -do_generate_keypair (int slot, int extended_mode, int read_only, +do_generate_keypair (int slot, int extended_mode, int p1, int p2, const char *data, size_t datalen, int le, unsigned char **result, size_t *resultlen) { @@ -641,7 +641,7 @@ do_generate_keypair (int slot, int extended_mode, int read_only, *resultlen = 0; sw = apdu_send_le (slot, extended_mode, - 0x00, CMD_GENERATE_KEYPAIR, read_only? 0x81:0x80, 0, + 0x00, CMD_GENERATE_KEYPAIR, p1, p2, datalen, data, le >= 0 && le < 256? 256:le, result, resultlen); @@ -659,12 +659,12 @@ do_generate_keypair (int slot, int extended_mode, int read_only, gpg_error_t -iso7816_generate_keypair (int slot, int extended_mode, +iso7816_generate_keypair (int slot, int extended_mode, int p1, int p2, const char *data, size_t datalen, int le, unsigned char **result, size_t *resultlen) { - return do_generate_keypair (slot, extended_mode, 0, + return do_generate_keypair (slot, extended_mode, p1, p2, data, datalen, le, result, resultlen); } @@ -675,7 +675,7 @@ iso7816_read_public_key (int slot, int extended_mode, int le, unsigned char **result, size_t *resultlen) { - return do_generate_keypair (slot, extended_mode, 1, + return do_generate_keypair (slot, extended_mode, 0x81, 0, data, datalen, le, result, resultlen); } diff --git a/scd/iso7816.h b/scd/iso7816.h index 44781ff..8da5a94 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -105,9 +105,11 @@ gpg_error_t iso7816_general_authenticate (int slot, int extended_mode, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_generate_keypair (int slot, int extended_mode, - const char *data, size_t datalen, - int le, - unsigned char **result, size_t *resultlen); + int p1, int p2, + const char *data, size_t datalen, + int le, + unsigned char **result, + size_t *resultlen); gpg_error_t iso7816_read_public_key (int slot, int extended_mode, const char *data, size_t datalen, int le, commit c075274aac0ffd388df638548b75a7d90e7e929d Author: Werner Koch Date: Wed Feb 6 12:24:30 2019 +0100 scd: Fix parameter name of app_change_key. * scd/app-common.h (APP_GENKEY_FLAG_FORCE): New. * scd/app.c (app_change_pin): Rename arg reset_mode to flags and change from int to unsigned int. -- This is basically a documentation fix. Signed-off-by: Werner Koch (cherry picked from commit c26af8ac263ea006ed32e110a09271e4bfbf1f37) diff --git a/scd/app-common.h b/scd/app-common.h index 37e3c60..4e3f432 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -25,11 +25,14 @@ #include #include - +/* Flags used with app_change_pin. */ #define APP_CHANGE_FLAG_RESET 1 /* PIN Reset mode. */ #define APP_CHANGE_FLAG_NULLPIN 2 /* NULL PIN mode. */ #define APP_CHANGE_FLAG_CLEAR 4 /* Clear the given PIN. */ +/* Flags used with app_genkey. */ +#define APP_GENKEY_FLAG_FORCE 1 /* Force overwriting existing key. */ + /* Bit flags set by the decipher function into R_INFO. */ #define APP_DECIPHER_INFO_NOPAD 1 /* Padding has been removed. */ @@ -181,9 +184,9 @@ gpg_error_t app_genkey (app_t app, ctrl_t ctrl, gpg_error_t app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer); gpg_error_t app_change_pin (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, - gpg_error_t (*pincb)(void*, const char *, char **), - void *pincb_arg); + const char *chvnostr, unsigned int flags, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg); gpg_error_t app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); diff --git a/scd/app.c b/scd/app.c index c430579..6391c3b 100644 --- a/scd/app.c +++ b/scd/app.c @@ -914,7 +914,8 @@ app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer) /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */ gpg_error_t -app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, +app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, + unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { @@ -929,8 +930,7 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, err = lock_app (app, ctrl); if (err) return err; - err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, - pincb, pincb_arg); + err = app->fnc.change_pin (app, ctrl, chvnostr, flags, pincb, pincb_arg); unlock_app (app); if (opt.verbose) log_info ("operation change_pin result: %s\n", gpg_strerror (err)); commit 6651a0640d0f1b4dd161210dc55974d9b93b7253 Author: Werner Koch Date: Tue Feb 5 14:48:49 2019 +0100 scd: Allow standard keyref scheme for app-openpgp. * scd/app-openpgp.c (do_change_pin): Allow prefixing the CHVNO with "OPENPGP." -- The generic keyref allows for better error detection in case a keyref is send to a wrong card. This has been taken from master commit 3231ecdafd71ac47b734469b07170756979ede72 which has additional changed for gpg-card-tool, which is only available there. Signed-off-by: Werner Koch diff --git a/doc/wks.texi b/doc/wks.texi index d6798b1..7a19e75 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -124,7 +124,7 @@ Requires installation of that command. @item --with-colons @opindex with-colons This option has currently only an effect on the @option{--supported} -command. If it is used all arguimenst on the command line are taken +command. If it is used all arguments on the command line are taken as domain names and tested for WKD support. The output format is one line per domain with colon delimited fields. The currently specified fields are (future versions may specify additional fields): diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 760332e..db206f5 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2563,6 +2563,8 @@ do_writecert (app_t app, ctrl_t ctrl, - 2 1 Verify CHV2 and set a new CHV1 and CHV2. - 2 2 Verify Reset Code and set a new PW1. - 3 any Verify CHV3/PW3 and set a new CHV3/PW3. + + The CHVNO can be prefixed with "OPENPGP.". */ static gpg_error_t do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, @@ -2571,7 +2573,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, void *pincb_arg) { int rc = 0; - int chvno = atoi (chvnostr); + int chvno; char *resetcode = NULL; char *oldpinvalue = NULL; char *pinvalue = NULL; @@ -2585,6 +2587,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, (void)ctrl; + if (digitp (chvnostr)) + chvno = atoi (chvnostr); + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.1")) + chvno = 1; + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.2")) + chvno = 2; + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.3")) + chvno = 3; + else + return gpg_error (GPG_ERR_INV_ID); + memset (&pininfo, 0, sizeof pininfo); pininfo.fixedlen = -1; pininfo.minlen = minlen; diff --git a/scd/iso7816.c b/scd/iso7816.c index 9e55073..b7819bf 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -330,6 +330,7 @@ iso7816_change_reference_data (int slot, int chvno, sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA, oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); + wipememory (buf, oldchvlen+newchvlen); xfree (buf); return map_sw (sw); commit 14ea581a1c040b53b0ad4c51136a7948363b1e4b Author: Werner Koch Date: Wed Jan 30 14:40:26 2019 +0100 gpg: Emit an ERROR status if no key was found with --list-keys. * g10/keylist.c (list_one): Emit status line. -- Signed-off-by: Werner Koch (cherry picked from commit 140fda8c61422ec055c3f7e214cc35706c4320dd) diff --git a/g10/keylist.c b/g10/keylist.c index 66b03bb..262ea8d 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -610,6 +610,7 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret) { log_error ("error reading key: %s\n", gpg_strerror (rc)); getkey_end (ctrl, ctx); + write_status_error ("keylist.getkey", rc); return; } ----------------------------------------------------------------------- Summary of changes: common/server-help.c | 50 +++++++++++++++++++++++++++++++++++++++++++- common/server-help.h | 8 ++++++++ common/sexputil.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ common/stringhelp.c | 13 ++++++++++++ common/stringhelp.h | 1 + common/util.h | 1 + doc/wks.texi | 2 +- g10/keylist.c | 1 + scd/app-common.h | 19 +++++++++-------- scd/app-openpgp.c | 23 +++++++++++++++++---- scd/app.c | 12 +++++------ scd/command.c | 3 ++- scd/iso7816.c | 11 +++++----- scd/iso7816.h | 8 +++++--- sm/certreqgen-ui.c | 22 +++++++++++++++++++- 15 files changed, 202 insertions(+), 30 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 11:39:23 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Feb 2019 11:39:23 +0100 Subject: [git] Assuan - branch, master, updated. libassuan-2.5.2-6-g259a23e 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 "IPC library used by GnuPG". The branch, master has been updated via 259a23e0089aa72d31a3102c1470927e16ef630d (commit) via 4de3154ea6e6e89e34760b7b9e0eed5123bb81f9 (commit) from 75770b1131e11075c82031bdb220591154df9e64 (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 259a23e0089aa72d31a3102c1470927e16ef630d Author: Werner Koch Date: Mon Feb 11 11:39:18 2019 +0100 Post release updates -- diff --git a/NEWS b/NEWS index de18f15..aa9b38e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.5.4 (unreleased) [C8/A8/R_] +------------------------------------------------ + + Noteworthy changes in version 2.5.3 (2019-02-11) [C8/A8/R3] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index f369e6b..82648ee 100644 --- a/configure.ac +++ b/configure.ac @@ -33,7 +33,7 @@ min_automake_version="1.14" m4_define([mym4_package],[libassuan]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [5]) -m4_define([mym4_micro], [3]) +m4_define([mym4_micro], [4]) # 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 4de3154ea6e6e89e34760b7b9e0eed5123bb81f9 Author: Werner Koch Date: Mon Feb 11 11:31:24 2019 +0100 Release 2.5.3 diff --git a/AUTHORS b/AUTHORS index 1bb7071..691417e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -55,7 +55,7 @@ List of Copyright holders Copyright (C) 1992-2013 Free Software Foundation, Inc. Copyright (C) 1994 X Consortium Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001-2018 g10 Code GmbH + Copyright (C) 2001-2019 g10 Code GmbH Copyright (C) 2004 Simon Josefsson diff --git a/NEWS b/NEWS index a52fe0e..de18f15 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,15 @@ -Noteworthy changes in version 2.5.3 (unreleased) [C8/A8/R_] +Noteworthy changes in version 2.5.3 (2019-02-11) [C8/A8/R3] ------------------------------------------------ + * Add a timeout for writing to a SOCKS5 proxy. This helps if another + service is running on the standard tor socket (e.g. Windows 10). + [#3381] + + * Add workaround for a problem with LD_LIBRARY_PATH on newer systems. + [#4298] + + Release-info: https://dev.gnupg.org/T4361 + Noteworthy changes in version 2.5.2 (2018-12-13) [C8/A8/R2] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 53a4ac6..f369e6b 100644 --- a/configure.ac +++ b/configure.ac @@ -63,7 +63,7 @@ AC_INIT([mym4_package],[mym4_version], [https://bugs.gnupg.org]) # LIBASSUAN_LT_CURRENT=8 LIBASSUAN_LT_AGE=8 -LIBASSUAN_LT_REVISION=2 +LIBASSUAN_LT_REVISION=3 # If the API is changed in an incompatible way: increment the next counter. LIBASSUAN_CONFIG_API_VERSION=2 diff --git a/src/assuan.h.in b/src/assuan.h.in index 4e04a9b..65d3b48 100644 --- a/src/assuan.h.in +++ b/src/assuan.h.in @@ -1,6 +1,6 @@ /* assuan.h - Definitions for the Assuan IPC library -*- c -*- * Copyright (C) 2001-2013 Free Software Foundation, Inc. - * Copyright (C) 2001-2017 g10 Code GmbH + * Copyright (C) 2001-2019 g10 Code GmbH * * This file is part of Assuan. * @@ -16,7 +16,7 @@ * * 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+ + * SPDX-License-Identifier: LGPL-2.1-or-later * * @configure_input@ */ diff --git a/src/sysutils.c b/src/sysutils.c index 9090128..b3679d7 100644 --- a/src/sysutils.c +++ b/src/sysutils.c @@ -47,7 +47,7 @@ _assuan_sysutils_blurb (void) "\n\n" "This is Libassuan " PACKAGE_VERSION " - The GnuPG IPC Library\n" "Copyright 2001-2013 Free Software Foundation, Inc.\n" - "Copyright 2001-2018 g10 Code GmbH\n" + "Copyright 2001-2019 g10 Code GmbH\n" "\n" "SPDX-License-Identifier: LGPL-2.1-or-later\n" "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n" diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index 5af9a86..8df9073 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -40,7 +40,7 @@ BEGIN VALUE "FileDescription", "Assuan - GnuPG IPC\0" VALUE "FileVersion", "@LIBASSUAN_LT_CURRENT at .@LIBASSUAN_LT_AGE at .@LIBASSUAN_LT_REVISION at .@BUILD_REVISION@\0" VALUE "InternalName", "libassuan\0" - VALUE "LegalCopyright", "Copyright ? 2001-2018 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright ? 2001-2019 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libassuan.dll\0" VALUE "PrivateBuild", "\0" ----------------------------------------------------------------------- Summary of changes: AUTHORS | 2 +- NEWS | 15 ++++++++++++++- configure.ac | 4 ++-- src/assuan.h.in | 4 ++-- src/sysutils.c | 2 +- src/versioninfo.rc.in | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 11:41:21 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Feb 2019 11:41:21 +0100 Subject: [git] gnupg-doc - branch, master, updated. 573d41ff1f42af20426267346a9a548e3466e361 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 573d41ff1f42af20426267346a9a548e3466e361 (commit) from 2c267afb8c8199fd570fa74174a86b987725fdba (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 573d41ff1f42af20426267346a9a548e3466e361 Author: Werner Koch Date: Mon Feb 11 11:40:59 2019 +0100 swdb: Release libassuan 2.5.3 diff --git a/web/swdb.mac b/web/swdb.mac index 61e0cb2..d89eb7c 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -141,11 +141,11 @@ # # LIBASSUAN # -#+macro: libassuan_ver 2.5.2 -#+macro: libassuan_date 2018-12-13 -#+macro: libassuan_size 557k -#+macro: libassuan_sha1 fb66bc1e8971d48ac9dbacd1cdaf6487a3e77375 -#+macro: libassuan_sha2 986b1bf277e375f7a960450fbb8ffbd45294d06598916ad4ebf79aee0cb788e7 +#+macro: libassuan_ver 2.5.3 +#+macro: libassuan_date 2019-02-11 +#+macro: libassuan_size 558k +#+macro: libassuan_sha1 6d81bf42fa91ed2894df8b65764ce899e39776f8 +#+macro: libassuan_sha2 91bcb0403866b4e7c4bc1cc52ed4c364a9b5414b3994f718c70303f7f765e702 # ----------------------------------------------------------------------- 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 Mon Feb 11 14:27:47 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 11 Feb 2019 14:27:47 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.3.2-15-g4891416 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 489141670fe292216d230b80bb943c267b5d262b (commit) via 536f9cedc07b997d1af2da795bbd2b9affe1ed6e (commit) from cf221afd9d59b803338206544927116c6ca01259 (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 489141670fe292216d230b80bb943c267b5d262b Author: Andre Heinecke Date: Mon Feb 11 14:26:48 2019 +0100 Use better names for our own attachments * src/mapihelp.h (MIMEATTACHFILENAME, PGPBODYFILENAME): Use better file names. -- This helps users to understand / analyze issues when they introspect or see the hidden attachments due to some bug. diff --git a/src/mapihelp.h b/src/mapihelp.h index 4fc34d2..b167b3d 100644 --- a/src/mapihelp.h +++ b/src/mapihelp.h @@ -30,13 +30,13 @@ extern "C" { #endif /* The filename of the attachment we create as the result of sign or - encrypt operations. Don't change this name as some tests rely on - it. */ -#define MIMEATTACHFILENAME "gpgolXXX.dat" + encrypt operations. */ +#define MIMEATTACHFILENAME "GpgOL_MIME_structure.txt" + /* The name of the file we use to store the original body of PGP encrypted messages. Note that PGP/MIME message don't need that because Outlook carries them as 2 attachments. */ -#define PGPBODYFILENAME "gpgolPGP.dat" +#define PGPBODYFILENAME "GpgOL_original_OpenPGP_message.txt" void log_mapi_property (LPMESSAGE message, ULONG prop, const char *propname); int get_gpgololdmsgclass_tag (LPMESSAGE message, ULONG *r_tag); commit 536f9cedc07b997d1af2da795bbd2b9affe1ed6e Author: Andre Heinecke Date: Mon Feb 11 14:26:22 2019 +0100 Add strings for new config options * src/addin-options.cpp: Add new strings. diff --git a/src/addin-options.cpp b/src/addin-options.cpp index 137d880..393bdaf 100644 --- a/src/addin-options.cpp +++ b/src/addin-options.cpp @@ -78,6 +78,16 @@ i18n_noops[] = { N_("Searches for X509 certificates automatically and imports them. This option searches in all configured services."), /* TRANSLATORS: Part of the config dialog. Warning about privacy leak. */ N_("Warning: The configured services will receive information about whom you send Emails!"), + /* TRANSLATORS: Part of the config dialog. */ + N_("Also automatically toggles secure if keys with level 0 trust were found."), + /* TRANSLATORS: Part of the config dialog. */ + N_("Also &with untrusted keys"), + /* TRANSLATORS: Included means here both attached keys and keys from the + * headers */ + N_("&Import any keys included in mails."); + /* TRANSLATORS: Included means here both attached keys and keys from the + * headers */ + N_("Import OpenPGP keys from mail attachments or from mail headers."); /* Not options but strings for the key adder */ /* TRANSLATORS: Part of address book key configuration dialog. ----------------------------------------------------------------------- Summary of changes: src/addin-options.cpp | 10 ++++++++++ src/mapihelp.h | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 15:33:23 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 11 Feb 2019 15:33:23 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-370-g43b14b4 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 43b14b4cc227311aa77b1fc1d9577c5f7d3eda86 (commit) from b2838694402ce0cfc2ef70451bf0e6677b875ca9 (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 43b14b4cc227311aa77b1fc1d9577c5f7d3eda86 Author: Werner Koch Date: Mon Feb 11 15:32:54 2019 +0100 scd: Implement decryption for PIV cards. * scd/app-piv.c (do_decipher): New. -- Note that ECDH decryption has not been tested due to the lack of ECC support in gpgsm. Signed-off-by: Werner Koch diff --git a/scd/app-piv.c b/scd/app-piv.c index 36086f5..9e355b4 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -2259,6 +2259,151 @@ do_auth (app_t app, const char *keyidstr, } +/* Decrypt the data in (INDATA,INDATALEN) and on success store the + * mallocated result at (R_OUTDATA,R_OUTDATALEN). */ +static gpg_error_t +do_decipher (app_t app, const char *keyidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const void *indata_arg, size_t indatalen, + unsigned char **r_outdata, size_t *r_outdatalen, + unsigned int *r_info) +{ + const unsigned char *indata = indata_arg; + gpg_error_t err; + data_object_t dobj; + unsigned char *outdata = NULL; + size_t outdatalen; + const unsigned char *s; + size_t n; + int keyref, mechanism; + unsigned int framelen; + unsigned char *indata_buffer = NULL; /* Malloced helper. */ + unsigned char *apdudata = NULL; + size_t apdudatalen; + + if (!keyidstr || !*keyidstr) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + + dobj = find_dobj_by_keyref (app, keyidstr); + if ((keyref = keyref_from_dobj (dobj)) == -1) + { + err = gpg_error (GPG_ERR_INV_ID); + goto leave; + } + if (keyref == 0x9A || keyref == 0x9C || keyref == 0x9E) + { + /* Signing only reference. We only allow '9D' and the retired + * cert key management DOs. */ + err = gpg_error (GPG_ERR_INV_ID); + goto leave; + } + + err = get_key_algorithm_by_dobj (app, dobj, &mechanism); + if (err) + goto leave; + + switch (mechanism) + { + case PIV_ALGORITHM_ECC_P256: + framelen = 1+32+32; + break; + case PIV_ALGORITHM_ECC_P384: + framelen = 1+48+48; + break; + case PIV_ALGORITHM_RSA: + framelen = 2048 / 8; + break; + default: + err = gpg_error (GPG_ERR_INTERNAL); + log_debug ("piv: unknown PIV mechanism %d while decrypting\n", mechanism); + goto leave; + } + + /* Check that the ciphertext has the right length; due to internal + * convey mechanism using MPIs leading zero bytes might have been + * lost. Adjust for this. Note that for ECC this actually + * superfluous because the first octet is always '04' to indicate an + * uncompressed point. */ + if (indatalen > framelen) + { + err = gpg_error (GPG_ERR_INV_VALUE); + log_error ("piv: input of %zu octets too large for mechanism %d\n", + indatalen, mechanism); + goto leave; + } + if (indatalen < framelen) + { + indata_buffer = xtrycalloc (1, framelen); + if (!indata_buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (indata_buffer+(framelen-indatalen), indata, indatalen); + indata = indata_buffer; + indatalen = framelen; + } + + /* Now verify the Application PIN. */ + err = verify_chv (app, 0x80, pincb, pincb_arg); + if (err) + return err; + + /* Build the Dynamic Authentication Template. */ + err = concat_tlv_list (&apdudata, &apdudatalen, + (int)0x7c, (size_t)0, NULL, /* Constructed. */ + (int)0x82, (size_t)0, "", + mechanism == PIV_ALGORITHM_RSA? + (int)0x81 : (int)0x85, (size_t)indatalen, indata, + (int)0, (size_t)0, NULL); + if (err) + goto leave; + + /* Note: the -1 requests command chaining. */ + err = iso7816_general_authenticate (app->slot, -1, + mechanism, keyref, + apdudata, (int)apdudatalen, 0, + &outdata, &outdatalen); + if (err) + goto leave; + + /* Parse the response. */ + if (outdatalen && *outdata == 0x7c + && (s = find_tlv (outdata, outdatalen, 0x82, &n))) + { + memmove (outdata, outdata + (s - outdata), n); + outdatalen = n; + } + else + { + err = gpg_error (GPG_ERR_CARD); + log_error ("piv: response does not contain a proper result\n"); + goto leave; + } + + leave: + if (err) + { + xfree (outdata); + *r_outdata = NULL; + *r_outdatalen = 0; + } + else + { + *r_outdata = outdata; + *r_outdatalen = outdatalen; + } + *r_info = 0; + xfree (apdudata); + xfree (indata_buffer); + return err; +} + + /* Check whether a key for DOBJ already exists. We detect this by * reading the certificate described by DOBJ. If FORCE is TRUE a * diagnositic will be printed but no error returned if the key @@ -2679,7 +2824,7 @@ app_select_piv (app_t app) app->fnc.genkey = do_genkey; app->fnc.sign = do_sign; app->fnc.auth = do_auth; - /* app->fnc.decipher = do_decipher; */ + app->fnc.decipher = do_decipher; app->fnc.change_pin = do_change_chv; app->fnc.check_pin = do_check_chv; ----------------------------------------------------------------------- Summary of changes: scd/app-piv.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 15:33:36 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 11 Feb 2019 15:33:36 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.12.0-130-gf8312d7 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 f8312d7c333193582dcb5816198219b9564023f0 (commit) from 302d5ef52e095378231efd54677b5c315354ad78 (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 f8312d7c333193582dcb5816198219b9564023f0 Author: Andre Heinecke Date: Mon Feb 11 15:32:49 2019 +0100 tests: Fix memleak in run-threaded * tests/run-threaded.c (verify): Free msg. diff --git a/tests/run-threaded.c b/tests/run-threaded.c index 93d1588..02524b2 100644 --- a/tests/run-threaded.c +++ b/tests/run-threaded.c @@ -408,6 +408,7 @@ verify (const char *fname, gpgme_protocol_t proto) gpgme_release (ctx); random_data_close (data); + free (msg); } ----------------------------------------------------------------------- Summary of changes: tests/run-threaded.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 15:49:09 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Mon, 11 Feb 2019 15:49:09 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.3.2-21-g5af5604 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 5af56045e25714e2b86a6555d8d976eae47ee748 (commit) via dafa897fd20ae16a45d980aab15adf01db66b491 (commit) via b25b89ba61cd7117bf0f6e5d064afbd27f7c3bcb (commit) via a3e70c63fc2d8c2dface0cfbdb01533ea71a75f8 (commit) via 4eabc9dd780b9fdedcb79b495ccde86b2af2e824 (commit) via 2808386bb5b403f80de78a9d6f0de23c8a010726 (commit) from 489141670fe292216d230b80bb943c267b5d262b (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 5af56045e25714e2b86a6555d8d976eae47ee748 Author: Andre Heinecke Date: Mon Feb 11 15:48:05 2019 +0100 Handle autoimport for attached pgp keys * src/keycache.cpp (KeyCache::import_pgp_key_data): New. * src/keycache.h: Update accordingly. * src/parsecontroller.cpp (ParseController::parse): Check for pgp-keys attachments and import them. diff --git a/src/keycache.cpp b/src/keycache.cpp index 81580ae..9d6f5d2 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -1423,3 +1423,54 @@ KeyCache::getUltimateKeys () gpgrt_lock_unlock (&fpr_map_lock); return ret; } + +/* static */ +bool +KeyCache::import_pgp_key_data (const GpgME::Data &data) +{ + TSTART; + if (data.isNull()) + { + STRANGEPOINT; + TRETURN false; + } + auto ctx = GpgME::Context::create(GpgME::OpenPGP); + + if (!ctx) + { + STRANGEPOINT; + TRETURN false; + } + + const auto type = data.type(); + + if (type != GpgME::Data::PGPKey) + { + log_debug ("%s:%s: Data does not look like PGP Keys", + SRCNAME, __func__); + TRETURN false; + } + const auto keys = data.toKeys(); + + if (keys.empty()) + { + log_debug ("%s:%s: Data does not contain PGP Keys", + SRCNAME, __func__); + TRETURN false; + } + + if (opt.enable_debug & DBG_DATA) + { + std::stringstream ss; + for (const auto &key: keys) + { + ss << key << '\n'; + } + log_debug ("Importing keys: %s", ss.str().c_str()); + } + const auto result = ctx->importKeys(keys); + + log_debug ("%s:%s: Import result from attached key err: %s", + SRCNAME, __func__, result.error ().asString ()); + TRETURN !result.error(); +} diff --git a/src/keycache.h b/src/keycache.h index 0a90575..0563e24 100644 --- a/src/keycache.h +++ b/src/keycache.h @@ -32,6 +32,7 @@ namespace GpgME { class Key; + class Data; }; class Mail; @@ -130,6 +131,10 @@ public: /* Get a vector of ultimately trusted keys. */ std::vector getUltimateKeys (); + /* Import PGP Keys from a Data object. Returns + true on success. */ + static bool import_pgp_key_data(const GpgME::Data &data); + // 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/parsecontroller.cpp b/src/parsecontroller.cpp index 4a72a65..309e587 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -546,6 +546,20 @@ ParseController::parse() m_block_html = true; } + /* Import any application/pgp-keys attachments if the option is set. */ + if (opt.autoimport) + { + for (const auto &attach: get_attachments()) + { + if (attach->get_content_type () == "application/pgp-keys") + { +#ifndef BUILD_TESTS + KeyCache::import_pgp_key_data (attach->get_data()); +#endif + } + } + } + if (opt.enable_debug & DBG_DATA) { std::stringstream ss; commit dafa897fd20ae16a45d980aab15adf01db66b491 Author: Andre Heinecke Date: Mon Feb 11 15:46:00 2019 +0100 Implement auto encrypt untrusted * src/keycache.cpp (getEncryptionKeys): Handle new option. -- This allows opportunistic encryption to any key in the keyring. As this is problematic it is off by default. diff --git a/src/keycache.cpp b/src/keycache.cpp index 3352144..81580ae 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -574,6 +574,14 @@ public: validEnough = true; break; } + if (opt.auto_unstrusted && + uid.validity() == GpgME::UserID::Unknown) + { + log_debug ("%s:%s: Passing unknown trust key for %s because of option", + SRCNAME, __func__, anonstr (recip.c_str ())); + validEnough = true; + break; + } } if (!validEnough) { commit b25b89ba61cd7117bf0f6e5d064afbd27f7c3bcb Author: Andre Heinecke Date: Mon Feb 11 15:45:22 2019 +0100 Add / parse new automation options * src/common_indep.h (opt): Add new fields. * src/main.c (read_options): Read them. diff --git a/src/common_indep.h b/src/common_indep.h index fb693ef..0a71914 100644 --- a/src/common_indep.h +++ b/src/common_indep.h @@ -206,6 +206,8 @@ struct int autoretrieve; /* Use --auto-key-retrieve. */ int search_smime_servers; /* Search for S/MIME keys on all configured S/MIME keyservers for each new unknown mail */ + int auto_unstrusted; /* Automatically encrypt even to untrusted keys. */ + int autoimport; /* Automatically import keys from headers or attachments. */ /* The forms revision number of the binary. */ int forms_revision; diff --git a/src/main.c b/src/main.c index 56b92ad..f61b9ee 100644 --- a/src/main.c +++ b/src/main.c @@ -299,6 +299,8 @@ read_options (void) opt.autotrust = get_conf_bool ("autotrust", 0); opt.search_smime_servers = get_conf_bool ("searchSmimeServers", 0); opt.smime_html_warn_shown = get_conf_bool ("smimeHtmlWarnShown", 0); + opt.auto_unstrusted = get_conf_bool ("autoencryptUntrusted", 0); + opt.autoimport = get_conf_bool ("autoimport", 0); if (!opt.automation) { @@ -308,6 +310,8 @@ read_options (void) opt.autoresolve = 0; opt.autotrust = 0; opt.autoretrieve = 0; + opt.autoimport = 0; + opt.auto_unstrusted = 0; } /* Hidden options */ commit a3e70c63fc2d8c2dface0cfbdb01533ea71a75f8 Author: Andre Heinecke Date: Mon Feb 11 15:44:15 2019 +0100 Store content-type for attachments * src/attachment.cpp (get_content_type, set_content_type): New. * src/mimedataprovider.cpp (create_attachment): Set it. * src/attachment.h: Update accordingly. diff --git a/src/attachment.cpp b/src/attachment.cpp index e626d26..265483a 100644 --- a/src/attachment.cpp +++ b/src/attachment.cpp @@ -77,3 +77,15 @@ Attachment::get_content_id() const { return m_cid; } + +void +Attachment::set_content_type(const char *ctype) +{ + m_ctype = ctype; +} + +std::string +Attachment::get_content_type() const +{ + return m_ctype; +} diff --git a/src/attachment.h b/src/attachment.h index 92bcd78..79f91df 100644 --- a/src/attachment.h +++ b/src/attachment.h @@ -43,6 +43,10 @@ public: void set_content_id (const char *cid); std::string get_content_id() const; + /* Content type */ + void set_content_type (const char *type); + std::string get_content_type () const; + /* get the underlying data structure */ GpgME::Data& get_data(); @@ -51,6 +55,7 @@ private: std::string m_utf8DisplayName; attachtype_t m_type; std::string m_cid; + std::string m_ctype; }; #endif // ATTACHMENT_H diff --git a/src/mimedataprovider.cpp b/src/mimedataprovider.cpp index be10e14..25e576c 100644 --- a/src/mimedataprovider.cpp +++ b/src/mimedataprovider.cpp @@ -1059,6 +1059,14 @@ MimeDataProvider::create_attachment() if (m_mime_ctx->mimestruct_cur && m_mime_ctx->mimestruct_cur->cid) { attach->set_content_id (m_mime_ctx->mimestruct_cur->cid); + log_data ("%s:%s: content-id: %s", + SRCNAME, __func__, m_mime_ctx->mimestruct_cur->cid); + } + if (m_mime_ctx->mimestruct_cur && m_mime_ctx->mimestruct_cur->content_type) + { + attach->set_content_type (m_mime_ctx->mimestruct_cur->content_type); + log_data ("%s:%s: content-type: %s", + SRCNAME, __func__, m_mime_ctx->mimestruct_cur->content_type); } m_attachments.push_back (attach); commit 4eabc9dd780b9fdedcb79b495ccde86b2af2e824 Author: Andre Heinecke Date: Mon Feb 11 14:36:45 2019 +0100 Fix syntax error * src/addin-options.cpp: Fix syntax. diff --git a/src/addin-options.cpp b/src/addin-options.cpp index 393bdaf..2e40bc5 100644 --- a/src/addin-options.cpp +++ b/src/addin-options.cpp @@ -84,10 +84,10 @@ i18n_noops[] = { N_("Also &with untrusted keys"), /* TRANSLATORS: Included means here both attached keys and keys from the * headers */ - N_("&Import any keys included in mails."); + N_("&Import any keys included in mails."), /* TRANSLATORS: Included means here both attached keys and keys from the * headers */ - N_("Import OpenPGP keys from mail attachments or from mail headers."); + N_("Import OpenPGP keys from mail attachments or from mail headers."), /* Not options but strings for the key adder */ /* TRANSLATORS: Part of address book key configuration dialog. commit 2808386bb5b403f80de78a9d6f0de23c8a010726 Author: Andre Heinecke Date: Mon Feb 11 14:35:52 2019 +0100 Fix implicit fallthrough warnings * src/application-events.cpp: Fix unintentional fallthrough from QUIT. * src/mailitem-events.cpp: Mark reply fallthrough as intentional. diff --git a/src/application-events.cpp b/src/application-events.cpp index 5d8b9a8..06baaf7 100644 --- a/src/application-events.cpp +++ b/src/application-events.cpp @@ -100,6 +100,7 @@ EVENT_SINK_INVOKE(ApplicationEvents) { log_debug ("%s:%s: Quit event. Shutting down", SRCNAME, __func__); + TBREAK; } default: log_oom ("%s:%s: Unhandled Event: %lx \n", diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index b251229..fa12d88 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -762,9 +762,8 @@ EVENT_SINK_INVOKE(MailItemEvents) /* Fallthrough */ case ReplyAll: case Reply: - { is_reply = true; - } + __attribute__ ((fallthrough)); case Forward: { log_oom ("%s:%s: %s : %p", ----------------------------------------------------------------------- Summary of changes: src/addin-options.cpp | 4 ++-- src/application-events.cpp | 1 + src/attachment.cpp | 12 ++++++++++ src/attachment.h | 5 ++++ src/common_indep.h | 2 ++ src/keycache.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++ src/keycache.h | 5 ++++ src/mailitem-events.cpp | 3 +-- src/main.c | 4 ++++ src/mimedataprovider.cpp | 8 +++++++ src/parsecontroller.cpp | 14 +++++++++++ 11 files changed, 113 insertions(+), 4 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 11 20:45:19 2019 From: cvs at cvs.gnupg.org (by Ben McGinnes) Date: Mon, 11 Feb 2019 20:45:19 +0100 Subject: [git] gnupg-doc - branch, ben/w3c-as2, updated. d6f056ce3b3093a7023abe136533901fdc90e1a5 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, ben/w3c-as2 has been updated via d6f056ce3b3093a7023abe136533901fdc90e1a5 (commit) from 648558c30e0e6bd0fbb978b99922bccadec01655 (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 d6f056ce3b3093a7023abe136533901fdc90e1a5 Author: Ben McGinnes Date: Tue Feb 12 06:43:54 2019 +1100 protocol: attribution affiliation fix * Corrected Emelia's affiliated organisation, as per her request. Signed-off-by: Ben McGinnes diff --git a/misc/w3c/as2/OpenPGPoverActivityStreams.org b/misc/w3c/as2/OpenPGPoverActivityStreams.org index 1419945..1e99b6f 100644 --- a/misc/w3c/as2/OpenPGPoverActivityStreams.org +++ b/misc/w3c/as2/OpenPGPoverActivityStreams.org @@ -90,7 +90,8 @@ Wiktor Kwapisiewicz. Particularly with regards to the discussions around the WebFinger protocol and related matters. Input and encouragement from [[https://mastodon.social/@david_ross][David Ross]] (Mozilla), [[https://switter.at/@e][Eliza]] (Assembly -Four, Switter), [[https://mastodon.social/@ThisIsMissEm][Emelia]] (Switter) and [[https://switter.at/@vwerner][Vince Werner]] has been a boon. +Four, Switter), [[https://mastodon.social/@ThisIsMissEm][Emelia]] (Unobvious Technology) and [[https://switter.at/@vwerner][Vince Werner]] has +been a boon. *** Additional Thanks ----------------------------------------------------------------------- Summary of changes: misc/w3c/as2/OpenPGPoverActivityStreams.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 12 18:37:43 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Feb 2019 18:37:43 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.12-31-ge5580ae 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 e5580ae7887adb640c330fb3c1e6d0e6984aaeb1 (commit) via 7922e2dd1c7eee48a8a2cf4799827942489ddd0f (commit) via d1df96bf1c48d2e7e9f22c712f98870d53f63851 (commit) from d1bee9d1efa28fa9d35b7eed1e616c6362fd044e (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 e5580ae7887adb640c330fb3c1e6d0e6984aaeb1 Author: Werner Koch Date: Tue Feb 12 18:37:40 2019 +0100 Post release updates -- diff --git a/NEWS b/NEWS index fb40a74..221bc03 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.2.14 (unreleased) +------------------------------------------------- + + Noteworthy changes in version 2.2.13 (2019-02-12) ------------------------------------------------- diff --git a/configure.ac b/configure.ac index f0e06b8..9260684 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], [13]) +m4_define([mym4_micro], [14]) # 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 7922e2dd1c7eee48a8a2cf4799827942489ddd0f Author: Werner Koch Date: Tue Feb 12 16:06:31 2019 +0100 Release 2.2.13 diff --git a/AUTHORS b/AUTHORS index 473b94c..32766a6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,9 +15,9 @@ copyrightable year that would otherwise be listed individually. List of Copyright holders ========================= - Copyright (C) 1997-2018 Werner Koch - Copyright (C) 1994-2018 Free Software Foundation, Inc. - Copyright (C) 2003-2013,2015-2018 g10 Code GmbH + Copyright (C) 1997-2019 Werner Koch + Copyright (C) 1994-2019 Free Software Foundation, Inc. + Copyright (C) 2003-2013,2015-2019 g10 Code GmbH Copyright (C) 2002 Klar?lvdalens Datakonsult AB Copyright (C) 1995-1997, 2000-2007 Ulrich Drepper Copyright (C) 1994 X Consortium diff --git a/NEWS b/NEWS index dfaa428..fb40a74 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,29 @@ -Noteworthy changes in version 2.2.13 (unreleased) +Noteworthy changes in version 2.2.13 (2019-02-12) ------------------------------------------------- + * gpg: Implement key lookup via keygrip (using the & prefix). + + * gpg: Allow generating Ed25519 key from existing key. + + * gpg: Emit an ERROR status line if no key was found with -k. + + * gpg: Stop early when trying to create a primary Elgamal key. [#4329] + + * gpgsm: Print the card's key algorithms along with their keygrips + in interactive key generation. + + * agent: Clear bogus pinentry cache in the error case. [#4348] + + * scd: Support "acknowledge button" feature. + + * scd: Fix for USB INTERRUPT transfer. [#4308] + + * wks: Do no use compression for the the encrypted challenge and + response. + + Release-info: https://dev.gnupg.org/T4290 + See-also: gnupg-announce/2019q1/000434.html + Noteworthy changes in version 2.2.12 (2018-12-14) ------------------------------------------------- diff --git a/README b/README index 4580a39..85639a4 100644 --- a/README +++ b/README @@ -2,8 +2,8 @@ ========================= Version 2.2 - Copyright 1997-2018 Werner Koch - Copyright 1998-2018 Free Software Foundation, Inc. + Copyright 1997-2019 Werner Koch + Copyright 1998-2019 Free Software Foundation, Inc. * INTRODUCTION diff --git a/common/argparse.c b/common/argparse.c index 90d0ff7..8f2c711 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -71,7 +71,7 @@ #else /* Used by GnuPG */ # define ARGPARSE_GPL_VERSION 3 -# define ARGPARSE_CRIGHT_STR "Copyright (C) 2018 Free Software Foundation, Inc." +# define ARGPARSE_CRIGHT_STR "Copyright (C) 2019 Free Software Foundation, Inc." #endif /*GNUPG_MAJOR_VERSION*/ diff --git a/common/w32info-rc.h.in b/common/w32info-rc.h.in index 2ff6863..ea9d463 100644 --- a/common/w32info-rc.h.in +++ b/common/w32info-rc.h.in @@ -29,4 +29,4 @@ built on @BUILD_HOSTNAME@ at @BUILD_TIMESTAMP@\0" #define W32INFO_PRODUCTVERSION "@VERSION@\0" #define W32INFO_LEGALCOPYRIGHT "Copyright \xa9 \ -2018 Free Software Foundation, Inc.\0" +2019 Free Software Foundation, Inc.\0" diff --git a/configure.ac b/configure.ac index 0ee3ffc..f0e06b8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac - for GnuPG 2.1 -# Copyright (C) 1998-2018 Free Software Foundation, Inc. -# Copyright (C) 1998-2018 Werner Koch +# Copyright (C) 1998-2019 Free Software Foundation, Inc. +# Copyright (C) 1998-2019 Werner Koch # # This file is part of GnuPG. # diff --git a/g10/gpg.c b/g10/gpg.c index 0e98c1a..a8f42e0 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1,7 +1,7 @@ /* gpg.c - The GnuPG utility (main for gpg) - * Copyright (C) 1998-2011 Free Software Foundation, Inc. - * Copyright (C) 1997-2017 Werner Koch - * Copyright (C) 2015-2017 g10 Code GmbH + * Copyright (C) 1998-2019 Free Software Foundation, Inc. + * Copyright (C) 1997-2019 Werner Koch + * Copyright (C) 2015-2019 g10 Code GmbH * * This file is part of GnuPG. * commit d1df96bf1c48d2e7e9f22c712f98870d53f63851 Author: Werner Koch Date: Tue Feb 12 16:30:17 2019 +0100 po: Auto-update -- diff --git a/po/ca.po b/po/ca.po index ad6d235..19ad09c 100644 --- a/po/ca.po +++ b/po/ca.po @@ -228,8 +228,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/cs.po b/po/cs.po index 24ada94..e3cc7ef 100644 --- a/po/cs.po +++ b/po/cs.po @@ -230,8 +230,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "Reseta?n? k?d" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0APro vstup pou?ijte kl?vesnici ?te?ky." msgid "Repeat this Reset Code" diff --git a/po/da.po b/po/da.po index 36cc3d7..e2ace1a 100644 --- a/po/da.po +++ b/po/da.po @@ -226,8 +226,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "Nulstillingskode" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0ABrug l?serens numeriske tastatur for indtastning." msgid "Repeat this Reset Code" diff --git a/po/de.po b/po/de.po index ac4d77d..17d1cbe 100644 --- a/po/de.po +++ b/po/de.po @@ -212,8 +212,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "R?ckstellcode" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0AZur Eingabe die Tastatur des Kartenlesers verwenden." msgid "Repeat this Reset Code" diff --git a/po/el.po b/po/el.po index fc25941..920954e 100644 --- a/po/el.po +++ b/po/el.po @@ -206,8 +206,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/eo.po b/po/eo.po index 8626ebc..4fabaa7 100644 --- a/po/eo.po +++ b/po/eo.po @@ -207,8 +207,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/es.po b/po/es.po index c0e05fb..8e6ba70 100644 --- a/po/es.po +++ b/po/es.po @@ -222,8 +222,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "C?digo de Reinicio" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0A Use el teclado del lector como entrada." msgid "Repeat this Reset Code" diff --git a/po/et.po b/po/et.po index 8b12acc..c3e541a 100644 --- a/po/et.po +++ b/po/et.po @@ -203,8 +203,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/fi.po b/po/fi.po index 14b94c2..3ee250d 100644 --- a/po/fi.po +++ b/po/fi.po @@ -219,8 +219,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/fr.po b/po/fr.po index a8e618f..21684c7 100644 --- a/po/fr.po +++ b/po/fr.po @@ -215,8 +215,12 @@ msgstr "CDP" msgid "Reset Code" msgstr "Code de r?initialisation" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0AUtilisez le pav? num?rique du lecteur en entr?e." msgid "Repeat this Reset Code" diff --git a/po/gl.po b/po/gl.po index 61942eb..295322d 100644 --- a/po/gl.po +++ b/po/gl.po @@ -205,8 +205,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/hu.po b/po/hu.po index c45dac1..c0c3d70 100644 --- a/po/hu.po +++ b/po/hu.po @@ -203,8 +203,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/id.po b/po/id.po index 00d416a..59f2c3e 100644 --- a/po/id.po +++ b/po/id.po @@ -208,8 +208,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/it.po b/po/it.po index 42fdee3..fd88478 100644 --- a/po/it.po +++ b/po/it.po @@ -203,8 +203,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/nb.po b/po/nb.po index 159349f..225d400 100644 --- a/po/nb.po +++ b/po/nb.po @@ -207,8 +207,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "Tilbakestillingskode" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0ABruk leserens kodeplate til ? skrive." msgid "Repeat this Reset Code" diff --git a/po/pl.po b/po/pl.po index cac673a..9339511 100644 --- a/po/pl.po +++ b/po/pl.po @@ -200,8 +200,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "Kod resetuj?cy" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0ADo wpisywania nale?y u?y? klawiatury czytnika." msgid "Repeat this Reset Code" diff --git a/po/pt.po b/po/pt.po index 578649a..b7cca6a 100644 --- a/po/pt.po +++ b/po/pt.po @@ -206,8 +206,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/ro.po b/po/ro.po index 0f5dced..e2fa0d7 100644 --- a/po/ro.po +++ b/po/ro.po @@ -219,8 +219,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/ru.po b/po/ru.po index 6972220..43af4e6 100644 --- a/po/ru.po +++ b/po/ru.po @@ -204,8 +204,12 @@ msgstr "??? ????????????? PIN (PUK)" msgid "Reset Code" msgstr "??? ??????" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0A??????? ?? ?????????? ???????????." msgid "Repeat this Reset Code" diff --git a/po/sk.po b/po/sk.po index c8a58fb..3bef735 100644 --- a/po/sk.po +++ b/po/sk.po @@ -206,8 +206,10 @@ msgstr "" msgid "Reset Code" msgstr "" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +msgid "Use the reader's pinpad for input." msgstr "" #, fuzzy diff --git a/po/sv.po b/po/sv.po index b763b8d..9ed59d8 100644 --- a/po/sv.po +++ b/po/sv.po @@ -236,9 +236,12 @@ msgstr "PUK-kod" msgid "Reset Code" msgstr "Nollst?ll kod" -#, fuzzy, c-format +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy #| msgid "%s%%0A%%0AUse the reader's keypad for input." -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0AAnv?nd l?sarens knappsats f?r inmatning." msgid "Repeat this Reset Code" diff --git a/po/tr.po b/po/tr.po index 8e76bf2..576b4d0 100644 --- a/po/tr.po +++ b/po/tr.po @@ -207,10 +207,14 @@ msgstr "" msgid "Reset Code" msgstr "S?f?rlama Kodu" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." msgstr "" +#, fuzzy +#| msgid "do not use a reader's keypad" +msgid "Use the reader's pinpad for input." +msgstr "bir okuyucu tu?tak?m? kullan?lmaz" + msgid "Repeat this Reset Code" msgstr "Bu S?f?rlama Kodu tekrarlans?n" diff --git a/po/uk.po b/po/uk.po index ea8270b..45039a2 100644 --- a/po/uk.po +++ b/po/uk.po @@ -206,8 +206,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "??? ????????" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0A????????????? ?????????? ??????????? ????????? ??? ????????." msgid "Repeat this Reset Code" diff --git a/po/zh_CN.po b/po/zh_CN.po index ae0fdc4..203d4bf 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -197,9 +197,12 @@ msgstr "PUK" msgid "Reset Code" msgstr "????" -#, fuzzy, c-format +msgid "Push ACK button on card/token." +msgstr "?? card/token ?? ACK ???" + +#, fuzzy #| msgid "Use the reader's pinpad for input." -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "????????????" msgid "Repeat this Reset Code" @@ -8609,9 +8612,6 @@ msgstr "" "???gpg-check-pattern [??] patternfile\n" "?? patternfile ??????????stdin??????\n" -#~ msgid "Push ACK button on card/token." -#~ msgstr "?? card/token ?? ACK ???" - #~ msgid "waiting for the dirmngr to come up ... (%ds)\n" #~ msgstr "?? dirmngr ?? ... (%ds)\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index 89dab47..e18d306 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -211,8 +211,12 @@ msgstr "PIN ??? (PUK)" msgid "Reset Code" msgstr "???" -#, c-format -msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Push ACK button on card/token." +msgstr "" + +#, fuzzy +#| msgid "%s%%0A%%0AUse the reader's pinpad for input." +msgid "Use the reader's pinpad for input." msgstr "%s%%0A%%0A???????????." msgid "Repeat this Reset Code" ----------------------------------------------------------------------- Summary of changes: AUTHORS | 6 +++--- NEWS | 29 ++++++++++++++++++++++++++++- README | 4 ++-- common/argparse.c | 2 +- common/w32info-rc.h.in | 2 +- configure.ac | 6 +++--- g10/gpg.c | 6 +++--- po/ca.po | 6 ++++-- po/cs.po | 8 ++++++-- po/da.po | 8 ++++++-- po/de.po | 8 ++++++-- po/el.po | 6 ++++-- po/eo.po | 6 ++++-- po/es.po | 8 ++++++-- po/et.po | 6 ++++-- po/fi.po | 6 ++++-- po/fr.po | 8 ++++++-- po/gl.po | 6 ++++-- po/hu.po | 6 ++++-- po/id.po | 6 ++++-- po/it.po | 6 ++++-- po/nb.po | 8 ++++++-- po/pl.po | 8 ++++++-- po/pt.po | 6 ++++-- po/ro.po | 6 ++++-- po/ru.po | 8 ++++++-- po/sk.po | 6 ++++-- po/sv.po | 7 +++++-- po/tr.po | 8 ++++++-- po/uk.po | 8 ++++++-- po/zh_CN.po | 10 +++++----- po/zh_TW.po | 8 ++++++-- 32 files changed, 165 insertions(+), 67 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 12 19:47:50 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 12 Feb 2019 19:47:50 +0100 Subject: [git] gnupg-doc - branch, master, updated. 73e8fe527b3d241a47cee106d97071238cdfd8b4 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 73e8fe527b3d241a47cee106d97071238cdfd8b4 (commit) from 573d41ff1f42af20426267346a9a548e3466e361 (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 73e8fe527b3d241a47cee106d97071238cdfd8b4 Author: Werner Koch Date: Tue Feb 12 19:47:45 2019 +0100 swdb: Release GnuPG 2.2.13 and moved some news to the attic diff --git a/web/index.org b/web/index.org index 5e81383..fc7ccdf 100644 --- a/web/index.org +++ b/web/index.org @@ -64,6 +64,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 2.2.13 released (2019-02-12) + +We are pleased to announce the availability of GnuPG version 2.2.12. +This is a maintenance release fixing a few problems and adding some +minor features. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2010q1/000434.html][more]]} + ** GnuPG 2.2.12 released (2018-12-14) We are pleased to announce the availability of GnuPG version 2.2.12. @@ -110,75 +116,6 @@ 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 {{{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. -This is a maintenance release fixing a few problems. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000424.html][more]]} - -** GnuPG Made Easy 1.11.1 released (2018-04-20) - -[[file:software/gpgme/index.org][GPGME]] is a library that allows to add support for cryptography to a -program. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000423.html][more]]}. - -** GnuPG 2.2.6 released (2018-04-09) - -We are pleased to announce the availability of GnuPG version 2.2.6. -This is a maintenance release fixing a few problems. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000421.html][more]]} - -Update (2018-04-16): In case you run into problems with [[file:software/gpgme/index.org][GPGME]] and this -or a later version of GnuPG, please apply this [[https://lists.gnupg.org/pipermail/gnupg-users/attachments/20180413/e2c8e5d5/attachment-0001.patch][patch]] to GPGME or use -GPGME version 1.11.0 which will soon be released. - -** GnuPG 2.2.5 released (2018-02-22) - -We are pleased to announce the availability of GnuPG version 2.2.5. -This is a maintenance release fixing a few problems. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q1/000420.html][more]]} - -** 20 Years of GnuPG (2017-12-20) - -Exactly 20 years ago the first public version of GnuPG was released -under the name "g10". Today we are pleased to announce the -availability of GnuPG version 2.2.4. This is a maintenance release -fixing a few minor bugs. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000419.html][more]]} - -** GnuPG Made Easy 1.10.0 released (2017-12-12) - -[[file:software/gpgme/index.org][GPGME]] is a library that allows to add support for cryptography to a -program. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000418.html][more]]} - -** GnuPG 2.2.3 released (2017-11-21) - -We are pleased to announce the availability of GnuPG version 2.2.3. -This is a maintenance release mainly fixing a bug on Windows. The -Windows installer [[https://gpg4win.org][Gpg4win]] 3.0.1 already includes this version of -GnuPG. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000417.html][more]]} - -** GnuPG 2.2.2 released (2017-11-07) - -We are pleased to announce the availability of GnuPG version 2.2.2. -This is a maintenance release fixing a few bugs. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000416.html][more]]} - -** GnuPG 2.2.1 released (2017-09-19) - -We are pleased to announce the availability of GnuPG version 2.2.1. -This is a maintenance release fixing a few minor bugs. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000415.html][more]]} - -** Libgcrypt 1.8.1 released (2017-08-31) :important: - -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]]}... - -** GnuPG 2.2.0 released (2017-08-28) - -The GnuPG team is pleased to announce the availability of a new -GnuPG release: version 2.2.0. Read {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000413.html][more]]} for details. - -This release marks the start of a new long term support series to -replace the 2.0.x series which will reach end-of-life on 2017-12-31. - - * COMMENT This is the publishing info used for the GnuPG pages #+begin_src emacs-lisp diff --git a/web/news.org b/web/news.org index 9888d47..c8a6e57 100644 --- a/web/news.org +++ b/web/news.org @@ -8,6 +8,75 @@ On this page you'll find all the news of previous years in reverse chronological order. News for the current year are found at the [[index][main page]]. +** GnuPG 2.2.7 released (2018-05-02) + +We are pleased to announce the availability of GnuPG version 2.2.7. +This is a maintenance release fixing a few problems. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000424.html][more]]} + +** GnuPG Made Easy 1.11.1 released (2018-04-20) + +[[file:software/gpgme/index.org][GPGME]] is a library that allows to add support for cryptography to a +program. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000423.html][more]]}. + +** GnuPG 2.2.6 released (2018-04-09) + +We are pleased to announce the availability of GnuPG version 2.2.6. +This is a maintenance release fixing a few problems. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q2/000421.html][more]]} + +Update (2018-04-16): In case you run into problems with [[file:software/gpgme/index.org][GPGME]] and this +or a later version of GnuPG, please apply this [[https://lists.gnupg.org/pipermail/gnupg-users/attachments/20180413/e2c8e5d5/attachment-0001.patch][patch]] to GPGME or use +GPGME version 1.11.0 which will soon be released. + +** GnuPG 2.2.5 released (2018-02-22) + +We are pleased to announce the availability of GnuPG version 2.2.5. +This is a maintenance release fixing a few problems. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2018q1/000420.html][more]]} + + +** 20 Years of GnuPG (2017-12-20) + +Exactly 20 years ago the first public version of GnuPG was released +under the name "g10". Today we are pleased to announce the +availability of GnuPG version 2.2.4. This is a maintenance release +fixing a few minor bugs. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000419.html][more]]} + +** GnuPG Made Easy 1.10.0 released (2017-12-12) + +[[file:software/gpgme/index.org][GPGME]] is a library that allows to add support for cryptography to a +program. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000418.html][more]]} + +** GnuPG 2.2.3 released (2017-11-21) + +We are pleased to announce the availability of GnuPG version 2.2.3. +This is a maintenance release mainly fixing a bug on Windows. The +Windows installer [[https://gpg4win.org][Gpg4win]] 3.0.1 already includes this version of +GnuPG. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000417.html][more]]} + +** GnuPG 2.2.2 released (2017-11-07) + +We are pleased to announce the availability of GnuPG version 2.2.2. +This is a maintenance release fixing a few bugs. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q4/000416.html][more]]} + +** GnuPG 2.2.1 released (2017-09-19) + +We are pleased to announce the availability of GnuPG version 2.2.1. +This is a maintenance release fixing a few minor bugs. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000415.html][more]]} + +** Libgcrypt 1.8.1 released (2017-08-31) :important: + +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]]}... + +** GnuPG 2.2.0 released (2017-08-28) + +The GnuPG team is pleased to announce the availability of a new +GnuPG release: version 2.2.0. Read {[[https://lists.gnupg.org/pipermail/gnupg-announce/2017q3/000413.html][more]]} for details. + +This release marks the start of a new long term support series to +replace the 2.0.x series which will reach end-of-life on 2017-12-31. + ** GnuPG 2.1.23 released (2017-08-09) diff --git a/web/swdb.mac b/web/swdb.mac index d89eb7c..eae7ece 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -10,17 +10,17 @@ # # GnuPG-2.2 # -#+macro: gnupg22_ver 2.2.12 -#+macro: gnupg22_date 2018-12-14 -#+macro: gnupg22_size 6525k -#+macro: gnupg22_sha1 2aeccc35ea8034306ff7a1072b84abbaa79619c3 -#+macro: gnupg22_sha2 db030f8b4c98640e91300d36d516f1f4f8fe09514a94ea9fc7411ee1a34082cb +#+macro: gnupg22_ver 2.2.13 +#+macro: gnupg22_date 2019-02-12 +#+macro: gnupg22_size 6545k +#+macro: gnupg22_sha1 66ebc053e2d22f743673d3fbe54453774e4fac58 +#+macro: gnupg22_sha2 76c787a955f9e6e0ead47c9be700bfb9d454f955a7b7c7e697aa719bac7b11d8 #+macro: gnupg22_branch STABLE-BRANCH-2-2 -#+macro: gnupg22_w32_ver 2.2.12_20181214 -#+macro: gnupg22_w32_date 2018-12-14 -#+macro: gnupg22_w32_size 3965k -#+macro: gnupg22_w32_sha1 8efed66ebfe68bae3069f7d1724c8b4b9de0b00b -#+macro: gnupg22_w32_sha2 b0ffe2c0153046d4ce9ca2ef2bb68cdfede19bec9db597bad6ae0c84049b59a0 +#+macro: gnupg22_w32_ver 2.2.13_20190212 +#+macro: gnupg22_w32_date 2019-02-12 +#+macro: gnupg22_w32_size 4078k +#+macro: gnupg22_w32_sha1 ce2c5e60f851f3d54c85da1be717cc53742c4953 +#+macro: gnupg22_w32_sha2 7245d857c1641610e8759426a12b62eeee84e27aa4dc4640d7523f4ab51d2da7 # ----------------------------------------------------------------------- Summary of changes: web/index.org | 75 +++++------------------------------------------------------ web/news.org | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ web/swdb.mac | 20 ++++++++-------- 3 files changed, 85 insertions(+), 79 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 13 09:49:19 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Feb 2019 09:49:19 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-371-g7e1cd2c 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 7e1cd2cd416f852fc039af310e3df1ce395d89a9 (commit) from 43b14b4cc227311aa77b1fc1d9577c5f7d3eda86 (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 7e1cd2cd416f852fc039af310e3df1ce395d89a9 Author: Werner Koch Date: Wed Feb 13 09:46:36 2019 +0100 card: New command "yubikey". * tools/card-tool-yubikey.c: New. * tools/Makefile.am (gpg_card_tool_SOURCES): Add it. * tools/card-call-scd.c (scd_apdu): Allow returning data. * tools/card-tool-misc.c (send_apdu): New. Move from gpg-card-tool.c and let it return data. Change all callers. * tools/gpg-card-tool.c (cmd_writecert): Prepend the certref with the current application type. (cmd_yubikey): New. -- This command allows listing of active applications and to enable or disable selected applications. This is in particular useful to disable the OpenPGP application so that the PIV support can easily be tested. Signed-off-by: Werner Koch diff --git a/tools/Makefile.am b/tools/Makefile.am index ad0f223..69f4098 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -129,6 +129,7 @@ gpg_card_tool_SOURCES = \ card-tool.h \ card-call-scd.c \ card-tool-keys.c \ + card-tool-yubikey.c \ card-tool-misc.c gpg_card_tool_LDADD = ../common/libgpgrl.a $(common_libs) \ diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 97fb6d9..8610da8 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -445,12 +445,20 @@ store_serialno (const char *line) /* Send an APDU to the current card. On success the status word is * stored at R_SW inless R_SW is NULL. With HEXAPDU being NULL only a * RESET command is send to scd. With HEXAPDU being the string - * "undefined" the command "SERIALNO undefined" is send to scd. */ + * "undefined" the command "SERIALNO undefined" is send to scd. If + * R_DATA is not NULL the data is without the status code is stored + * there. Caller must release it. */ gpg_error_t -scd_apdu (const char *hexapdu, unsigned int *r_sw) +scd_apdu (const char *hexapdu, unsigned int *r_sw, + unsigned char **r_data, size_t *r_datalen) { gpg_error_t err; + if (r_data) + *r_data = NULL; + if (r_datalen) + *r_datalen = 0; + err = start_agent (START_AGENT_NO_STARTUP_CMDS); if (err) return err; @@ -489,6 +497,12 @@ scd_apdu (const char *hexapdu, unsigned int *r_sw) { if (r_sw) *r_sw = buf16_to_uint (data+datalen-2); + if (r_data && r_datalen) + { + *r_data = data; + *r_datalen = datalen - 2; + data = NULL; + } } xfree (data); } diff --git a/tools/card-tool-misc.c b/tools/card-tool-misc.c index 06fcb67..d0fb55d 100644 --- a/tools/card-tool-misc.c +++ b/tools/card-tool-misc.c @@ -77,3 +77,37 @@ hex_to_buffer (const char *string, size_t *r_length) *r_length = n; return buffer; } + + +/* Direct sending of an hex encoded APDU with error printing. This is + * a simple wrapper around scd_apdu. */ +gpg_error_t +send_apdu (const char *hexapdu, const char *desc, unsigned int ignore, + unsigned char **r_data, size_t *r_datalen) +{ + gpg_error_t err; + unsigned int sw; + + err = scd_apdu (hexapdu, &sw, r_data, r_datalen); + if (err) + log_error ("sending card command %s failed: %s\n", desc, + gpg_strerror (err)); + else if (!hexapdu || !strcmp (hexapdu, "undefined")) + ; + else if (ignore == 0xffff) + ; /* Ignore all status words. */ + else if (sw != 0x9000) + { + switch (sw) + { + case 0x6285: err = gpg_error (GPG_ERR_OBJ_TERM_STATE); break; + case 0x6982: err = gpg_error (GPG_ERR_BAD_PIN); break; + case 0x6985: err = gpg_error (GPG_ERR_USE_CONDITIONS); break; + default: err = gpg_error (GPG_ERR_CARD); + } + if (!(ignore && ignore == sw)) + log_error ("card command %s failed: %s (0x%04x)\n", desc, + gpg_strerror (err), sw); + } + return err; +} diff --git a/tools/card-tool-yubikey.c b/tools/card-tool-yubikey.c new file mode 100644 index 0000000..a03915a --- /dev/null +++ b/tools/card-tool-yubikey.c @@ -0,0 +1,438 @@ +/* card-tool-yubikey.c - Yubikey specific functions. + * Copyright (C) 2019 g10 Code GmbH + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * 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 copy of the GNU General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include + +#include "../common/util.h" +#include "../common/i18n.h" +#include "../common/tlv.h" +#include "../common/ttyio.h" +#include "card-tool.h" + + +/* Object to describe requested interface options. */ +struct iface_s { + unsigned int usb:1; + unsigned int nfc:1; +}; + + +/* Bit flags as used by the fields in struct ykapps_s. */ +#define YKAPP_USB_SUPPORTED 0x01 +#define YKAPP_USB_ENABLED 0x02 +#define YKAPP_NFC_SUPPORTED 0x04 +#define YKAPP_NFC_ENABLED 0x08 +#define YKAPP_SELECTED 0x80 /* Selected by the command. */ + +/* An object to describe the applications on a Yubikey. Each field + * has 8 bits to hold the above flag values. */ +struct ykapps_s { + unsigned int otp:8; + unsigned int u2f:8; + unsigned int opgp:8; + unsigned int piv:8; + unsigned int oath:8; + unsigned int fido2:8; +}; + + + +/* Helper to parse an unsigned integer config value consisting of bit + * flags. TAG select the config item and MASK is the mask ORed into + * the value for a set bit. The function modifies YK. */ +static gpg_error_t +parse_ul_config_value (struct ykapps_s *yk, + const unsigned char *config, size_t configlen, + int tag, unsigned int mask) +{ + const unsigned char *s; + size_t n; + unsigned long ul = 0; + int i; + + s = find_tlv (config, configlen, tag, &n); + if (s && n) + { + if (n > sizeof ul) + { + log_error ("too large integer in Yubikey config tag %02x detected\n", + tag); + if (opt.verbose) + log_printhex (config, configlen, "config:"); + return gpg_error (GPG_ERR_CARD); + } + for (i=0; i < n; i++) + { + ul <<=8; + ul |= s[i]; + } + if (ul & 0x01) + yk->otp |= mask; + if (ul & 0x02) + yk->u2f |= mask; + if (ul & 0x08) + yk->opgp |= mask; + if (ul & 0x10) + yk->piv |= mask; + if (ul & 0x20) + yk->oath |= mask; + if (ul & 0x200) + yk->fido2 |= mask; + } + return 0; +} + + +/* Create an unsigned integer config value for TAG from the data in YK + * and store it the provided 4 byte buffer RESULT. If ENABLE is true + * the respective APP_SELECTED bit in YK sets the corresponding bit + * flags, it is is false that bit flag is cleared. IF APP_SELECTED is + * not set the bit flag is not changed. */ +static void +set_ul_config_value (struct ykapps_s *yk, + unsigned int bitflag, int tag, unsigned int enable, + unsigned char *result) +{ + unsigned long ul = 0; + + /* First set the current values. */ + if ((yk->otp & bitflag)) + ul |= 0x01; + if ((yk->u2f & bitflag)) + ul |= 0x02; + if ((yk->opgp & bitflag)) + ul |= 0x08; + if ((yk->piv & bitflag)) + ul |= 0x10; + if ((yk->oath & bitflag)) + ul |= 0x20; + if ((yk->fido2 & bitflag)) + ul |= 0x200; + + /* Then enable or disable the bits according to the selection flag. */ + if (enable) + { + if ((yk->otp & YKAPP_SELECTED)) + ul |= 0x01; + if ((yk->u2f & YKAPP_SELECTED)) + ul |= 0x02; + if ((yk->opgp & YKAPP_SELECTED)) + ul |= 0x08; + if ((yk->piv & YKAPP_SELECTED)) + ul |= 0x10; + if ((yk->oath & YKAPP_SELECTED)) + ul |= 0x20; + if ((yk->fido2 & YKAPP_SELECTED)) + ul |= 0x200; + } + else + { + if ((yk->otp & YKAPP_SELECTED)) + ul &= ~0x01; + if ((yk->u2f & YKAPP_SELECTED)) + ul &= ~0x02; + if ((yk->opgp & YKAPP_SELECTED)) + ul &= ~0x08; + if ((yk->piv & YKAPP_SELECTED)) + ul &= ~0x10; + if ((yk->oath & YKAPP_SELECTED)) + ul &= ~0x20; + if ((yk->fido2 & YKAPP_SELECTED)) + ul &= ~0x200; + } + + /* Make sure that we do not disable the CCID transport. Without + * CCID we won't have any way to change the configuration again. We + * would instead need one of the other Yubikey tools to enable an + * application and thus its transport again. */ + if (bitflag == YKAPP_USB_ENABLED && !(ul & (0x08|0x10|0x20))) + { + log_info ("Enabling PIV so that at least one CCI transport is enabled\n"); + ul |= 0x10; + } + + result[0] = tag; + result[1] = 2; + result[2] = ul >> 8; + result[3] = ul; +} + + +/* Print the info from YK. */ +static void +yk_list (estream_t fp, struct ykapps_s *yk) +{ + if (opt.interactive) + tty_fprintf (fp, ("Application USB NFC\n" + "-----------------------\n")); + tty_fprintf (fp, "OTP %s %s\n", + (yk->otp & YKAPP_USB_SUPPORTED)? + (yk->otp & YKAPP_USB_ENABLED? "yes" : "no ") : "- ", + (yk->otp & YKAPP_NFC_SUPPORTED)? + (yk->otp & YKAPP_NFC_ENABLED? "yes" : "no ") : "- "); + tty_fprintf (fp, "U2F %s %s\n", + (yk->otp & YKAPP_USB_SUPPORTED)? + (yk->otp & YKAPP_USB_ENABLED? "yes" : "no ") : "- ", + (yk->otp & YKAPP_NFC_SUPPORTED)? + (yk->otp & YKAPP_NFC_ENABLED? "yes" : "no ") : "- "); + tty_fprintf (fp, "OPGP %s %s\n", + (yk->opgp & YKAPP_USB_SUPPORTED)? + (yk->opgp & YKAPP_USB_ENABLED? "yes" : "no ") : "- ", + (yk->opgp & YKAPP_NFC_SUPPORTED)? + (yk->opgp & YKAPP_NFC_ENABLED? "yes" : "no ") : "- "); + tty_fprintf (fp, "PIV %s %s\n", + (yk->piv & YKAPP_USB_SUPPORTED)? + (yk->piv & YKAPP_USB_ENABLED? "yes" : "no ") : "- ", + (yk->piv & YKAPP_NFC_SUPPORTED)? + (yk->piv & YKAPP_NFC_ENABLED? "yes" : "no ") : "- "); + tty_fprintf (fp, "OATH %s %s\n", + (yk->oath & YKAPP_USB_SUPPORTED)? + (yk->oath & YKAPP_USB_ENABLED? "yes" : "no ") : "- ", + (yk->oath & YKAPP_NFC_SUPPORTED)? + (yk->oath & YKAPP_NFC_ENABLED? "yes" : "no ") : "- "); + tty_fprintf (fp, "FIDO2 %s %s\n", + (yk->fido2 & YKAPP_USB_SUPPORTED)? + (yk->fido2 & YKAPP_USB_ENABLED? "yes" : "no ") : "- ", + (yk->fido2 & YKAPP_NFC_SUPPORTED)? + (yk->fido2 & YKAPP_NFC_ENABLED? "yes" : "no ") : "- "); +} + + +/* Enable disable the apps as marked in YK with flag YKAPP_SELECTED. */ +static gpg_error_t +yk_enable_disable (struct ykapps_s *yk, struct iface_s *iface, + const unsigned char *config, size_t configlen, int enable) +{ + gpg_error_t err = 0; + unsigned char apdu[100]; + unsigned int apdulen; + /* const unsigned char *s; */ + /* size_t n; */ + char *hexapdu = NULL; + + apdulen = 0; + apdu[apdulen++] = 0x00; + apdu[apdulen++] = 0x1c; /* Write Config instruction. */ + apdu[apdulen++] = 0x00; + apdu[apdulen++] = 0x00; + apdu[apdulen++] = 0x00; /* Lc will be fixed up later. */ + apdu[apdulen++] = 0x00; /* Length of data will also be fixed up later. */ + + /* The ykman tool has no way to set NFC and USB flags in one go. + * Reasoning about the Yubikey's firmware it seems plausible that + * combining should work. Let's try it here if the user called for + * setting both interfaces. */ + if (iface->nfc) + { + set_ul_config_value (yk, YKAPP_NFC_ENABLED, 0x0e, enable, apdu+apdulen); + apdulen += 4; + } + if (iface->usb) + { + set_ul_config_value (yk, YKAPP_USB_ENABLED, 0x03, enable, apdu+apdulen); + apdulen += 4; + /* Yubikey's ykman copies parts of the config data when writing + * the config for USB. Below is a commented example on how that + * can be done. */ + (void)config; + (void)configlen; + /* Copy the device flags. */ + /* s = find_tlv (config, configlen, 0x08, &n); */ + /* if (s && n) */ + /* { */ + /* s -= 2; */ + /* n += 2; */ + /* if (apdulen + n > sizeof apdu) */ + /* { */ + /* err = gpg_error (GPG_ERR_BUFFER_TOO_SHORT); */ + /* goto leave; */ + /* } */ + /* memcpy (apdu+apdulen, s, n); */ + /* apdulen += n; */ + /* } */ + } + if (iface->nfc || iface->usb) + { + if (apdulen + 2 > sizeof apdu) + { + err = gpg_error (GPG_ERR_BUFFER_TOO_SHORT); + goto leave; + } + /* Disable the next two lines to let the card reboot. Not doing + * this is however more convenient for this tool because further + * commands don't end up with an error. It seems to be better + * that a "reset" command from gpg-card-tool is run at the + * user's discretion. */ + /* apdu[apdulen++] = 0x0c; /\* Reboot tag *\/ */ + /* apdu[apdulen++] = 0; /\* No data for reboot. *\/ */ + /* Fixup the lngth bytes. */ + apdu[4] = apdulen - 6 + 1; + apdu[5] = apdulen - 6; + + hexapdu = bin2hex (apdu, apdulen, NULL); + if (!hexapdu) + err = gpg_error_from_syserror (); + else + err = send_apdu (hexapdu, "YK.write_config", 0, NULL, NULL); + } + + leave: + xfree (hexapdu); + return err; +} + + +/* Implementation part of cmd_yubikey. ARGV is an array of size ARGc + * with the argumets given to the yubikey command. Note that ARGV has + * no terminating NULL so that ARGC must be considred. FP is the + * stream to output information. This function must only be called on + * Yubikeys. */ +gpg_error_t +yubikey_commands (estream_t fp, int argc, char *argv[]) +{ + gpg_error_t err; + enum {ykLIST, ykENABLE, ykDISABLE } cmd; + struct iface_s iface = {0,0}; + struct ykapps_s ykapps = {0}; + unsigned char *config = NULL; + size_t configlen; + int i; + + if (!argc) + return gpg_error (GPG_ERR_SYNTAX); + + /* Parse command. */ + if (!ascii_strcasecmp (argv[0], "list")) + cmd = ykLIST; + else if (!ascii_strcasecmp (argv[0], "enable")) + cmd = ykENABLE; + else if (!ascii_strcasecmp (argv[0], "disable")) + cmd = ykDISABLE; + else + { + err = gpg_error (GPG_ERR_UNKNOWN_COMMAND); + goto leave; + } + + /* Parse interface if needed. */ + if (cmd == ykLIST) + iface.usb = iface.nfc = 1; + else if (argc < 2) + { + err = gpg_error (GPG_ERR_SYNTAX); + goto leave; + } + else if (!ascii_strcasecmp (argv[1], "usb")) + iface.usb = 1; + else if (!ascii_strcasecmp (argv[1], "nfc")) + iface.nfc = 1; + else if (!ascii_strcasecmp (argv[1], "all") || !strcmp (argv[1], "*")) + iface.usb = iface.nfc = 1; + else + { + err = gpg_error (GPG_ERR_SYNTAX); + goto leave; + } + + /* Parse list of applications. */ + for (i=2; i < argc; i++) + { + if (!ascii_strcasecmp (argv[i], "otp")) + ykapps.otp = 0x80; + else if (!ascii_strcasecmp (argv[i], "u2f")) + ykapps.u2f = 0x80; + else if (!ascii_strcasecmp (argv[i], "opgp") + ||!ascii_strcasecmp (argv[i], "openpgp")) + ykapps.opgp = 0x80; + else if (!ascii_strcasecmp (argv[i], "piv")) + ykapps.piv = 0x80; + else if (!ascii_strcasecmp (argv[i], "oath") + || !ascii_strcasecmp (argv[i], "oauth")) + ykapps.oath = 0x80; + else if (!ascii_strcasecmp (argv[i], "fido2")) + ykapps.fido2 = 0x80; + else if (!ascii_strcasecmp (argv[i], "all")|| !strcmp (argv[i], "*")) + { + ykapps.otp = ykapps.u2f = ykapps.opgp = ykapps.piv = ykapps.oath + = ykapps.fido2 = 0x80; + } + else + { + err = gpg_error (GPG_ERR_SYNTAX); + goto leave; + } + } + + /* Select the Yubikey Manager application. */ + err = send_apdu ("00A4040008a000000527471117", "Select.YK-Manager", 0, + NULL, NULL); + if (err) + goto leave; + /* Send the read config command. */ + err = send_apdu ("001D000000", "YK.read_config", 0, &config, &configlen); + if (err) + goto leave; + if (!configlen || *config > configlen - 1) + { + /* The length byte is shorter than the actual length. */ + log_error ("Yubikey returned improper config data\n"); + log_printhex (config, configlen, "config:"); + err = gpg_error (GPG_ERR_CARD); + goto leave; + } + if (configlen-1 > *config) + { + log_info ("Extra config data ignored\n"); + log_printhex (config, configlen, "config:"); + } + configlen = *config; + + err = parse_ul_config_value (&ykapps, config+1, configlen, + 0x01, YKAPP_USB_SUPPORTED); + if (!err) + err = parse_ul_config_value (&ykapps, config+1, configlen, + 0x03, YKAPP_USB_ENABLED); + if (!err) + err = parse_ul_config_value (&ykapps, config+1, configlen, + 0x0d, YKAPP_NFC_SUPPORTED); + if (!err) + err = parse_ul_config_value (&ykapps, config+1, configlen, + 0x0e, YKAPP_NFC_ENABLED); + if (err) + goto leave; + + switch (cmd) + { + case ykLIST: yk_list (fp, &ykapps); break; + case ykENABLE: err = yk_enable_disable (&ykapps, &iface, + config+1, configlen, 1); break; + case ykDISABLE: err = yk_enable_disable (&ykapps, &iface, + config+1, configlen, 0); break; + } + + leave: + xfree (config); + return err; +} diff --git a/tools/card-tool.h b/tools/card-tool.h index f49f253..f83ebf9 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -192,12 +192,16 @@ gpg_error_t test_get_matching_keys (const char *hexgrip); /*-- card-tool-misc.c --*/ key_info_t find_kinfo (card_info_t info, const char *keyref); void *hex_to_buffer (const char *string, size_t *r_length); +gpg_error_t send_apdu (const char *hexapdu, const char *desc, + unsigned int ignore, + unsigned char **r_data, size_t *r_datalen); /*-- card-call-scd.c --*/ void release_card_info (card_info_t info); const char *app_type_string (app_type_t app_type); -gpg_error_t scd_apdu (const char *hexapdu, unsigned int *r_sw); +gpg_error_t scd_apdu (const char *hexapdu, unsigned int *r_sw, + unsigned char **r_data, size_t *r_datalen); gpg_error_t scd_learn (card_info_t info); gpg_error_t scd_getattr (const char *name, struct card_info_s *info); gpg_error_t scd_setattr (const char *name, @@ -218,6 +222,8 @@ gpg_error_t scd_checkpin (const char *serialno); unsigned long agent_get_s2k_count (void); +/*-- card-tool-yubikey.c --*/ +gpg_error_t yubikey_commands (estream_t fp, int argc, char *argv[]); #endif /*GNUPG_CARD_TOOL_H*/ diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 93153b1..2bc2e5f 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -1596,6 +1596,16 @@ cmd_writecert (card_info_t info, char *argstr) } certref = certref_buffer = xstrdup ("OPENPGP.3"); } + else /* Upcase the certref; prepend cardtype if needed. */ + { + if (!strchr (certref, '.')) + certref_buffer = xstrconcat (app_type_string (info->apptype), ".", + certref, NULL); + else + certref_buffer = xstrdup (certref); + ascii_strupr (certref_buffer); + certref = certref_buffer; + } if (opt_clear) { @@ -2156,38 +2166,6 @@ cmd_unblock (card_info_t info) } -/* Direct sending of an hex encoded APDU with error printing. */ -static gpg_error_t -send_apdu (const char *hexapdu, const char *desc, unsigned int ignore) -{ - gpg_error_t err; - unsigned int sw; - - err = scd_apdu (hexapdu, &sw); - if (err) - log_error ("sending card command %s failed: %s\n", desc, - gpg_strerror (err)); - else if (!hexapdu || !strcmp (hexapdu, "undefined")) - ; - else if (ignore == 0xffff) - ; /* Ignore all status words. */ - else if (sw != 0x9000) - { - switch (sw) - { - case 0x6285: err = gpg_error (GPG_ERR_OBJ_TERM_STATE); break; - case 0x6982: err = gpg_error (GPG_ERR_BAD_PIN); break; - case 0x6985: err = gpg_error (GPG_ERR_USE_CONDITIONS); break; - default: err = gpg_error (GPG_ERR_CARD); - } - if (!(ignore && ignore == sw)) - log_error ("card command %s failed: %s (0x%04x)\n", desc, - gpg_strerror (err), sw); - } - return err; -} - - /* Note: On successful execution a redisplay should be scheduled. If * this function fails the card may be in an unknown state. */ static gpg_error_t @@ -2308,11 +2286,12 @@ cmd_factoryreset (card_info_t info) * unblock PIN command. */ any_apdu = 1; for (i=0; i < 5; i++) - send_apdu ("0020008008FFFFFFFFFFFFFFFF", "VERIFY", 0xffff); + send_apdu ("0020008008FFFFFFFFFFFFFFFF", "VERIFY", 0xffff, + NULL, NULL); for (i=0; i < 5; i++) send_apdu ("002C008010FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "RESET RETRY COUNTER", 0xffff); - err = send_apdu ("00FB000001FF", "YUBIKEY RESET", 0); + "RESET RETRY COUNTER", 0xffff, NULL, NULL); + err = send_apdu ("00FB000001FF", "YUBIKEY RESET", 0, NULL, NULL); if (err) goto leave; } @@ -2321,14 +2300,15 @@ cmd_factoryreset (card_info_t info) any_apdu = 1; /* We need to select a card application before we can send APDUs * to the card without scdaemon doing anything on its own. */ - err = send_apdu (NULL, "RESET", 0); + err = send_apdu (NULL, "RESET", 0, NULL, NULL); if (err) goto leave; - err = send_apdu ("undefined", "dummy select ", 0); + err = send_apdu ("undefined", "dummy select ", 0, NULL, NULL); if (err) goto leave; /* Select the OpenPGP application. */ - err = send_apdu ("00A4040006D27600012401", "SELECT AID", 0); + err = send_apdu ("00A4040006D27600012401", "SELECT AID", 0, + NULL, NULL); if (err) goto leave; @@ -2343,14 +2323,16 @@ cmd_factoryreset (card_info_t info) for (i=0; i < 4; i++) send_apdu ("0020008120" "40404040404040404040404040404040" - "40404040404040404040404040404040", "VERIFY", 0xffff); + "40404040404040404040404040404040", "VERIFY", 0xffff, + NULL, NULL); for (i=0; i < 4; i++) send_apdu ("0020008320" "40404040404040404040404040404040" - "40404040404040404040404040404040", "VERIFY", 0xffff); + "40404040404040404040404040404040", "VERIFY", 0xffff, + NULL, NULL); /* Send terminate datafile command. */ - err = send_apdu ("00e60000", "TERMINATE DF", 0x6985); + err = send_apdu ("00e60000", "TERMINATE DF", 0x6985, NULL, NULL); if (err) goto leave; } @@ -2361,13 +2343,13 @@ cmd_factoryreset (card_info_t info) any_apdu = 1; /* Send activate datafile command. This is used without * confirmation if the card is already in termination state. */ - err = send_apdu ("00440000", "ACTIVATE DF", 0); + err = send_apdu ("00440000", "ACTIVATE DF", 0, NULL, NULL); if (err) goto leave; } /* Finally we reset the card reader once more. */ - err = send_apdu (NULL, "RESET", 0); + err = send_apdu (NULL, "RESET", 0, NULL, NULL); if (err) goto leave; @@ -2859,7 +2841,60 @@ cmd_uif (card_info_t info, char *argstr) } +static gpg_error_t +cmd_yubikey (card_info_t info, char *argstr) +{ + gpg_error_t err, err2; + estream_t fp = opt.interactive? NULL : es_stdout; + char *words[20]; + int nwords; + + if (!info) + return print_help + ("YUBIKEY args\n\n" + "Various commands pertaining to Yubikey tokens with being:\n" + "\n" + " LIST \n" + "\n" + "List supported and enabled applications.\n" + "\n" + " ENABLE usb|nfc|all [otp|u2f|opgp|piv|oath|fido2|all]\n" + " DISABLE usb|nfc|all [otp|u2f|opgp|piv|oath|fido2|all]\n" + "\n" + "Enable or disable the specified or all applications on the\n" + "given interface.", + 0); + + argstr = skip_options (argstr); + + if (!info->cardtype || strcmp (info->cardtype, "yubikey")) + { + log_info ("This command can only be used with Yubikeys.\n"); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto leave; + } + + nwords = split_fields (argstr, words, DIM (words)); + if (nwords < 1) + { + err = gpg_error (GPG_ERR_SYNTAX); + goto leave; + } + + + /* Note that we always do a learn to get a chance to the card back + * into a usable state. */ + err = yubikey_commands (fp, nwords, words); + err2 = scd_learn (info); + if (err2) + log_error ("Error re-reading card: %s\n", gpg_strerror (err)); + + leave: + return err; +} + + /* Data used by the command parser. This needs to be outside of the * function scope to allow readline based command completion. */ enum cmdids @@ -2869,7 +2904,7 @@ enum cmdids cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSALUT, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP, - cmdKEYATTR, cmdUIF, cmdAUTHENTICATE, + cmdKEYATTR, cmdUIF, cmdAUTHENTICATE, cmdYUBIKEY, cmdINVCMD }; @@ -2907,10 +2942,10 @@ static struct { "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")}, { "key-attr", cmdKEYATTR, 1, N_("change the key attribute")}, { "uif", cmdUIF, 1, N_("change the User Interaction Flag")}, - /* Note, that we do not announce these command yet. */ { "privatedo", cmdPRIVATEDO, 0, N_("change a private data object")}, { "readcert", cmdREADCERT, 0, N_("read a certificate from a data object")}, { "writecert", cmdWRITECERT, 1, N_("store a certificate to a data object")}, + { "yubikey", cmdYUBIKEY, 0, N_("Yubikey management commands")}, { NULL, cmdINVCMD, 0, NULL } }; @@ -3020,7 +3055,7 @@ dispatch_command (card_info_t info, const char *orig_command) else { flush_keyblock_cache (); - err = scd_apdu (NULL, NULL); + err = scd_apdu (NULL, NULL, NULL, NULL); } break; @@ -3048,6 +3083,7 @@ dispatch_command (card_info_t info, const char *orig_command) case cmdKDFSETUP: err = cmd_kdfsetup (info, argstr); break; case cmdKEYATTR: err = cmd_keyattr (info, argstr); break; case cmdUIF: err = cmd_uif (info, argstr); break; + case cmdYUBIKEY: err = cmd_yubikey (info, argstr); break; case cmdINVCMD: default: @@ -3262,7 +3298,7 @@ interactive_loop (void) else { flush_keyblock_cache (); - err = scd_apdu (NULL, NULL); + err = scd_apdu (NULL, NULL, NULL, NULL); } break; @@ -3318,6 +3354,7 @@ interactive_loop (void) case cmdKDFSETUP: err = cmd_kdfsetup (info, argstr); break; case cmdKEYATTR: err = cmd_keyattr (info, argstr); break; case cmdUIF: err = cmd_uif (info, argstr); break; + case cmdYUBIKEY: err = cmd_yubikey (info, argstr); break; case cmdINVCMD: default: ----------------------------------------------------------------------- Summary of changes: tools/Makefile.am | 1 + tools/card-call-scd.c | 18 +- tools/card-tool-misc.c | 34 ++++ tools/card-tool-yubikey.c | 438 ++++++++++++++++++++++++++++++++++++++++++++++ tools/card-tool.h | 8 +- tools/gpg-card-tool.c | 131 +++++++++----- 6 files changed, 580 insertions(+), 50 deletions(-) create mode 100644 tools/card-tool-yubikey.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 13 13:58:15 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 13 Feb 2019 13:58:15 +0100 Subject: [git] gnupg-doc - branch, master, updated. 9f4400dfc8fe39cd6d0fc5b0ff323f52e985e788 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 9f4400dfc8fe39cd6d0fc5b0ff323f52e985e788 (commit) from 73e8fe527b3d241a47cee106d97071238cdfd8b4 (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 9f4400dfc8fe39cd6d0fc5b0ff323f52e985e788 Author: Werner Koch Date: Wed Feb 13 13:57:54 2019 +0100 web: Fix link in previous commit diff --git a/web/index.org b/web/index.org index fc7ccdf..74a3039 100644 --- a/web/index.org +++ b/web/index.org @@ -68,7 +68,7 @@ The latest release news:\\ We are pleased to announce the availability of GnuPG version 2.2.12. This is a maintenance release fixing a few problems and adding some -minor features. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2010q1/000434.html][more]]} +minor features. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2019q1/000434.html][more]]} ** GnuPG 2.2.12 released (2018-12-14) ----------------------------------------------------------------------- Summary of changes: web/index.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 Thu Feb 14 01:23:37 2019 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat via Gnupg-devel) Date: Thu, 14 Feb 2019 01:23:37 +0100 Subject: [git] KSBA - branch, master, updated. libksba-1.3.5-35-g9888206 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 "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 98882064f45778927d38c6fdbe008f5858b36813 (commit) from 3f99f332ada603468eb30d77649c4fdf84b383e6 (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 98882064f45778927d38c6fdbe008f5858b36813 Author: Damien Goutte-Gattat via Gnupg-devel Date: Fri Nov 16 01:27:38 2018 +0000 Support multi-valued signatures in CSRs. * src/certreq.c (ksba_certreq_set_sig_val): Support signatures made of several values. -- The current implementation of ksba_certreq_set_sig_val takes only the first MPI value in the provided S-expression to build the CSR signature. This is enough for RSA, but not for ECDSA since a ECDSA signature is made of two values. This patch makes sure all values are taken into account. It also partially replaces some of the ad-hoc parsing code by the helper functions defined in sexp-parse.h. GnuPG-bug-id: 4092 Signed-off-by: Damien Goutte-Gattat diff --git a/src/certreq.c b/src/certreq.c index 46fca44..5c730a7 100644 --- a/src/certreq.c +++ b/src/certreq.c @@ -42,6 +42,7 @@ #include "keyinfo.h" #include "der-encoder.h" #include "ber-help.h" +#include "sexp-parse.h" #include "certreq.h" static const char oidstr_subjectAltName[] = "2.5.29.17"; @@ -406,8 +407,10 @@ ksba_certreq_add_extension (ksba_certreq_t cr, gpg_error_t ksba_certreq_set_sig_val (ksba_certreq_t cr, ksba_const_sexp_t sigval) { - const char *s, *endp; - unsigned long n; + const unsigned char *s, *saved; + char *buf = NULL; + unsigned long n, len; + int pass, nparam; if (!cr) return gpg_error (GPG_ERR_INV_VALUE); @@ -417,24 +420,17 @@ ksba_certreq_set_sig_val (ksba_certreq_t cr, ksba_const_sexp_t sigval) return gpg_error (GPG_ERR_INV_SEXP); s++; - n = strtoul (s, (char**)&endp, 10); - s = endp; - if (!n || *s!=':') - return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */ - s++; - if (n != 7 || memcmp (s, "sig-val", 7)) + if (!(n = snext (&s))) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, 7, "sig-val")) return gpg_error (GPG_ERR_UNKNOWN_SEXP); - s += 7; if (*s != '(') return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP); s++; /* break out the algorithm ID */ - n = strtoul (s, (char**)&endp, 10); - s = endp; - if (!n || *s != ':') - return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */ - s++; + if (!(n = snext (&s))) + return gpg_error (GPG_ERR_INV_SEXP); xfree (cr->sig_val.algo); if (n==3 && s[0] == 'r' && s[1] == 's' && s[2] == 'a') { /* kludge to allow "rsa" to be passed as algorithm name */ @@ -452,42 +448,98 @@ ksba_certreq_set_sig_val (ksba_certreq_t cr, ksba_const_sexp_t sigval) } s += n; - /* And now the values - FIXME: For now we only support one */ - /* fixme: start loop */ - if (*s != '(') - return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP); - s++; - n = strtoul (s, (char**)&endp, 10); - s = endp; - if (!n || *s != ':') - return gpg_error (GPG_ERR_INV_SEXP); - s++; - s += n; /* ignore the name of the parameter */ + /* And now the values. + * + * If there is only one value, the signature is simply + * that value. Otherwise, the signature is a DER-encoded + * SEQUENCE of INTEGERs representing the different values. + * + * We need three passes over the values: + * - first pass is to get the number of values (nparam); + * - second pass is to compute the total length (len); + * - third pass is to build the final signature. */ + for (pass = 1, nparam = len = 0, saved = s; pass < 4; pass++) + { + s = saved; - if (!digitp(s)) - return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */ - n = strtoul (s, (char**)&endp, 10); - s = endp; - if (!n || *s != ':') - return gpg_error (GPG_ERR_INV_SEXP); - s++; - if (n > 1 && !*s) - { /* We might have a leading zero due to the way we encode - MPIs - this zero should not go into the BIT STRING. */ - s++; - n--; + if (pass == 3) + { + size_t needed = len; + if (nparam > 1) + needed += _ksba_ber_count_tl (TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, len); + + xfree (cr->sig_val.value); + cr->sig_val.value = xtrymalloc (needed); + if (!cr->sig_val.value) + return gpg_error (GPG_ERR_ENOMEM); + cr->sig_val.valuelen = needed; + buf = cr->sig_val.value; + + if (nparam > 1) + buf += _ksba_ber_encode_tl (buf, TYPE_SEQUENCE, + CLASS_UNIVERSAL, 1, len); + } + + while (*s != ')') + { + if (*s != '(') + return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP); + s++; + if (!(n = snext (&s))) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; /* Ignore the name of the parameter. */ + + if (!digitp (s)) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (!(n = snext (&s))) + return gpg_error (GPG_ERR_INV_SEXP); + + if (pass == 1) + nparam++; + else if (pass == 2) + { + if (nparam > 1) + len += _ksba_ber_count_tl (TYPE_INTEGER, CLASS_UNIVERSAL, 0, + *s >= 0x80? n + 1 : n) + + (*s >= 0x80? n + 1 : n); + else + len += (n > 1 && !*s)? n - 1 : n; + } + else if (pass == 3) + { + if (nparam > 1) + { + if (*s >= 0x80) + { /* Add leading zero byte. */ + buf += _ksba_ber_encode_tl (buf, TYPE_INTEGER, + CLASS_UNIVERSAL, 0, n + 1); + *buf++ = 0; + } + else + buf += _ksba_ber_encode_tl (buf, TYPE_INTEGER, + CLASS_UNIVERSAL, 0, n); + memcpy (buf, s, n); + buf += n; + } + else + { + if (n > 1 && !*s) + { /* Remove leading zero byte, which must not be + included in the bitstring. */ + s++; + n--; + } + memcpy (buf, s, n); + buf += n; + } + } + + s += n; + if (*s != ')') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + } } - xfree (cr->sig_val.value); - cr->sig_val.value = xtrymalloc (n); - if (!cr->sig_val.value) - return gpg_error (GPG_ERR_ENOMEM); - memcpy (cr->sig_val.value, s, n); - cr->sig_val.valuelen = n; - s += n; - if ( *s != ')') - return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */ - s++; - /* fixme: end loop over parameters */ /* we need 2 closing parenthesis */ if ( *s != ')' || s[1] != ')') ----------------------------------------------------------------------- Summary of changes: src/certreq.c | 148 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 48 deletions(-) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 14 15:45:56 2019 From: cvs at cvs.gnupg.org (by Ingvar Hagelund) Date: Thu, 14 Feb 2019 15:45:56 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-372-gb89f179 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 b89f1790e0b9f3196a2382a9b9ff5f461c58a449 (commit) from 7e1cd2cd416f852fc039af310e3df1ce395d89a9 (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 b89f1790e0b9f3196a2382a9b9ff5f461c58a449 Author: Ingvar Hagelund Date: Thu Feb 14 09:44:38 2019 -0500 po: Correct a simple typo in the Norwegian translation Signed-off-by: Ingvar Hagelund diff --git a/po/nb.po b/po/nb.po index c6694e7..c040c44 100644 --- a/po/nb.po +++ b/po/nb.po @@ -3180,7 +3180,7 @@ msgid "Really sign all text user IDs? (y/N) " msgstr "Er du sikker p? at du vil signerere alle bruker-id-er? (j/N) " msgid "Really sign all user IDs? (y/N) " -msgstr "Er du sikekr p? at du vil signerere alle bruker-id-er? (j/N) " +msgstr "Er du sikker p? at du vil signerere alle bruker-id-er? (j/N) " msgid "Hint: Select the user IDs to sign\n" msgstr "Tips: Velg bruker-id-en(e) du vil signere\n" ----------------------------------------------------------------------- Summary of changes: po/nb.po | 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 Thu Feb 14 15:46:49 2019 From: cvs at cvs.gnupg.org (by Ingvar Hagelund) Date: Thu, 14 Feb 2019 15:46:49 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.13-2-ga09bba9 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 a09bba976d2f5694011a9291189a70a0f3c4caae (commit) from e5580ae7887adb640c330fb3c1e6d0e6984aaeb1 (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 a09bba976d2f5694011a9291189a70a0f3c4caae Author: Ingvar Hagelund Date: Thu Feb 14 09:44:38 2019 -0500 po: Correct a simple typo in the Norwegian translation Signed-off-by: Ingvar Hagelund diff --git a/po/nb.po b/po/nb.po index 225d400..9eff77d 100644 --- a/po/nb.po +++ b/po/nb.po @@ -3286,7 +3286,7 @@ msgid "Really sign all text user IDs? (y/N) " msgstr "Er du sikker p? at du vil signerere alle bruker-id-er? (j/N) " msgid "Really sign all user IDs? (y/N) " -msgstr "Er du sikekr p? at du vil signerere alle bruker-id-er? (j/N) " +msgstr "Er du sikker p? at du vil signerere alle bruker-id-er? (j/N) " msgid "Hint: Select the user IDs to sign\n" msgstr "Tips: Velg bruker-id-en(e) du vil signere\n" ----------------------------------------------------------------------- Summary of changes: po/nb.po | 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 Thu Feb 14 20:58:35 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 14 Feb 2019 20:58:35 +0100 Subject: [git] Scute - branch, master, updated. scute-1.5.0-10-gff9e757 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 "PKCS#11 token on top of gpg-agent". The branch, master has been updated via ff9e757e352f1b4cf3b4625eb4398415051367af (commit) from c4be31f93ea5f471f7ca127ed61b02fc14c418d6 (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 ff9e757e352f1b4cf3b4625eb4398415051367af Author: Werner Koch Date: Thu Feb 14 20:57:57 2019 +0100 Rework of some parts to support several keys pers slot. * src/cert.h (struct cert): Add member certref. * src/agent.h (struct agent_card_info_s): Remove legacy data. * src/agent.c (learn_status_cb): Ditto. (scute_agent_get_cert): Copy the certref to the cert object. * src/cert-object.c (scute_attr_cert): Add arg 'grip' and use new scheme for CKA_ID. (scute_attr_prv): Ditto. * src/gpgsm.c (struct search): Rename to search_cb_parm for clarity. Add member 'grip'. (search_cb): Pass GRIP to scute_attr_prv and scute_attr_cert. (scute_gpgsm_get_cert): Convey GRIP. * src/slots.c (slot_init): Replace fixed "OPENPGP.3" by a loop over all available keyrefs. (session_sign): Actually use the set key. Add a few checks. * src/settings.h (LIBRARY_DESCRIPTION): Rename to "GnuPG". * src/slots.c (mechanism_alloc): Change ulMaxKeySize to 4096. * src/p11-gettokeninfo.c (C_GetTokenInfo): Set ulMaxSessionCount to CK_EFFECTIVELY_INFINITE. * tests/t-getattribute.c (dump_one_string): New. (dump_object): Use for some objects. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 3615a49..bc56dae 100644 --- a/configure.ac +++ b/configure.ac @@ -73,9 +73,9 @@ LIBSCUTE_LT_REVISION=3 VERSION_MAJOR=1 VERSION_MINOR=0 -NEED_GPG_ERROR_VERSION=1.14 -NEED_LIBASSUAN_VERSION=2.0.0 -NEED_GPGSM_VERSION=1.9.6 +NEED_GPG_ERROR_VERSION=1.24 +NEED_LIBASSUAN_VERSION=2.5.0 +NEED_GPGSM_VERSION=2.2.0 # Some status variables to give feedback at the end of a configure run. have_gpg_error=no have_libassuan=no @@ -252,7 +252,7 @@ AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) # Generate values for the DLL version info if test "$have_w32_system" = yes; then BUILD_TIMESTAMP=`date --iso-8601=minutes` - changequote(,)dnl + changequote(,)dnl BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` changequote([,])dnl BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION_DEC}" @@ -439,7 +439,7 @@ die=no if test "$have_gpg_error" = "no"; then die=yes AC_MSG_NOTICE([[ -*** +*** *** You need libgpg-error to build this program. ** This library is for example available at *** ftp://ftp.gnupg.org/pub/gcrypt/libgpg-error diff --git a/src/agent.c b/src/agent.c index f8bea95..4fe969b 100644 --- a/src/agent.c +++ b/src/agent.c @@ -669,26 +669,6 @@ learn_status_cb (void *opaque, const char *line) strncpy (kinfo->grip, hexgrip, sizeof kinfo->grip); kinfo->grip[sizeof kinfo->grip -1] = 0; - - /* Keep legacy info. */ - if (!strcmp (keyref, "OPENPGP.1")) - { - strncpy (parm->grip1, hexgrip, sizeof parm->grip1); - parm->grip1[sizeof parm->grip1 - 1] = 0; - parm->grip1valid = 1; - } - else if (!strcmp (keyref, "OPENPGP.2")) - { - strncpy (parm->grip2, hexgrip, sizeof parm->grip2); - parm->grip2[sizeof parm->grip2 - 1] = 0; - parm->grip2valid = 1; - } - else if (!strcmp (keyref, "OPENPGP.3")) - { - strncpy (parm->grip3, hexgrip, sizeof parm->grip3); - parm->grip3[sizeof parm->grip3 - 1] = 0; - parm->grip3valid = 1; - } } } else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen)) @@ -854,7 +834,7 @@ pksign_cb (void *opaque, const void *buffer, size_t length) } /* Parse the result of an pksign operation which is a s-expression in - normal form that looks like (7:sig-val(3:rsa(1:s:))). + canonical form that looks like (7:sig-val(3:rsa(1:s:))). The raw result is stored in RESULT of size *LEN, and *LEN is adjusted to the actual size. */ static gpg_error_t @@ -897,7 +877,7 @@ pksign_parse_result (const struct signature *sig, if (! n) return gpg_error (GPG_ERR_INV_SEXP); - /* Remove nul byte prepended by gpg-agent. */ + /* Remove a possible prepended zero byte. */ if (!*s && n > 1) { n -= 1; @@ -990,9 +970,13 @@ decode_hash (const unsigned char *data, int len, return 0; } -/* Call the agent to learn about a smartcard. */ + +/* Call the agent to sign (DATA,LEN) using the key described by + * HEXGRIP. Stores the signature in SIG_RESULT and its lengtn at + * SIG_LEN; SIGLEN must initially point to the allocated size of + * SIG_RESULT. */ gpg_error_t -scute_agent_sign (char *grip, unsigned char *data, int len, +scute_agent_sign (const char *hexgrip, unsigned char *data, int len, unsigned char *sig_result, unsigned int *sig_len) { char cmd[150]; @@ -1020,10 +1004,11 @@ scute_agent_sign (char *grip, unsigned char *data, int len, return 0; } - if (grip == NULL || sig_result == NULL) + if (!hexgrip || !sig_result) return gpg_error (GPG_ERR_INV_ARG); - snprintf (cmd, sizeof (cmd), "SIGKEY %s", grip); + snprintf (cmd, sizeof (cmd), "SIGKEY %s", hexgrip); + err = assuan_transact (agent_ctx, cmd, NULL, NULL, default_inq_cb, NULL, NULL, NULL); if (err) @@ -1149,6 +1134,8 @@ scute_agent_get_cert (const char *certref, struct cert *cert) cert->cert_der = cert_s.cert_der; cert->cert_der_len = cert_s.cert_der_len; + strncpy (cert->certref, certref, sizeof cert->certref -1); + cert->certref[sizeof cert->certref - 1] = 0; return 0; } diff --git a/src/agent.h b/src/agent.h index 3fb2f89..367b7e2 100644 --- a/src/agent.h +++ b/src/agent.h @@ -90,12 +90,6 @@ struct agent_card_info_s cache it anyway. */ int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ - char grip1valid; - char grip2valid; - char grip3valid; - char grip1[41]; - char grip2[41]; - char grip3[41]; int rng_available; /* True if the GET CHALLENGE operation is supported. */ int is_piv; /* True if this is a PIV card. */ @@ -131,11 +125,11 @@ void scute_agent_release_card_info (struct agent_card_info_s *info); key_info_t scute_find_kinfo (agent_card_info_t info, const char *keyref); -/* Sign the data DATA of length LEN with the key GRIP and return the - signature in SIG_RESULT and SIG_LEN. */ -gpg_error_t scute_agent_sign (char *grip, unsigned char *data, int len, - unsigned char *sig_result, - unsigned int *sig_len); +/* Sign the data DATA of length LEN with the key HEXGRIP and return + * the signature in SIG_RESULT and SIG_LEN. */ +gpg_error_t scute_agent_sign (const char *hexgrip, + unsigned char *data, int len, + unsigned char *sig_result, unsigned int *sig_len); /* Determine if FPR is trusted. */ gpg_error_t scute_agent_is_trusted (char *fpr, bool *is_trusted); diff --git a/src/cert-object.c b/src/cert-object.c index 6b559a8..a0f07bd 100644 --- a/src/cert-object.c +++ b/src/cert-object.c @@ -414,7 +414,7 @@ scute_attr_free (CK_ATTRIBUTE_PTR attr, CK_ULONG attr_count) gpg_error_t -scute_attr_cert (struct cert *cert, +scute_attr_cert (struct cert *cert, const char *grip, CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp) { CK_RV err = 0; @@ -432,9 +432,6 @@ scute_attr_cert (struct cert *cert, CK_BBOOL obj_token = CK_TRUE; CK_BBOOL obj_private = CK_FALSE; CK_BBOOL obj_modifiable = CK_FALSE; - CK_BYTE obj_label[] = { 'D', 'u', 'm', 'm', 'y', ' ', - 'L', 'a', 'b', 'e', 'l' }; - CK_CERTIFICATE_TYPE obj_cert_type = CKC_X_509; CK_BBOOL obj_trusted = cert->is_trusted; CK_ULONG obj_cert_cat = 0; @@ -493,8 +490,14 @@ scute_attr_cert (struct cert *cert, err = attr_one (attr, &attr_count, CKA_MODIFIABLE, &obj_modifiable, sizeof obj_modifiable); if (!err) - err = attr_one (attr, &attr_count, CKA_LABEL, - &obj_label, sizeof obj_label); + { + if (*cert->certref) + err = attr_one (attr, &attr_count, CKA_LABEL, + cert->certref, strlen (cert->certref)); + else + err = attr_one (attr, &attr_count, CKA_LABEL, + "DummyLabel", 10); + } if (!err) err = attr_one (attr, &attr_count, CKA_CERTIFICATE_TYPE, &obj_cert_type, sizeof obj_cert_type); @@ -543,22 +546,19 @@ scute_attr_cert (struct cert *cert, err = attr_one (attr, &attr_count, CKA_SUBJECT, subject_start, subject_len); -#if 0 - /* If we get the info directly from the card, we don't have a - fingerprint, and parsing the subject key identifier is quite a - mouth full. Let's try a different approach for now. */ + /* We construct the CKA_ID from the CERTREF and the KEYGRIP. This + * allows us to use both values as needed. */ if (!err) - err = attr_one (attr, &attr_count, CKA_ID, - cert->fpr, 40); -#else - { - char certptr[40]; - snprintf (certptr, DIM (certptr), "%p", cert); - if (!err) + { + char cka_id_buffer[200]; + + snprintf (cka_id_buffer, sizeof cka_id_buffer, "%s %s", + *cert->certref ? cert->certref:"-", + grip && *grip? grip : "?" ); err = attr_one (attr, &attr_count, CKA_ID, - certptr, strlen (certptr)); - } -#endif + cka_id_buffer, strlen (cka_id_buffer)); + } + if (!err) err = attr_one (attr, &attr_count, CKA_ISSUER, @@ -599,8 +599,8 @@ scute_attr_cert (struct cert *cert, gpg_error_t -scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp, - CK_ULONG *attr_countp) +scute_attr_prv (struct cert *cert, const char *grip, + CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp) { CK_RV err = 0; CK_ATTRIBUTE_PTR attr; @@ -617,9 +617,6 @@ scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp, CK_BBOOL obj_token = CK_TRUE; CK_BBOOL obj_private = CK_FALSE; CK_BBOOL obj_modifiable = CK_FALSE; - CK_BYTE obj_label[] = { 'O', 'P', 'E', 'N', 'P', 'G', - 'P', '.', '3' }; - CK_KEY_TYPE obj_key_type = CKK_RSA; CK_DATE obj_start_date; CK_DATE obj_end_date; @@ -686,28 +683,31 @@ scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp, err = attr_one (attr, &attr_count, CKA_MODIFIABLE, &obj_modifiable, sizeof obj_modifiable); if (!err) - err = attr_one (attr, &attr_count, CKA_LABEL, - &obj_label, sizeof obj_label); + { + if (*cert->certref) + err = attr_one (attr, &attr_count, CKA_LABEL, + cert->certref, strlen (cert->certref)); + else + err = attr_one (attr, &attr_count, CKA_LABEL, + "DummyLabel", 10); + } if (!err) err = attr_one (attr, &attr_count, CKA_KEY_TYPE, &obj_key_type, sizeof obj_key_type); -#if 0 - /* If we get the info directly from the card, we don't have a - fingerprint, and parsing the subject key identifier is quite a - mouth full. Let's try a different approach for now. */ + + /* We construct the CKA_ID from the CERTREF and the KEYGRIP. This + * allows us to use both values as needed. */ if (!err) - err = attr_one (attr, &attr_count, CKA_ID, - &cert->fpr, 40); -#else - { - char certptr[40]; - snprintf (certptr, DIM (certptr), "%p", cert); - if (!err) + { + char cka_id_buffer[200]; + + snprintf (cka_id_buffer, sizeof cka_id_buffer, "%s %s", + *cert->certref ? cert->certref:"-", + grip && *grip? grip : "?" ); err = attr_one (attr, &attr_count, CKA_ID, - certptr, strlen (certptr)); - } -#endif + cka_id_buffer, strlen (cka_id_buffer)); + } #if 0 /* For now, we disable these fields. We can parse them from the diff --git a/src/cert.h b/src/cert.h index eb09802..b57db0f 100644 --- a/src/cert.h +++ b/src/cert.h @@ -2,7 +2,7 @@ Copyright (C) 2006, 2007 g10 Code GmbH This file is part of Scute. - + Scute 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 @@ -46,6 +46,10 @@ struct cert /* True if we started to fill in a certificate. */ bool valid; + /* The certifciate reference if retrieved from a card or an empty + * string if not known. Example value: "OPENPGP.3". */ + char certref[25]; + #if 1 /* We disable some elements, because they are easy to get from gpgsm but hard to get from the card directly. These fields are only @@ -121,15 +125,15 @@ gpg_error_t scute_gpgsm_search_certs_by_grip (const char *grip, gpg_error_t scute_gpgsm_search_certs_by_fpr (const char *fpr, cert_search_cb_t search_cb, void *search_cb_hook); - + /* From cert-object.c. */ -gpg_error_t scute_attr_cert (struct cert *cert, +gpg_error_t scute_attr_cert (struct cert *cert, const char *grip, CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp); -gpg_error_t scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp, - CK_ULONG *attr_countp); +gpg_error_t scute_attr_prv (struct cert *cert, const char *grip, + CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp); void scute_attr_free (CK_ATTRIBUTE_PTR attr, CK_ULONG attr_count); diff --git a/src/gpgsm.c b/src/gpgsm.c index 57a364f..27e5036 100644 --- a/src/gpgsm.c +++ b/src/gpgsm.c @@ -49,19 +49,21 @@ #include "debug.h" -struct search +/* Communication object for search_cb. */ +struct search_cb_parm { bool found; /* Set to true if a private key object was found. */ cert_get_cb_t cert_get_cb; void *hook; bool with_chain; + const char *grip; }; static gpg_error_t search_cb (void *hook, struct cert *cert) { - struct search *ctx = hook; + struct search_cb_parm *ctx = hook; gpg_error_t err = 0; CK_ATTRIBUTE_PTR attrp; @@ -70,7 +72,7 @@ search_cb (void *hook, struct cert *cert) /* Add the private key object only once. */ if (!ctx->found) { - err = scute_attr_prv (cert, &attrp, &attr_countp); + err = scute_attr_prv (cert, ctx->grip, &attrp, &attr_countp); if (err) return err; @@ -92,7 +94,7 @@ search_cb (void *hook, struct cert *cert) scute_gpgsm_search_certs_by_fpr (cert->chain_id, search_cb, ctx); /* Turn this certificate into a certificate object. */ - err = scute_attr_cert (cert, &attrp, &attr_countp); + err = scute_attr_cert (cert, ctx->grip, &attrp, &attr_countp); if (err) return err; @@ -123,12 +125,15 @@ scute_gpgsm_get_cert (char *grip, const char *certref, cert_get_cb_t cert_get_cb, void *hook) { gpg_error_t err; - struct search search; + struct search_cb_parm search; search.found = false; search.cert_get_cb = cert_get_cb; search.hook = hook; search.with_chain = false; + search.grip = grip; + + DEBUG (DBG_INFO, "scute_gpgsm_get_cert: certref='%s'", certref); /* If the cert is requested from the card, we try to get it from * the card as well. */ @@ -154,6 +159,7 @@ scute_gpgsm_get_cert (char *grip, const char *certref, } } + DEBUG (DBG_INFO, "scute_gpgsm_get_cert: falling back to gpgsm"); search.with_chain = true; err = scute_gpgsm_search_certs_by_grip (grip, search_cb, &search); return err; diff --git a/src/p11-gettokeninfo.c b/src/p11-gettokeninfo.c index 3a78598..4094f42 100644 --- a/src/p11-gettokeninfo.c +++ b/src/p11-gettokeninfo.c @@ -97,9 +97,9 @@ C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) else if (len == 0) pInfo->flags |= CKF_USER_PIN_LOCKED; - pInfo->ulMaxSessionCount = CK_UNAVAILABLE_INFORMATION; + pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE; pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION; - pInfo->ulMaxRwSessionCount = CK_UNAVAILABLE_INFORMATION; + pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE; pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION; slot_token_maxpinlen (slot, &pInfo->ulMaxPinLen, &pInfo->ulMinPinLen); diff --git a/src/p11-sign.c b/src/p11-sign.c index ceb262e..344bfd8 100644 --- a/src/p11-sign.c +++ b/src/p11-sign.c @@ -37,6 +37,18 @@ #include "slots.h" +/* Sign the data (PDATA,ULDATALEN) using the information recorded in + * the HSESSION by C_SignInit. PSIGNAURE is a buffer to receive the + * signature. The length of that buffer must be stored in a variable + * to which PULSIGNATURELEN points to; on success that length is + * updated to the actual length of the signature in PULSIGNATURE. + * + * If the function returns CKR_BUFFER_TOO_SMALL no further C_SignInit + * is required, instead the function can be called again with a larger + * buffer. On a successful operation CKR_OK is returned and other + * signatures may be created without an new C_SignInit. On all other + * return codes a new C_SignInit is required. + */ CK_RV CK_SPEC C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) @@ -56,11 +68,14 @@ C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, if (err) goto out; - /* FIXME: Who cares if they called sign init correctly. */ + /* FIXME: Check that C_SignInit has been called. */ + err = session_sign (slot, session, pData, ulDataLen, pSignature, pulSignatureLen); out: + /* FIXME: Update the flag which indicates whether C_SignInit has + * been called. */ scute_global_unlock (); return err; } diff --git a/src/p11-signinit.c b/src/p11-signinit.c index 560f37e..598d91d 100644 --- a/src/p11-signinit.c +++ b/src/p11-signinit.c @@ -36,7 +36,11 @@ #include "locking.h" #include "slots.h" - +/* Prepare a signature operation. HSESSION is the session's handle. + * PMECHANISM describes the mechanism to be used. HKEY describes the + * key to be used. After calling this function either C_Sign or + * (C_SignUpdate, C_SignFinal) can be used to actually sign the data. + * The preparation is valid until C_Sign or C_SignFinal. */ CK_RV CK_SPEC C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) diff --git a/src/settings.h b/src/settings.h index 40375c7..8f3f4c8 100644 --- a/src/settings.h +++ b/src/settings.h @@ -2,7 +2,7 @@ Copyright (C) 2006 g10 Code GmbH This file is part of Scute. - + Scute 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 @@ -37,14 +37,14 @@ /* The manufacturer ID in UTF-8. Only up to 32 bytes are used. */ #define MANUFACTURER_ID "g10 Code GmbH" -#define LIBRARY_DESCRIPTION "Cryptoki for SCDaemon" +#define LIBRARY_DESCRIPTION "Cryptoki for GnuPG" /* The version number of this library. Defined by config.h. */ #if (! defined VERSION_MAJOR) || (! defined VERSION_MINOR) #error Define VERSION_MAJOR and VERSION_MINOR in config.h. #endif -/* FIXME: The following should be queried from SCD, really. */ +/* FIXME: The following should be queried from GnuPG, really. */ #define SLOT_DESCRIPTION "GnuPG Smart Card Daemon" #define SLOT_MANUFACTURER_ID "g10 Code GmbH" #define SLOT_HARDWARE_VERSION_MAJOR 0 diff --git a/src/slots.c b/src/slots.c index 5dfc94a..1e9b1a6 100644 --- a/src/slots.c +++ b/src/slots.c @@ -167,7 +167,7 @@ mechanism_alloc (void **data_r, void *hook) /* Set some default values. */ mechanism->type = CKM_RSA_PKCS; mechanism->info.ulMinKeySize = 1024; - mechanism->info.ulMaxKeySize = 1024; + mechanism->info.ulMaxKeySize = 4096; mechanism->info.flags = CKF_HW | (*flags); *data_r = mechanism; @@ -384,16 +384,20 @@ slot_init (slot_iterator_t id) { gpg_error_t err = 0; struct slot *slot = scute_table_data (slots, id); + key_info_t ki; - err = scute_gpgsm_get_cert (slot->info.grip3, "OPENPGP.3", add_object, slot); - if (err) - goto init_out; + for (ki = slot->info.kinfo; ki; ki = ki->next) + { + err = scute_gpgsm_get_cert (ki->grip, ki->keyref, add_object, slot); + if (err) + goto leave; + } /* FIXME: Perform the rest of the initialization of the token. */ slot->token_present = true; - init_out: + leave: if (err) slot_reset (id); @@ -1027,6 +1031,7 @@ session_set_signing_key (slot_iterator_t id, session_iterator_t sid, if (err) return err; + /* FIXME: What kind of strange loop is this? */ while (attr_count-- > 0) if (attr->type == CKA_CLASS) break; @@ -1045,7 +1050,7 @@ session_set_signing_key (slot_iterator_t id, session_iterator_t sid, } -/* FIXME: The dscription is wrong: +/* FIXME: The description is wrong: Set the signing key for session SID in slot ID to KEY. */ CK_RV session_sign (slot_iterator_t id, session_iterator_t sid, @@ -1053,27 +1058,57 @@ session_sign (slot_iterator_t id, session_iterator_t sid, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { struct slot *slot = scute_table_data (slots, id); + struct session *session = scute_table_data (slot->sessions, sid); gpg_error_t err; + CK_ATTRIBUTE_PTR attr; + CK_ULONG attr_count; + CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY; unsigned int sig_len; + CK_BYTE key_id[100]; + int i; + const char *keyref; - /* FIXME: Who cares if they called sign init correctly. Should - check the signing_key object. */ + if (!pSignature) + return CKR_ARGUMENTS_BAD; - if (pSignature == NULL_PTR) - { - err = scute_agent_sign (NULL, NULL, 0, NULL, &sig_len); - if (err) - return scute_gpg_err_to_ck (err); - *pulSignatureLen = sig_len; - return 0; - } + if (!session->signing_key) + return CKR_OPERATION_NOT_INITIALIZED; + + err = slot_get_object (id, session->signing_key, &attr, &attr_count); + if (err) + return err; + if (attr_count == (CK_ULONG) -1) + return CKR_KEY_HANDLE_INVALID; + if (attr->ulValueLen != sizeof (key_class) + || memcmp (attr->pValue, &key_class, sizeof (key_class))) + return CKR_KEY_HANDLE_INVALID; + + /* Find the CKA_ID */ + for (i = 0; i < attr_count; i++) + if (attr[i].type == CKA_ID) + break; + if (i == attr_count) + return CKR_GENERAL_ERROR; + + if (attr[i].ulValueLen >= sizeof key_id - 1) + return CKR_GENERAL_ERROR; + strncpy (key_id, attr[i].pValue, attr[i].ulValueLen); + key_id[attr[i].ulValueLen] = 0; + DEBUG (DBG_INFO, "Found CKA_ID '%s'", key_id); + for (keyref=key_id; *keyref && *keyref != ' '; keyref++) + ; + if (*keyref) + keyref++; /* Point to the grip. */ + DEBUG (DBG_INFO, "Using keyref '%s'", keyref); sig_len = *pulSignatureLen; - err = scute_agent_sign (slot->info.grip3, pData, ulDataLen, - pSignature, &sig_len); - /* FIXME: Oh well. */ - if (gpg_err_code (err) == GPG_ERR_INV_ARG) - return CKR_BUFFER_TOO_SMALL; + err = scute_agent_sign (keyref, pData, ulDataLen, pSignature, &sig_len); - return scute_gpg_err_to_ck (err); + /* Take care of error codes which are not mapped by default. */ + if (gpg_err_code (err) == GPG_ERR_INV_LENGTH) + return CKR_BUFFER_TOO_SMALL; + else if (gpg_err_code (err) == GPG_ERR_INV_ARG) + return CKR_ARGUMENTS_BAD; + else + return scute_gpg_err_to_ck (err); } diff --git a/tests/t-auth.c b/tests/t-auth.c index 53c23ed..ba69ccd 100644 --- a/tests/t-auth.c +++ b/tests/t-auth.c @@ -2,7 +2,7 @@ Copyright (C) 2006 g10 Code GmbH This file is part of Scute. - + Scute 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 @@ -128,7 +128,7 @@ main (int argc, char *argv[]) err = C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL, &session); fail_if_err (err); - + printf (" Session ID: %lu\n", session); err = C_FindObjectsInit (session, attr, DIM (attr)); diff --git a/tests/t-getattribute.c b/tests/t-getattribute.c index a2be7c0..982aaae 100644 --- a/tests/t-getattribute.c +++ b/tests/t-getattribute.c @@ -85,6 +85,35 @@ dump_one (CK_ATTRIBUTE_PTR attr, unsigned char *data, unsigned int max_size) CK_RV +dump_one_string (CK_ATTRIBUTE_PTR attr, + unsigned char *data, unsigned int max_size) +{ + unsigned int i; + int blanks = 0; + + if (attr->ulValueLen > max_size) + { + putc ('\n', stdout); + return CKR_GENERAL_ERROR; + } + for (i = 0; i < attr->ulValueLen; i++) + { + if (data[i] == ' ') + { + blanks++; + continue; + } + for (; blanks; blanks--) + putc (' ', stdout); + putc (data[i], stdout); + } + putc ('\n', stdout); + + return 0; +} + + +CK_RV dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) { CK_RV err; @@ -186,9 +215,8 @@ dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) printf (" Certificate Modifiable: %s\n", cert_modifiable ? "true" : "false"); - printf (" Certificate Label: Length %lu\n", - cert_attr[4].ulValueLen); - err = dump_one (&cert_attr[4], cert_label, sizeof (cert_label)); + printf (" Certificate Label: "); + err = dump_one_string (&cert_attr[4], cert_label, sizeof (cert_label)); fail_if_err (err); fail_if_err ((cert_attr[5].ulValueLen != sizeof (cert_trusted)) ? @@ -246,9 +274,8 @@ dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) err = dump_one (&cert_attr[10], cert_subject, sizeof (cert_subject)); fail_if_err (err); - printf (" Certificate ID: Length %lu\n", - cert_attr[11].ulValueLen); - err = dump_one (&cert_attr[11], cert_id, sizeof (cert_id)); + printf (" Certificate ID: "); + err = dump_one_string (&cert_attr[11], cert_id, sizeof (cert_id)); fail_if_err (err); printf (" Certificate Issuer: Length %lu\n", @@ -405,14 +432,12 @@ dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) printf (" Key Modifiable: %s\n", key_modifiable ? "true" : "false"); - printf (" Key Label: Length %lu\n", - key_attr[4].ulValueLen); - err = dump_one (&key_attr[4], key_label, sizeof (key_label)); + printf (" Key Label: "); + err = dump_one_string (&key_attr[4], key_label, sizeof (key_label)); fail_if_err (err); - printf (" Key ID: Length %lu\n", - key_attr[5].ulValueLen); - err = dump_one (&key_attr[5], key_id, sizeof (key_id)); + printf (" Key ID: "); + err = dump_one_string (&key_attr[5], key_id, sizeof (key_id)); fail_if_err (err); if (key_attr[6].ulValueLen && key_attr[7].ulValueLen) diff --git a/tests/t-getinfo.c b/tests/t-getinfo.c index b90f132..f246254 100644 --- a/tests/t-getinfo.c +++ b/tests/t-getinfo.c @@ -2,7 +2,7 @@ Copyright (C) 2006 g10 Code GmbH This file is part of Scute. - + Scute 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 @@ -46,7 +46,7 @@ main (int argc, char *argv[]) err = C_GetInfo (&info); fail_if_err (err); - printf ("Cryptoki version: %i.%i\n", info.cryptokiVersion.major, + printf ("Cryptoki version: %i.%i\n", info.cryptokiVersion.major, info.cryptokiVersion.minor); if (info.cryptokiVersion.major != 2) fail ("Cryptoki major version is not 2"); @@ -59,8 +59,8 @@ main (int argc, char *argv[]) fail ("Flags is not 0"); printf ("Library description: %.32s\n", info.libraryDescription); - printf ("Library version: %i.%i\n", info.cryptokiVersion.major, - info.cryptokiVersion.minor); + printf ("Library version: %i.%i\n", info.libraryVersion.major, + info.libraryVersion.minor); return 0; } ----------------------------------------------------------------------- Summary of changes: configure.ac | 10 +++--- src/agent.c | 39 ++++++++---------------- src/agent.h | 16 +++------- src/cert-object.c | 82 +++++++++++++++++++++++++------------------------- src/cert.h | 14 ++++++--- src/gpgsm.c | 16 +++++++--- src/p11-gettokeninfo.c | 4 +-- src/p11-sign.c | 17 ++++++++++- src/p11-signinit.c | 6 +++- src/settings.h | 6 ++-- src/slots.c | 79 ++++++++++++++++++++++++++++++++++-------------- tests/t-auth.c | 4 +-- tests/t-getattribute.c | 49 ++++++++++++++++++++++-------- tests/t-getinfo.c | 8 ++--- 14 files changed, 210 insertions(+), 140 deletions(-) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 15 03:01:32 2019 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat via Gnupg-devel) Date: Fri, 15 Feb 2019 03:01:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-373-g74e9b57 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 74e9b579ca273fc07be090bb5fb7800a97b1b452 (commit) from b89f1790e0b9f3196a2382a9b9ff5f461c58a449 (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 74e9b579ca273fc07be090bb5fb7800a97b1b452 Author: Damien Goutte-Gattat via Gnupg-devel Date: Fri Nov 16 01:27:37 2018 +0000 sm: Support generation of card-based ECDSA CSR. * sm/call-agent.c (gpgsm_scd_pksign): Identify type of signing key and format resulting S-expression accordingly. * sm/misc.c (transform_sigval): Support ECDSA signatures. -- Current GpgSM implementation assumes card-based keys are RSA keys. This patch introduces support for ECDSA keys. By itself this patch is not sufficient, we also need support from libksba. GnuPG-bug-id: 4092 Signed-off-by: Damien Goutte-Gattat diff --git a/sm/call-agent.c b/sm/call-agent.c index 20d879f..6ac715f 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -334,7 +334,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, unsigned char *digest, size_t digestlen, int digestalgo, unsigned char **r_buf, size_t *r_buflen ) { - int rc, i; + int rc, i, pkalgo; char *p, line[ASSUAN_LINELENGTH]; membuf_t data; size_t len; @@ -342,6 +342,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, unsigned char *sigbuf; size_t sigbuflen; struct default_inq_parm_s inq_parm; + gcry_sexp_t sig; (void)desc; @@ -366,6 +367,23 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, if (digestlen*2 + 50 > DIM(line)) return gpg_error (GPG_ERR_GENERAL); + /* Get the key type from the scdaemon. */ + snprintf (line, DIM(line), "SCD READKEY %s", keyid); + init_membuf (&data, 1024); + rc = assuan_transact (agent_ctx, line, + put_membuf_cb, &data, NULL, NULL, NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return rc; + } + + p = get_membuf (&data, &len); + pkalgo = get_pk_algo_from_canon_sexp (p, len); + xfree (p); + if (!pkalgo) + return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + p = stpcpy (line, "SCD SETDATA " ); for (i=0; i < digestlen ; i++, p += 2 ) sprintf (p, "%02X", digest[i]); @@ -386,24 +404,31 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, } sigbuf = get_membuf (&data, &sigbuflen); - /* Create an S-expression from it which is formatted like this: - "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" Fixme: If a card ever - creates non-RSA keys we need to change things. */ - *r_buflen = 21 + 11 + sigbuflen + 4; - p = xtrymalloc (*r_buflen); - *r_buf = (unsigned char*)p; - if (!p) + switch(pkalgo) { - xfree (sigbuf); - return 0; + case GCRY_PK_RSA: + rc = gcry_sexp_build (&sig, NULL, "(sig-val(rsa(s%b)))", + sigbuflen, sigbuf); + break; + + case GCRY_PK_ECC: + rc = gcry_sexp_build (&sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))", + sigbuflen/2, sigbuf, + sigbuflen/2, sigbuf + sigbuflen/2); + break; + + default: + rc = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + break; } - p = stpcpy (p, "(7:sig-val(3:rsa(1:s" ); - sprintf (p, "%u:", (unsigned int)sigbuflen); - p += strlen (p); - memcpy (p, sigbuf, sigbuflen); - p += sigbuflen; - strcpy (p, ")))"); xfree (sigbuf); + if (rc) + return rc; + + rc = make_canon_sexp (sig, r_buf, r_buflen); + gcry_sexp_release (sig); + if (rc) + return rc; assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL)); return 0; diff --git a/sm/misc.c b/sm/misc.c index 6d04776..9bf5285 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -109,13 +109,16 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, gpg_error_t err; const unsigned char *buf, *tok; size_t buflen, toklen; - int depth, last_depth1, last_depth2; + int depth, last_depth1, last_depth2, pkalgo; int is_pubkey = 0; - const unsigned char *rsa_s = NULL; - size_t rsa_s_len = 0; + const unsigned char *rsa_s, *ecc_r, *ecc_s; + size_t rsa_s_len, ecc_r_len, ecc_s_len; const char *oid; gcry_sexp_t sexp; + rsa_s = ecc_r = ecc_s = NULL; + rsa_s_len = ecc_r_len = ecc_s_len = 0; + *r_newsigval = NULL; if (r_newsigvallen) *r_newsigvallen = 0; @@ -137,7 +140,13 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, return err; if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) return err; - if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen)) + if (!tok) + return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + if (toklen == 3 && !memcmp ("rsa", tok, 3)) + pkalgo = GCRY_PK_RSA; + else if (toklen == 5 && !memcmp ("ecdsa", tok, 5)) + pkalgo = GCRY_PK_ECC; + else return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); last_depth1 = depth; @@ -150,16 +159,27 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, return err; if (tok && toklen == 1) { - const unsigned char **mpi; - size_t *mpi_len; + const unsigned char **mpi = NULL; + size_t *mpi_len = NULL; switch (*tok) { - case 's': mpi = &rsa_s; mpi_len = &rsa_s_len; break; + case 's': + if (pkalgo == GCRY_PK_RSA) + { + mpi = &rsa_s; + mpi_len = &rsa_s_len; + } + else if (pkalgo == GCRY_PK_ECC) + { + mpi = &ecc_s; + mpi_len = &ecc_s_len; + } + break; + + case 'r': mpi = &ecc_r; mpi_len = &ecc_r_len; break; default: mpi = NULL; mpi_len = NULL; break; } - if (mpi && *mpi) - return gpg_error (GPG_ERR_DUP_VALUE); if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) return err; @@ -182,33 +202,52 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, return err; /* Map the hash algorithm to an OID. */ - switch (mdalgo) + switch (mdalgo | (pkalgo << 8)) { - case GCRY_MD_SHA1: + case GCRY_MD_SHA1 | (GCRY_PK_RSA << 8): oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */ break; - case GCRY_MD_SHA256: + case GCRY_MD_SHA256 | (GCRY_PK_RSA << 8): oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */ break; - case GCRY_MD_SHA384: + case GCRY_MD_SHA384 | (GCRY_PK_RSA << 8): oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */ break; - case GCRY_MD_SHA512: + case GCRY_MD_SHA512 | (GCRY_PK_RSA << 8): oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */ break; + case GCRY_MD_SHA224 | (GCRY_PK_ECC << 8): + oid = "1.2.840.10045.4.3.1"; /* ecdsa-with-sha224 */ + break; + + case GCRY_MD_SHA256 | (GCRY_PK_ECC << 8): + oid = "1.2.840.10045.4.3.2"; /* ecdsa-with-sha256 */ + break; + + case GCRY_MD_SHA384 | (GCRY_PK_ECC << 8): + oid = "1.2.840.10045.4.3.3"; /* ecdsa-with-sha384 */ + break; + + case GCRY_MD_SHA512 | (GCRY_PK_ECC << 8): + oid = "1.2.840.10045.4.3.4"; /* ecdsa-with-sha512 */ + break; + default: return gpg_error (GPG_ERR_DIGEST_ALGO); } - if (rsa_s && !is_pubkey) - err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", - oid, (int)rsa_s_len, rsa_s); - else + if (is_pubkey) err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid); + else if (pkalgo == GCRY_PK_RSA) + err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", oid, + (int)rsa_s_len, rsa_s); + else if (pkalgo == GCRY_PK_ECC) + err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(r%b)(s%b)))", oid, + (int)ecc_r_len, ecc_r, (int)ecc_s_len, ecc_s); if (err) return err; err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen); ----------------------------------------------------------------------- Summary of changes: sm/call-agent.c | 57 +++++++++++++++++++++++++++++++------------ sm/misc.c | 75 +++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 98 insertions(+), 34 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 16 11:34:36 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 16 Feb 2019 11:34:36 +0100 Subject: [git] gnupg-doc - branch, master, updated. 30d12db3aee612611976cf4a3f567fc0d6d3d4ec 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 30d12db3aee612611976cf4a3f567fc0d6d3d4ec (commit) from 9f4400dfc8fe39cd6d0fc5b0ff323f52e985e788 (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 30d12db3aee612611976cf4a3f567fc0d6d3d4ec Author: Werner Koch Date: Sat Feb 16 11:34:32 2019 +0100 web: Yet another c+p fix. diff --git a/web/index.org b/web/index.org index 74a3039..f566962 100644 --- a/web/index.org +++ b/web/index.org @@ -66,7 +66,7 @@ The latest release news:\\ ** GnuPG 2.2.13 released (2019-02-12) -We are pleased to announce the availability of GnuPG version 2.2.12. +We are pleased to announce the availability of GnuPG version 2.2.13. This is a maintenance release fixing a few problems and adding some minor features. {[[https://lists.gnupg.org/pipermail/gnupg-announce/2019q1/000434.html][more]]} ----------------------------------------------------------------------- Summary of changes: web/index.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 Feb 17 21:44:53 2019 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sun, 17 Feb 2019 21:44:53 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-152-gd455068 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 d455068988e5779b0200c51415ddab6b51e12dc4 (commit) from afab94d222425ecb838eb56cb0723bdaf3e5de36 (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 d455068988e5779b0200c51415ddab6b51e12dc4 Author: Jussi Kivilinna Date: Thu Feb 7 20:50:02 2019 +0200 Add 2-way path for SSSE3 version of ChaCha20 * cipher/chacha20-amd64-ssse3.S (_gcry_chacha20_amd64_ssse3_blocks1) (_gcry_chacha20_poly1305_amd64_ssse3_blocks1): Add 2-way code paths. * cipher/chacha20.c (_gcry_chacha20_poly1305_encrypt): Add preprosessing of 2 blocks with SSSE3. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/chacha20-amd64-ssse3.S b/cipher/chacha20-amd64-ssse3.S index d7faf64..1657f77 100644 --- a/cipher/chacha20-amd64-ssse3.S +++ b/cipher/chacha20-amd64-ssse3.S @@ -334,7 +334,7 @@ ELF(.size _gcry_chacha20_amd64_ssse3_blocks4, .-_gcry_chacha20_amd64_ssse3_blocks4;) /********************************************************************** - 1-way chacha20 + 2-way && 1-way chacha20 **********************************************************************/ #define ROTATE_SHUF(v1,shuf) \ @@ -384,6 +384,66 @@ _gcry_chacha20_amd64_ssse3_blocks1: movdqu (8 * 4)(INPUT), X12; movdqu (12 * 4)(INPUT), X13; + cmp $2, NBLKS; + jb .Loop1; + + mov $20, ROUND; + + movdqa X10, X0; + movdqa X11, X1; + movdqa X12, X2; + movdqa X13, X3; + + movdqa X10, X8; + movdqa X11, X9; + movdqa X12, X14; + movdqa X13, X15; + paddq X4, X15; + +.Lround2_2: + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + sub $2, ROUND; + jnz .Lround2_2; + + PLUS(X0, X10); + PLUS(X1, X11); + PLUS(X2, X12); + PLUS(X3, X13); + + /* Update counter */ + paddq X4, X13; + + PLUS(X8, X10); + PLUS(X9, X11); + PLUS(X14, X12); + PLUS(X15, X13); + + /* Update counter */ + paddq X4, X13; + + xor_src_dst(DST, SRC, 0 * 4, X0, X7); + xor_src_dst(DST, SRC, 4 * 4, X1, X7); + xor_src_dst(DST, SRC, 8 * 4, X2, X7); + xor_src_dst(DST, SRC, 12 * 4, X3, X7); + xor_src_dst(DST, SRC, 16 * 4, X8, X7); + xor_src_dst(DST, SRC, 20 * 4, X9, X7); + xor_src_dst(DST, SRC, 24 * 4, X14, X7); + xor_src_dst(DST, SRC, 28 * 4, X15, X7); + + lea (2 * 64)(DST), DST; + lea (2 * 64)(SRC), SRC; + + clear(X8); + clear(X9); + clear(X14); + clear(X15); + + sub $2, NBLKS; + jz .Ldone1; + .Loop1: mov $20, ROUND; @@ -417,6 +477,7 @@ _gcry_chacha20_amd64_ssse3_blocks1: sub $1, NBLKS; jnz .Loop1; +.Ldone1: /* Store counter */ movdqu X13, (12 * 4)(INPUT); @@ -848,7 +909,7 @@ ELF(.size _gcry_chacha20_poly1305_amd64_ssse3_blocks4, .-_gcry_chacha20_poly1305_amd64_ssse3_blocks4;) /********************************************************************** - 1-way stitched chacha20-poly1305 + 2-way && 1-way stitched chacha20-poly1305 **********************************************************************/ .align 8 @@ -891,6 +952,153 @@ _gcry_chacha20_poly1305_amd64_ssse3_blocks1: POLY1305_LOAD_STATE(); + cmpq $2, (7 * 8)(%rsp); #NBLKS + jb .Loop_poly1; + + movdqa X10, X0; + movdqa X11, X1; + movdqa X12, X2; + movdqa X13, X3; + + movdqa X10, X8; + movdqa X11, X9; + movdqa X12, X14; + movdqa X13, X15; + paddq X4, X15; + + /* Process two ChaCha20 blocks and eight Poly1305 blocks. */ + + POLY1305_BLOCK_PART1(0 * 16); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART1(1 * 16); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART1(2 * 16); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART1(3 * 16); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART1(4 * 16); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART1(5 * 16); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART1(6 * 16); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART1(7 * 16); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + POLY1305_BLOCK_PART2(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART3(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x39, 0x4e, 0x93); + POLY1305_BLOCK_PART4(); + QUARTERROUND4(X0, X1, X2, X3, X5, X6, X7, 0x93, 0x4e, 0x39); + POLY1305_BLOCK_PART5(); + QUARTERROUND4(X8, X9, X14, X15, X5, X6, X7, 0x93, 0x4e, 0x39); + + movq (5 * 8)(%rsp), SRC; + movq (6 * 8)(%rsp), DST; + + PLUS(X0, X10); + PLUS(X1, X11); + PLUS(X2, X12); + PLUS(X3, X13); + + /* Update counter */ + paddq X4, X13; + + PLUS(X8, X10); + PLUS(X9, X11); + PLUS(X14, X12); + PLUS(X15, X13); + + /* Update counter */ + paddq X4, X13; + + xor_src_dst(DST, SRC, 0 * 4, X0, X7); + xor_src_dst(DST, SRC, 4 * 4, X1, X7); + xor_src_dst(DST, SRC, 8 * 4, X2, X7); + xor_src_dst(DST, SRC, 12 * 4, X3, X7); + xor_src_dst(DST, SRC, 16 * 4, X8, X7); + xor_src_dst(DST, SRC, 20 * 4, X9, X7); + xor_src_dst(DST, SRC, 24 * 4, X14, X7); + xor_src_dst(DST, SRC, 28 * 4, X15, X7); + + clear(X8); + clear(X9); + clear(X14); + clear(X15); + + subq $2, (7 * 8)(%rsp); # NBLKS + lea (2 * 64)(POLY_RSRC), POLY_RSRC; + lea (2 * 64)(SRC), SRC; + lea (2 * 64)(DST), DST; + movq SRC, (5 * 8)(%rsp); + movq DST, (6 * 8)(%rsp); + jz .Ldone_poly1; + .Loop_poly1: movdqa X10, X0; movdqa X11, X1; @@ -973,6 +1181,7 @@ _gcry_chacha20_poly1305_amd64_ssse3_blocks1: jnz .Loop_poly1; +.Ldone_poly1: /* Store state */ POLY1305_STORE_STATE(); diff --git a/cipher/chacha20.c b/cipher/chacha20.c index 3e6327d..eae4979 100644 --- a/cipher/chacha20.c +++ b/cipher/chacha20.c @@ -611,6 +611,16 @@ _gcry_chacha20_poly1305_encrypt(gcry_cipher_hd_t c, byte *outbuf, outbuf += 4 * CHACHA20_BLOCK_SIZE; inbuf += 4 * CHACHA20_BLOCK_SIZE; } + else if (ctx->use_ssse3 && length >= CHACHA20_BLOCK_SIZE * 2) + { + nburn = _gcry_chacha20_amd64_ssse3_blocks1(ctx->input, outbuf, inbuf, 2); + burn = nburn > burn ? nburn : burn; + + authptr = outbuf; + length -= 2 * CHACHA20_BLOCK_SIZE; + outbuf += 2 * CHACHA20_BLOCK_SIZE; + inbuf += 2 * CHACHA20_BLOCK_SIZE; + } else if (ctx->use_ssse3 && length >= CHACHA20_BLOCK_SIZE) { nburn = _gcry_chacha20_amd64_ssse3_blocks1(ctx->input, outbuf, inbuf, 1); ----------------------------------------------------------------------- Summary of changes: cipher/chacha20-amd64-ssse3.S | 213 +++++++++++++++++++++++++++++++++++++++++- cipher/chacha20.c | 10 ++ 2 files changed, 221 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 18 03:34:23 2019 From: cvs at cvs.gnupg.org (by Damien Goutte-Gattat via Gnupg-devel) Date: Mon, 18 Feb 2019 03:34:23 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-374-g3cbdf89 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 3cbdf896e6919333b5423001ab58c01a04363386 (commit) from 74e9b579ca273fc07be090bb5fb7800a97b1b452 (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 3cbdf896e6919333b5423001ab58c01a04363386 Author: Damien Goutte-Gattat via Gnupg-devel Date: Sun Feb 17 17:40:51 2019 +0000 sm: Support generation of card-based ed25519 CSR. * sm/call-agent.c (gpgsm_scd_pksign): Allow SHA512. Create proper S-expression for EdDSA signature. * sm/certreqgen.c (create_request): Force use of SHA512 when using a ed25519 key. * sm/misc.c (transform_sigval): Insert OID for ed25519. -- GnuPG-bug-id: 4013 Signed-off-by: Damien Goutte-Gattat diff --git a/sm/call-agent.c b/sm/call-agent.c index 6ac715f..4f2b83f 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -354,6 +354,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, case GCRY_MD_RMD160:hashopt = "--hash=rmd160"; break; case GCRY_MD_MD5: hashopt = "--hash=md5"; break; case GCRY_MD_SHA256:hashopt = "--hash=sha256"; break; + case GCRY_MD_SHA512:hashopt = "--hash=sha512"; break; default: return gpg_error (GPG_ERR_DIGEST_ALGO); } @@ -417,6 +418,12 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc, sigbuflen/2, sigbuf + sigbuflen/2); break; + case GCRY_PK_EDDSA: + rc = gcry_sexp_build (&sig, NULL, "(sig-val(eddsa(r%b)(s%b)))", + sigbuflen/2, sigbuf, + sigbuflen/2, sigbuf + sigbuflen/2); + break; + default: rc = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); break; diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 1d610c1..01fba30 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -807,8 +807,10 @@ create_request (ctrl_t ctrl, if (err) return err; - string = get_parameter_value (para, pHASHALGO, 0); - if (string) + len = gcry_sexp_canon_len (public, 0, NULL, NULL); + if (get_pk_algo_from_canon_sexp (public, len) == GCRY_PK_EDDSA) + mdalgo = GCRY_MD_SHA512; + else if ((string = get_parameter_value (para, pHASHALGO, 0))) mdalgo = gcry_md_map_name (string); else mdalgo = GCRY_MD_SHA256; diff --git a/sm/misc.c b/sm/misc.c index 9bf5285..4672f26 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -146,6 +146,8 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, pkalgo = GCRY_PK_RSA; else if (toklen == 5 && !memcmp ("ecdsa", tok, 5)) pkalgo = GCRY_PK_ECC; + else if (toklen == 5 && !memcmp ("eddsa", tok, 5)) + pkalgo = GCRY_PK_EDDSA; else return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); @@ -170,7 +172,7 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, mpi = &rsa_s; mpi_len = &rsa_s_len; } - else if (pkalgo == GCRY_PK_ECC) + else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA) { mpi = &ecc_s; mpi_len = &ecc_s_len; @@ -236,6 +238,10 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, oid = "1.2.840.10045.4.3.4"; /* ecdsa-with-sha512 */ break; + case GCRY_MD_SHA512 | (GCRY_PK_EDDSA << 8): + oid = "1.3.101.112"; /* ed25519 */ + break; + default: return gpg_error (GPG_ERR_DIGEST_ALGO); } @@ -245,7 +251,7 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, else if (pkalgo == GCRY_PK_RSA) err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", oid, (int)rsa_s_len, rsa_s); - else if (pkalgo == GCRY_PK_ECC) + else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA) err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(r%b)(s%b)))", oid, (int)ecc_r_len, ecc_r, (int)ecc_s_len, ecc_s); if (err) ----------------------------------------------------------------------- Summary of changes: sm/call-agent.c | 7 +++++++ sm/certreqgen.c | 6 ++++-- sm/misc.c | 10 ++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 18 12:05:18 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Feb 2019 12:05:18 +0100 Subject: [git] Scute - branch, master, updated. scute-1.5.0-11-gd981ad1 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 "PKCS#11 token on top of gpg-agent". The branch, master has been updated via d981ad1ed18d5e7d7b63ecf256348a509cc4eb59 (commit) from ff9e757e352f1b4cf3b4625eb4398415051367af (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 d981ad1ed18d5e7d7b63ecf256348a509cc4eb59 Author: Werner Koch Date: Mon Feb 18 12:03:51 2019 +0100 Let gpgsm do the actual key selection work. * src/agent.c (scute_agent_is_trusted): Make FPR arg const. * src/cert.h (enum keylist_modes): new. * src/cert-gpgsm.c (scute_gpgsm_search_certs_by_fpr): Remove. (scute_gpgsm_search_certs_by_grip): Rename to ... (scute_gpgsm_search_certs): this. Remove the same named old fucntion. Change args and rewrite. (export_cert_compat): Remove. (export_cert): Make FPR arg const. Remove trailing LF from assuna command. (search_certs): Rename to keylist_cb. Fold the double callbacks into just one. (MAX_LINE_LEN): Define based on ASSUAN_LINELENGTH. -- This patch cleans up a lot of cruft and also replaces the Scute internal selection of keys by simply asking gpgsm to only return the requested keys. This speeds up things a lot. Signed-off-by: Werner Koch diff --git a/src/agent.c b/src/agent.c index 4fe969b..706fdf3 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1036,7 +1036,7 @@ scute_agent_sign (const char *hexgrip, unsigned char *data, int len, /* Determine if FPR is trusted. */ gpg_error_t -scute_agent_is_trusted (char *fpr, bool *is_trusted) +scute_agent_is_trusted (const char *fpr, bool *is_trusted) { gpg_error_t err; bool trusted = false; diff --git a/src/agent.h b/src/agent.h index 367b7e2..0b75f14 100644 --- a/src/agent.h +++ b/src/agent.h @@ -132,7 +132,7 @@ gpg_error_t scute_agent_sign (const char *hexgrip, unsigned char *sig_result, unsigned int *sig_len); /* Determine if FPR is trusted. */ -gpg_error_t scute_agent_is_trusted (char *fpr, bool *is_trusted); +gpg_error_t scute_agent_is_trusted (const char *fpr, bool *is_trusted); /* Try to get certificate for key numer NO. */ gpg_error_t scute_agent_get_cert (const char *certref, struct cert *cert); diff --git a/src/cert-gpgsm.c b/src/cert-gpgsm.c index c982b75..14a675a 100644 --- a/src/cert-gpgsm.c +++ b/src/cert-gpgsm.c @@ -2,7 +2,7 @@ Copyright (C) 2006, 2007 g10 Code GmbH This file is part of Scute. - + Scute 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 @@ -45,33 +45,39 @@ #include "support.h" #include "debug.h" - -#ifndef HAVE_W32_SYSTEM -#define COMPAT_FALLBACK -#endif - /* The maximum length of a key listing line. We take the double of - the allowed Assuan line length to avoid a memmove after a part of a - line has been processed. FIXME: There is actually no limit on the - length of the line. */ -#define MAX_LINE_LEN (1024*2) + * the allowed Assuan line length plus some extra space to avoid a + * memmove after a part of a line has been processed. */ +#define MAX_LINE_LEN (ASSUAN_LINELENGTH*2 + 200) -struct search_ctx +struct keylist_ctx { /* The pending line in an active key listing. */ char pending[MAX_LINE_LEN + 1]; unsigned int pending_len; + /* The current certificate. */ + struct cert cert; + /* The caller's search callback, invoked for each certificate. */ cert_search_cb_t search_cb; void *search_cb_hook; - - /* The current certificate. */ - struct cert cert; }; +/* Support macros */ +#define atoi_1(p) (*(p) - '0' ) +#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) +#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) + + +/*** Local prototypes ***/ +static gpg_error_t export_cert (const char *fpr, struct cert *cert); + + + + /* Release allocated storage for the certificate CERT and reset the certificate. */ static void @@ -89,12 +95,6 @@ cert_reset (struct cert *cert) memset (cert, '\0', sizeof (struct cert)); } - -/* Support routines for key list processing. */ - -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) /* Parse the string TIMESTAMP into a time_t. The string may either be seconds since Epoch or in the ISO 8601 format like @@ -127,7 +127,7 @@ parse_timestamp (const char *timestamp, char **endp) memset (&buf, 0, sizeof buf); buf.tm_year = year - 1900; - buf.tm_mon = atoi_2 (timestamp+4) - 1; + buf.tm_mon = atoi_2 (timestamp+4) - 1; buf.tm_mday = atoi_2 (timestamp+6); buf.tm_hour = atoi_2 (timestamp+9); buf.tm_min = atoi_2 (timestamp+11); @@ -229,9 +229,9 @@ decode_c_string (const char *src, char **destp, size_t len) /* A binary zero is not representable in a C string. */ *(dest++) = '\\'; - *(dest++) = '0'; + *(dest++) = '0'; } - else + else *((unsigned char *) dest++) = val; src += 4; } @@ -244,28 +244,19 @@ decode_c_string (const char *src, char **destp, size_t len) *(dest++) = *(src++); *(dest++) = *(src++); } - } + } } *(dest++) = 0; return 0; } - -/* The cert handler for certificate searches. This is invoked for - each complete certificate found by search_certs_line, and the last - pending certificate when EOF is encountered by search_certs. */ -static gpg_error_t -search_certs_cert (struct search_ctx *ctx) -{ - return (*ctx->search_cb) (ctx->search_cb_hook, &ctx->cert); -} - -/* The line handler for certificate searches. This is invoked for - each complete line found by search_certs. */ + +/* Helper for keylist_cb. This fucntion is invoked for each complete + * line assembled by keylist_cb. */ static gpg_error_t -search_certs_line (struct search_ctx *ctx) +keylist_cb_line (struct keylist_ctx *ctx) { char *line; enum { RT_NONE, RT_CRT, RT_CRS, RT_FPR, RT_GRP, RT_UID } rectype = RT_NONE; @@ -301,7 +292,7 @@ search_certs_line (struct search_ctx *ctx) rectype = RT_GRP; else if (!strcmp (field[0], "uid")) rectype = RT_UID; - else + else rectype = RT_NONE; switch (rectype) @@ -313,8 +304,11 @@ search_certs_line (struct search_ctx *ctx) { gpg_error_t err; - err = search_certs_cert (ctx); - if (err) + /* Return the cert. */ + err = export_cert (ctx->cert.fpr, &ctx->cert); + if (!err) + err = ctx->search_cb (ctx->search_cb_hook, &ctx->cert); + if (err) return err; cert_reset (cert); @@ -334,7 +328,7 @@ search_certs_line (struct search_ctx *ctx) int i = atoi (field[2]); /* Ignore invalid values. */ if (i > 1) - cert->length = i; + cert->length = i; } /* Field 4 has the public key algorithm. */ @@ -433,13 +427,13 @@ search_certs_line (struct search_ctx *ctx) /* This is the data line callback handler provided to assuan_transact - in scute_gpgsm_search_certs. It buffers incomplete lines, and also - handles the EOF signal provided directly by - scute_gpgsm_search_certs. */ + * in scute_gpgsm_search_certs_by_{grip,fpr}. It buffers incomplete + * lines, and is also used to handle the EOF signal directly outside + * of assuan_transact. */ static gpg_error_t -search_certs (void *hook, const void *line_data, size_t line_len) +keylist_cb (void *hook, const void *line_data, size_t line_len) { - struct search_ctx *ctx = hook; + struct keylist_ctx *ctx = hook; const char *line = line_data; gpg_error_t err; @@ -451,23 +445,29 @@ search_certs (void *hook, const void *line_data, size_t line_len) newline. */ if (ctx->pending_len) { - err = search_certs_line (ctx); + err = keylist_cb_line (ctx); if (err) return err; } - /* Check for a pending certificate. */ + /* Check for a pending certificate and return it. */ if (ctx->cert.valid) - return search_certs_cert (ctx); + { + err = export_cert (ctx->cert.fpr, &ctx->cert); + if (!err) + err = ctx->search_cb (ctx->search_cb_hook, &ctx->cert); + } + else + err = 0; - return 0; + return err; } while (line_len) { if (*line == '\n') { - err = search_certs_line (ctx); + err = keylist_cb_line (ctx); if (err) return err; } @@ -486,132 +486,7 @@ search_certs (void *hook, const void *line_data, size_t line_len) } -/* Invoke SEARCH_CB for each certificate found using assuan connection - CTX to GPGSM. */ -static gpg_error_t -scute_gpgsm_search_certs (assuan_context_t ctx, cert_search_cb_t search_cb, - void *search_cb_hook) -{ - gpg_error_t err; - struct search_ctx search; - - err = assuan_transact (ctx, "OPTION with-key-data", NULL, NULL, - NULL, NULL, NULL, NULL); - if (err) - return err; - - search.pending_len = 0; - search.search_cb = search_cb; - search.search_cb_hook = search_cb_hook; - memset (&search.cert, '\0', sizeof (search.cert)); - - err = assuan_transact (ctx, "DUMPKEYS", &search_certs, &search, NULL, - NULL, NULL, NULL); - if (err) - goto out; - - /* Signal the EOF. This is not done by Assuan for us. */ - err = search_certs (&search, NULL, 0); - if (err) - goto out; - - out: - cert_reset (&search.cert); - return err; -} - -struct search_ctx_by_field -{ - /* What we are searching for. */ - enum { SEARCH_BY_GRIP, SEARCH_BY_FPR } field; - - /* The pattern we are looking for. */ - const char *pattern; - - cert_search_cb_t search_cb; - void *search_cb_hook; -}; - - -#ifdef COMPAT_FALLBACK -/* This is a compatibility function for GPGSM 2.0.0, which does not - support the --data option with the EXPORT command. */ -static gpg_error_t -export_cert_compat (char *fpr, struct cert *cert) -{ - gpg_error_t err; - assuan_context_t ctx; - const char *argv[] = { "gpgsm", "--server", NULL }; - int got; -#define COMMANDLINELEN 80 - char cmd[COMMANDLINELEN]; - int output_fds[2]; - int child_fds[2]; - -#define MAX_CERT_SIZE 4096 - cert->cert_der = malloc (MAX_CERT_SIZE); - if (!cert->cert_der) - return gpg_error_from_syserror (); - - if(pipe (output_fds) < 0) - return gpg_error_from_syserror (); - - child_fds[0] = assuan_fd_from_posix_fd (output_fds[1]); - child_fds[1] = -1; - - err = assuan_new (&ctx); - if (err) - { - close (output_fds[0]); - close (output_fds[1]); - DEBUG (DBG_CRIT, "failed to allocate assuan context: %s\n", - gpg_strerror (err)); - return err; - } - - err = assuan_pipe_connect (ctx, get_gpgsm_path (), argv, child_fds, - NULL, NULL, 128); - close (output_fds[1]); - if (err) - { - close (output_fds[0]); - assuan_release (ctx); - DEBUG (DBG_CRIT, "failed to spawn %s\n", get_gpgsm_path ()); - return err; - } - - snprintf (cmd, sizeof (cmd), "OUTPUT FD=%i", output_fds[1]); - err = assuan_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL); - if (err) - goto export_out; - - /* FIXME: This will only work if the certificate is small and fits - into the pipe buffer completely!!! */ - snprintf (cmd, sizeof (cmd), "EXPORT %s\n", cert->fpr); - err = assuan_transact (ctx, cmd, NULL, NULL, NULL, NULL, NULL, NULL); - if (err) - goto export_out; - - do - { - got = read (output_fds[0], cert->cert_der + cert->cert_der_len, - MAX_CERT_SIZE - cert->cert_der_len); - if (got > 0) - cert->cert_der_len += got; - } - while (!err && got > 0 && cert->cert_der_len < MAX_CERT_SIZE); - - if (got < 0 || cert->cert_der_len == MAX_CERT_SIZE) - err = gpg_error (GPG_ERR_GENERAL); - - export_out: - assuan_release (ctx); - close (output_fds[0]); - return err; -} -#endif - struct export_hook { @@ -653,8 +528,11 @@ export_cert_cb (void *hook, const void *line_data, size_t line_len) } +/* Export the certifciate using a second assuan connection. This is + * called during the key listing after a "crt" record has been + * received. */ static gpg_error_t -export_cert (char *fpr, struct cert *cert) +export_cert (const char *fpr, struct cert *cert) { gpg_error_t err; assuan_context_t ctx; @@ -684,7 +562,7 @@ export_cert (char *fpr, struct cert *cert) exp.buffer_len = 0; exp.buffer_size = 0; - snprintf (cmd, sizeof (cmd), "EXPORT --data -- %s\n", cert->fpr); + snprintf (cmd, sizeof (cmd), "EXPORT --data -- %s", cert->fpr); err = assuan_transact (ctx, cmd, export_cert_cb, &exp, NULL, NULL, NULL, NULL); assuan_release (ctx); @@ -694,19 +572,6 @@ export_cert (char *fpr, struct cert *cert) cert->cert_der = exp.buffer; cert->cert_der_len = exp.buffer_len; } -#ifdef COMPAT_FALLBACK - else if (gpg_err_code (err) == GPG_ERR_ASS_NO_OUTPUT) - { - /* For compatibility with GPGSM 2.0.0, we fall back to a work - around in that case. */ - if (cert->cert_der) - { - free (cert->cert_der); - cert->cert_der = NULL; - } - err = export_cert_compat (fpr, cert); - } -#endif if (!err) err = scute_agent_is_trusted (fpr, &cert->is_trusted); @@ -715,40 +580,18 @@ export_cert (char *fpr, struct cert *cert) } -static gpg_error_t -search_certs_by_field (void *hook, struct cert *cert) -{ - struct search_ctx_by_field *ctx = hook; - gpg_error_t err = 0; - - if ((ctx->field == SEARCH_BY_GRIP && !strcmp (ctx->pattern, cert->grip)) - || (ctx->field == SEARCH_BY_FPR && !strcmp (ctx->pattern, cert->fpr))) - { - if (strlen (cert->fpr) != 40) - return gpg_error (GPG_ERR_GENERAL); - - err = export_cert (cert->fpr, cert); - if (err) - return err; - - err = (*ctx->search_cb) (ctx->search_cb_hook, cert); - } - - return err; -} - - -/* Invoke SEARCH_CB for each certificate found using assuan connection - CTX to GPGSM. */ +/* Search for certificates using a key listing using PATTERN which is + * described by MODE. Invoke SEARCH_CB for each certificate found. */ gpg_error_t -scute_gpgsm_search_certs_by_grip (const char *grip, - cert_search_cb_t search_cb, - void *search_cb_hook) +scute_gpgsm_search_certs (enum keylist_modes mode, const char *pattern, + cert_search_cb_t search_cb, + void *search_cb_hook) { gpg_error_t err; assuan_context_t ctx; const char *argv[] = { "gpgsm", "--server", NULL }; - struct search_ctx_by_field search; + char line[ASSUAN_LINELENGTH]; + struct keylist_ctx keylist_ctx; err = assuan_new (&ctx); if (err) @@ -763,56 +606,37 @@ scute_gpgsm_search_certs_by_grip (const char *grip, if (err) { assuan_release (ctx); - DEBUG (DBG_CRIT, "spawning %s\n", get_gpgsm_path ()); + DEBUG (DBG_CRIT, "failed to spawn %s\n", get_gpgsm_path ()); return err; } - search.field = SEARCH_BY_GRIP; - search.pattern = grip; - search.search_cb = search_cb; - search.search_cb_hook = search_cb_hook; + memset (&keylist_ctx, 0, sizeof keylist_ctx); + keylist_ctx.search_cb = search_cb; + keylist_ctx.search_cb_hook = search_cb_hook; - err = scute_gpgsm_search_certs (ctx, &search_certs_by_field, &search); - assuan_release (ctx); - return err; -} + err = assuan_transact (ctx, "OPTION with-key-data", NULL, NULL, + NULL, NULL, NULL, NULL); + if (err) + goto leave; -/* Invoke SEARCH_CB for each certificate found using assuan connection - CTX to GPGSM. */ -gpg_error_t -scute_gpgsm_search_certs_by_fpr (const char *fpr, - cert_search_cb_t search_cb, - void *search_cb_hook) -{ - gpg_error_t err; - assuan_context_t ctx; - const char *argv[] = { "gpgsm", "--server", NULL }; - struct search_ctx_by_field search; - - err = assuan_new (&ctx); + snprintf (line, sizeof line, "LISTKEYS %s%s", + mode == KEYLIST_BY_GRIP? "&":"", + pattern); + err = assuan_transact (ctx, line, + keylist_cb, &keylist_ctx, + NULL, NULL, + NULL, NULL); if (err) - { - DEBUG (DBG_CRIT, "failed to allocate assuan context: %s", - gpg_strerror (err)); - return err; - } + goto leave; - err = assuan_pipe_connect (ctx, get_gpgsm_path (), argv, NULL, - NULL, NULL, 128); + /* Signal the EOF. This is not done by Assuan for us. */ + err = keylist_cb (&keylist_ctx, NULL, 0); if (err) - { - assuan_release (ctx); - DEBUG (DBG_CRIT, "failed to spawn %s\n", get_gpgsm_path ()); - return err; - } - - search.field = SEARCH_BY_FPR; - search.pattern = fpr; - search.search_cb = search_cb; - search.search_cb_hook = search_cb_hook; + goto leave; - err = scute_gpgsm_search_certs (ctx, &search_certs_by_field, &search); + leave: + cert_reset (&keylist_ctx.cert); assuan_release (ctx); return err; } diff --git a/src/cert.h b/src/cert.h index b57db0f..d1a6cb1 100644 --- a/src/cert.h +++ b/src/cert.h @@ -92,7 +92,7 @@ struct cert /* The key grip. */ unsigned char grip[41]; - /* The chain ID. */ + /* The chain ID as return by a gpgsm key listing. */ unsigned char chain_id[41]; /* The certificate in DER format. This is not entered by the search @@ -109,22 +109,23 @@ struct cert /* From cert-gpgsm.c. */ +enum keylist_modes + { + KEYLIST_BY_GRIP, + KEYLIST_BY_FPR + }; + /* The callback type invoked for each certificate found in the search. */ typedef gpg_error_t (*cert_search_cb_t) (void *hook, struct cert *cert); -/* Invoke SEARCH_CB for each certificate found using assuan connection - CTX to GPGSM. */ -gpg_error_t scute_gpgsm_search_certs_by_grip (const char *grip, - cert_search_cb_t search_cb, - void *search_cb_hook); - -/* Invoke SEARCH_CB for each certificate found using assuan connection - CTX to GPGSM. */ -gpg_error_t scute_gpgsm_search_certs_by_fpr (const char *fpr, - cert_search_cb_t search_cb, - void *search_cb_hook); +/* Search for certificates using a key listing using PATTERN which is + * described by MODE. Invoke SEARCH_CB for each certificate found. */ +gpg_error_t scute_gpgsm_search_certs (enum keylist_modes mode, + const char *pattern, + cert_search_cb_t search_cb, + void *search_cb_hook); /* From cert-object.c. */ diff --git a/src/gpgsm.c b/src/gpgsm.c index 27e5036..b0d4c4c 100644 --- a/src/gpgsm.c +++ b/src/gpgsm.c @@ -91,7 +91,7 @@ search_cb (void *hook, struct cert *cert) might still be able to proceed, for example with client authentication. */ if (ctx->with_chain && strcmp (cert->chain_id, cert->fpr)) - scute_gpgsm_search_certs_by_fpr (cert->chain_id, search_cb, ctx); + scute_gpgsm_search_certs (KEYLIST_BY_FPR, cert->chain_id, search_cb, ctx); /* Turn this certificate into a certificate object. */ err = scute_attr_cert (cert, ctx->grip, &attrp, &attr_countp); @@ -161,6 +161,6 @@ scute_gpgsm_get_cert (char *grip, const char *certref, DEBUG (DBG_INFO, "scute_gpgsm_get_cert: falling back to gpgsm"); search.with_chain = true; - err = scute_gpgsm_search_certs_by_grip (grip, search_cb, &search); + err = scute_gpgsm_search_certs (KEYLIST_BY_GRIP, grip, search_cb, &search); return err; } ----------------------------------------------------------------------- Summary of changes: src/agent.c | 2 +- src/agent.h | 2 +- src/cert-gpgsm.c | 344 ++++++++++++++----------------------------------------- src/cert.h | 25 ++-- src/gpgsm.c | 4 +- 5 files changed, 101 insertions(+), 276 deletions(-) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 18 15:20:23 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Feb 2019 15:20:23 +0100 Subject: [git] Scute - branch, master, updated. scute-1.5.0-12-ga148c21 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 "PKCS#11 token on top of gpg-agent". The branch, master has been updated via a148c216517c6dcf2d339f5060c5b09164dd18c9 (commit) from d981ad1ed18d5e7d7b63ecf256348a509cc4eb59 (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 a148c216517c6dcf2d339f5060c5b09164dd18c9 Author: Werner Koch Date: Mon Feb 18 15:19:51 2019 +0100 Properly handle card switching. * src/agent.c (scute_agent_learn): Handle GPG_ERR_CARD_REMOVED. -- diff --git a/src/agent.c b/src/agent.c index 706fdf3..3316c97 100644 --- a/src/agent.c +++ b/src/agent.c @@ -712,6 +712,20 @@ scute_agent_learn (struct agent_card_info_s *info) err = assuan_transact (agent_ctx, "LEARN --sendinfo", NULL, NULL, default_inq_cb, NULL, learn_status_cb, info); + if (gpg_err_source(err) == GPG_ERR_SOURCE_SCD + && gpg_err_code (err) == GPG_ERR_CARD_REMOVED) + { + /* SCD session is in card removed state. clear that state. */ + err = assuan_transact (agent_ctx, "SCD SERIALNO", + NULL, NULL, NULL, NULL, NULL, NULL); + if (!err) + { + memset (info, 0, sizeof (*info)); + err = assuan_transact (agent_ctx, "LEARN --sendinfo", + NULL, NULL, default_inq_cb, + NULL, learn_status_cb, info); + } + } return err; } ----------------------------------------------------------------------- Summary of changes: src/agent.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 18 17:21:38 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 18 Feb 2019 17:21:38 +0100 Subject: [git] Scute - branch, master, updated. scute-1.5.0-13-g90fe9f7 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 "PKCS#11 token on top of gpg-agent". The branch, master has been updated via 90fe9f7be2a386fa7e4d7869fec32a4f4e24151b (commit) from a148c216517c6dcf2d339f5060c5b09164dd18c9 (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 90fe9f7be2a386fa7e4d7869fec32a4f4e24151b Author: Werner Koch Date: Mon Feb 18 16:53:23 2019 +0100 Clean up use of label and s/n in CK_TOKEN_INFO. * src/agent.c (scute_agent_learn): Also get the DISPSERIALNO. (learn_status_cb): Support it. * src/p11-gettokeninfo.c (C_GetTokenInfo): Simplify serialNumber setting. * src/slots.c (slot_token_label): Redirect to ... (slot_token_serial): here and remove the secial OpenPGP card handling which is not needed due to DISPSERIALNO. Signed-off-by: Werner Koch diff --git a/src/agent.c b/src/agent.c index 3316c97..9a25820 100644 --- a/src/agent.c +++ b/src/agent.c @@ -463,6 +463,7 @@ scute_agent_release_card_info (struct agent_card_info_s *info) return; free (info->serialno); + free (info->dispserialno); free (info->cardtype); free (info->disp_name); free (info->disp_lang); @@ -539,6 +540,11 @@ learn_status_cb (void *opaque, const char *line) free (parm->serialno); parm->serialno = store_serialno (line); } + else if (keywordlen == 13 && !memcmp (keyword, "$DISPSERIALNO", keywordlen)) + { + free (parm->dispserialno); + parm->dispserialno = unescape_status_string (line); + } else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen)) { parm->is_piv = !strcmp (line, "PIV"); @@ -710,8 +716,9 @@ scute_agent_learn (struct agent_card_info_s *info) memset (info, 0, sizeof (*info)); err = assuan_transact (agent_ctx, "LEARN --sendinfo", - NULL, NULL, default_inq_cb, - NULL, learn_status_cb, info); + NULL, NULL, + default_inq_cb, NULL, + learn_status_cb, info); if (gpg_err_source(err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_CARD_REMOVED) { @@ -722,10 +729,23 @@ scute_agent_learn (struct agent_card_info_s *info) { memset (info, 0, sizeof (*info)); err = assuan_transact (agent_ctx, "LEARN --sendinfo", - NULL, NULL, default_inq_cb, - NULL, learn_status_cb, info); + NULL, NULL, + default_inq_cb, NULL, + learn_status_cb, info); } } + if (!err) + { + /* Also try to get the human readabale serial number. */ + err = assuan_transact (agent_ctx, "SCD GETATTR $DISPSERIALNO", + NULL, NULL, + default_inq_cb, NULL, + learn_status_cb, info); + if (gpg_err_code (err) == GPG_ERR_INV_NAME + || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_OPERATION) + err = 0; /* Not implemented or GETATTR not supported. */ + } + return err; } diff --git a/src/agent.h b/src/agent.h index 0b75f14..d14ebb7 100644 --- a/src/agent.h +++ b/src/agent.h @@ -61,7 +61,8 @@ typedef struct key_info_s *key_info_t; struct agent_card_info_s { char *serialno; /* Malloced hex string. */ - char *cardtype; /* Null or mallcoed string with the card type. */ + char *dispserialno; /* NULL or malloced human readable S/N. */ + char *cardtype; /* Null or malloced string with the card type. */ char *disp_name; /* Malloced. */ char *disp_lang; /* Malloced. */ int disp_sex; /* 0 = unspecified, 1 = male, 2 = female. */ diff --git a/src/p11-gettokeninfo.c b/src/p11-gettokeninfo.c index 4094f42..bb9190a 100644 --- a/src/p11-gettokeninfo.c +++ b/src/p11-gettokeninfo.c @@ -65,9 +65,7 @@ C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) scute_copy_string (pInfo->manufacturerID, slot_token_manufacturer (slot), 32); scute_copy_string (pInfo->model, slot_token_application (slot), 16); - len = slot_token_serial (slot, pInfo->serialNumber); - while (len < 16) - pInfo->serialNumber[len++] = ' '; + scute_copy_string (pInfo->serialNumber, slot_token_serial (slot), 16); pInfo->flags = CKF_TOKEN_INITIALIZED | CKF_PROTECTED_AUTHENTICATION_PATH | CKF_WRITE_PROTECTED diff --git a/src/slots.c b/src/slots.c index 1e9b1a6..70d4ea2 100644 --- a/src/slots.c +++ b/src/slots.c @@ -536,14 +536,12 @@ slot_token_present (slot_iterator_t id) } -/* Return the token label. */ -char * +/* Return the token label. We use the dispserialno here too because + * Firefox prints that value in the prompt ("Stored at:"). */ +const char * slot_token_label (slot_iterator_t id) { - struct slot *slot = scute_table_data (slots, id); - - /* slots_update() makes sure this is valid. */ - return slot->info.serialno; + return slot_token_serial (id); } @@ -615,26 +613,14 @@ slot_token_application (slot_iterator_t id) } -/* Get the serial number of the token. Must not write more than 16 - bytes starting from DST. */ -int -slot_token_serial (slot_iterator_t id, char *dst) +/* Get the serial number of the token. */ +const char * +slot_token_serial (slot_iterator_t id) { struct slot *slot = scute_table_data (slots, id); - int i; - if (slot->info.is_piv) - { - strncpy (dst, slot->info.serialno, 15); - dst[15] = 0; - return 16; - } - - /* slots_update() makes sure serialno is valid. */ - for (i = 0; i < 8; i++) - dst[i] = slot->info.serialno[20 + i]; - - return 8; + /* slots_update() makes sure this is valid. */ + return slot->info.dispserialno? slot->info.dispserialno : slot->info.serialno; } diff --git a/src/slots.h b/src/slots.h index ac34734..6783219 100644 --- a/src/slots.h +++ b/src/slots.h @@ -90,7 +90,7 @@ CK_RV slots_lookup (CK_SLOT_ID id, slot_iterator_t *slot); bool slot_token_present (slot_iterator_t slot); /* Return the token label. */ -char *slot_token_label (slot_iterator_t id); +const char *slot_token_label (slot_iterator_t id); /* Get the manufacturer of the token. */ const char *slot_token_manufacturer (slot_iterator_t id); @@ -98,9 +98,8 @@ const char *slot_token_manufacturer (slot_iterator_t id); /* Get the application of the token. */ const char *slot_token_application (slot_iterator_t id); -/* Get the serial number of the token. Must not write more than 16 - bytes starting from DST. */ -int slot_token_serial (slot_iterator_t id, char *dst); +/* Get the serial number of the token. */ +const char *slot_token_serial (slot_iterator_t id); /* Get the manufacturer of the token. */ void slot_token_version (slot_iterator_t id, ----------------------------------------------------------------------- Summary of changes: src/agent.c | 28 ++++++++++++++++++++++++---- src/agent.h | 3 ++- src/p11-gettokeninfo.c | 4 +--- src/slots.c | 32 +++++++++----------------------- src/slots.h | 7 +++---- 5 files changed, 39 insertions(+), 35 deletions(-) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 19 03:58:02 2019 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 19 Feb 2019 03:58:02 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-375-gada797f 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 ada797f477f923bee36d67c8e49f728ae7adb9e9 (commit) from 3cbdf896e6919333b5423001ab58c01a04363386 (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 ada797f477f923bee36d67c8e49f728ae7adb9e9 Author: NIIBE Yutaka Date: Tue Feb 19 11:55:55 2019 +0900 agent: Factor out the getpin interaction. * agent/call-pinentry.c (do_getpin): New. (agent_askpin, agent_get_passphrase): Use do_getpin. Signed-off-by: NIIBE Yutaka diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 541a4a3..c7ff70a 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -941,6 +941,41 @@ build_cmd_setdesc (char *line, size_t linelen, const char *desc) +/* Ask pinentry to get a pin by "GETPIN" command. + * FIXME: Support EOF detection of the socket: ctrl->thread_startup.fd + */ +static gpg_error_t +do_getpin (ctrl_t ctrl, struct entry_parm_s *parm, + struct pin_entry_info_s *pininfo) +{ + int rc; + unsigned int pinentry_status; + int saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); + + (void)ctrl; + assuan_begin_confidential (entry_ctx); + pinentry_status = 0; + rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm, + inq_quality, entry_ctx, + pinentry_status_cb, &pinentry_status); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); + /* Most pinentries out in the wild return the old Assuan error code + for canceled which gets translated to an assuan Cancel error and + not to the code for a user cancel. Fix this here. */ + if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + /* Change error code in case the window close button was clicked + to cancel the operation. */ + if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON) + && gpg_err_code (rc) == GPG_ERR_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED); + + if (pininfo) + pininfo->status = pinentry_status; + + return rc; +} + /* Call the Entry and ask for the PIN. We do check for a valid PIN number here and repeat it as long as we have invalid formed numbers. KEYINFO and CACHE_MODE are used to tell pinentry something @@ -957,7 +992,6 @@ agent_askpin (ctrl_t ctrl, struct entry_parm_s parm; const char *errtext = NULL; int is_pin = 0; - int saveflag; if (opt.batch) return 0; /* fixme: we should return BAD PIN */ @@ -1100,26 +1134,7 @@ agent_askpin (ctrl_t ctrl, return unlock_pinentry (ctrl, rc); } - saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); - assuan_begin_confidential (entry_ctx); - rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, - inq_quality, entry_ctx, - pinentry_status_cb, &pininfo->status); - assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); - /* Most pinentries out in the wild return the old Assuan error code - for canceled which gets translated to an assuan Cancel error and - not to the code for a user cancel. Fix this here. */ - if (rc && gpg_err_source (rc) - && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) - rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); - - - /* Change error code in case the window close button was clicked - to cancel the operation. */ - if ((pininfo->status & PINENTRY_STATUS_CLOSE_BUTTON) - && gpg_err_code (rc) == GPG_ERR_CANCELED) - rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED); - + rc = do_getpin (ctrl, &parm, pininfo); if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA) errtext = is_pin? L_("PIN too long") : L_("Passphrase too long"); @@ -1188,12 +1203,9 @@ agent_get_passphrase (ctrl_t ctrl, const char *errtext, int with_qualitybar, const char *keyinfo, cache_mode_t cache_mode) { - int rc; char line[ASSUAN_LINELENGTH]; struct entry_parm_s parm; - int saveflag; - unsigned int pinentry_status; *retpass = NULL; if (opt.batch) @@ -1277,24 +1289,7 @@ agent_get_passphrase (ctrl_t ctrl, if (!parm.buffer) return unlock_pinentry (ctrl, out_of_core ()); - saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); - assuan_begin_confidential (entry_ctx); - pinentry_status = 0; - rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, - inq_quality, entry_ctx, - pinentry_status_cb, &pinentry_status); - assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); - /* Most pinentries out in the wild return the old Assuan error code - for canceled which gets translated to an assuan Cancel error and - not to the code for a user cancel. Fix this here. */ - if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) - rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); - /* Change error code in case the window close button was clicked - to cancel the operation. */ - if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON) - && gpg_err_code (rc) == GPG_ERR_CANCELED) - rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED); - + rc = do_getpin (ctrl, &parm, NULL); if (rc) xfree (parm.buffer); else ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 79 ++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 42 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 19 06:41:42 2019 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 19 Feb 2019 06:41:42 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-377-gc395f83 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 c395f8315362793409be54aca630ce6e903ea984 (commit) via 99aa54323f97937613e02d8c2da91544e1fe7bcf (commit) from ada797f477f923bee36d67c8e49f728ae7adb9e9 (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 c395f8315362793409be54aca630ce6e903ea984 Author: NIIBE Yutaka Date: Tue Feb 19 14:36:50 2019 +0900 agent: Terminate pinentry process gracefully, by watching socket. * agent/call-pinentry.c (watch_sock): New. (do_getpin): Spawn the watching thread. -- While we don't have npth_cancel (and it's difficult to implement it correctly), this is a kind of best compromise allowing a thread's polling when pinentry is active. GnuPG-bug-id: 2011 Signed-off-by: NIIBE Yutaka diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 0c8f7dc..34dde37 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -942,16 +942,88 @@ build_cmd_setdesc (char *line, size_t linelen, const char *desc) -/* Ask pinentry to get a pin by "GETPIN" command. - * FIXME: Support EOF detection of the socket: ctrl->thread_startup.fd +/* Watch the socket's EOF condition, while checking finish of + foreground thread. When EOF condition is detected, terminate + the pinentry process behind the assuan pipe. + */ +static void * +watch_sock (void *arg) +{ + gnupg_fd_t *p = (gnupg_fd_t *)arg; + pid_t pid = assuan_get_pid (entry_ctx); + + while (1) + { + int err; + gnupg_fd_t sock = *p; + fd_set fdset; + struct timeval timeout = { 0, 500000 }; + + if (sock == GNUPG_INVALID_FD) + return NULL; + + FD_ZERO (&fdset); + FD_SET (FD2INT (sock), &fdset); + err = npth_select (FD2INT (sock)+1, &fdset, NULL, NULL, &timeout); + + if (err < 0) + { + if (errno == EINTR) + continue; + else + return NULL; + } + + /* Possibly, it's EOF. */ + if (err > 0) + break; + } + + if (pid == (pid_t)(-1)) + ; /* No pid available can't send a kill. */ +#ifdef HAVE_W32_SYSTEM + /* Older versions of assuan set PID to 0 on Windows to indicate an + invalid value. */ + else if (pid != (pid_t) INVALID_HANDLE_VALUE && pid != 0) + TerminateProcess ((HANDLE)pid, 1); +#else + else if (pid > 0) + kill (pid, SIGINT); +#endif + + return NULL; +} + + +/* Ask pinentry to get a pin by "GETPIN" command, spawning a thread + detecting the socket's EOF. */ static gpg_error_t do_getpin (ctrl_t ctrl, struct entry_parm_s *parm) { - int rc; + npth_attr_t tattr; + gpg_error_t rc; + int err; + npth_t thread; int saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); + gnupg_fd_t sock_watched = ctrl->thread_startup.fd; + + err = npth_attr_init (&tattr); + if (err) + { + log_error ("do_getpin: error npth_attr_init: %s\n", strerror (err)); + return gpg_error_from_errno (err); + } + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); + + err = npth_create (&thread, &tattr, watch_sock, (void *)&sock_watched); + npth_attr_destroy (&tattr); + if (err) + { + log_error ("do_getpin: error spawning thread: %s\n", strerror (err)); + return gpg_error_from_errno (err); + } - (void)ctrl; assuan_begin_confidential (entry_ctx); rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm, inq_quality, entry_ctx, @@ -968,6 +1040,11 @@ do_getpin (ctrl_t ctrl, struct entry_parm_s *parm) && gpg_err_code (rc) == GPG_ERR_CANCELED) rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED); + sock_watched = GNUPG_INVALID_FD; + err = npth_join (thread, NULL); + if (err) + log_error ("do_getpin: error joining thread: %s\n", strerror (err)); + return rc; } commit 99aa54323f97937613e02d8c2da91544e1fe7bcf Author: NIIBE Yutaka Date: Tue Feb 19 13:12:07 2019 +0900 agent: Minor change for pinentry status handling. * agent/call-pinentry.c (struct entry_parm_s): Add status. (do_getpin): Use param->status. (agent_askpin): Copy param->status. to pininfo. Signed-off-by: NIIBE Yutaka diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index c7ff70a..0c8f7dc 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -85,6 +85,7 @@ struct entry_parm_s int lines; size_t size; unsigned char *buffer; + int status; }; @@ -945,19 +946,16 @@ build_cmd_setdesc (char *line, size_t linelen, const char *desc) * FIXME: Support EOF detection of the socket: ctrl->thread_startup.fd */ static gpg_error_t -do_getpin (ctrl_t ctrl, struct entry_parm_s *parm, - struct pin_entry_info_s *pininfo) +do_getpin (ctrl_t ctrl, struct entry_parm_s *parm) { int rc; - unsigned int pinentry_status; int saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); (void)ctrl; assuan_begin_confidential (entry_ctx); - pinentry_status = 0; rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm, inq_quality, entry_ctx, - pinentry_status_cb, &pinentry_status); + pinentry_status_cb, &parm->status); assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and @@ -966,13 +964,10 @@ do_getpin (ctrl_t ctrl, struct entry_parm_s *parm, rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); /* Change error code in case the window close button was clicked to cancel the operation. */ - if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON) + if ((parm->status & PINENTRY_STATUS_CLOSE_BUTTON) && gpg_err_code (rc) == GPG_ERR_CANCELED) rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED); - if (pininfo) - pininfo->status = pinentry_status; - return rc; } @@ -1134,7 +1129,8 @@ agent_askpin (ctrl_t ctrl, return unlock_pinentry (ctrl, rc); } - rc = do_getpin (ctrl, &parm, pininfo); + rc = do_getpin (ctrl, &parm); + pininfo->status = parm.status; if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA) errtext = is_pin? L_("PIN too long") : L_("Passphrase too long"); @@ -1289,7 +1285,7 @@ agent_get_passphrase (ctrl_t ctrl, if (!parm.buffer) return unlock_pinentry (ctrl, out_of_core ()); - rc = do_getpin (ctrl, &parm, NULL); + rc = do_getpin (ctrl, &parm); if (rc) xfree (parm.buffer); else ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 101 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 14 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 19 07:55:59 2019 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 19 Feb 2019 07:55:59 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.13-6-g14e5435 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 14e5435afb50dc9a9243ff3e0aed5030beba2914 (commit) via 005e951714ff62087b8c8802e05d14b7998826f3 (commit) via 90e5f49b6a2e002d3c67a041a076f07aeb7a7f54 (commit) via 6e422b5135c71f8fa859a3f4de51bf89e3ff5ac6 (commit) from a09bba976d2f5694011a9291189a70a0f3c4caae (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 14e5435afb50dc9a9243ff3e0aed5030beba2914 Author: Neal H. Walfield Date: Fri Oct 6 11:51:39 2017 +0200 gpg: Fix comparison. * g10/gpgcompose.c (literal_name): Complain if passed zero arguments, not one or fewer. -- Cherry-picked master commit of: 1ed21eee79749b976b4a935f2279b162634e9c5e Signed-off-by: Neal H. Walfield diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index 430538e..226f793 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -2746,7 +2746,7 @@ literal_name (const char *option, int argc, char *argv[], void *cookie) { struct litinfo *li = cookie; - if (argc <= 1) + if (argc <= 0) log_fatal ("Usage: %s NAME\n", option); if (strlen (argv[0]) > 255) commit 005e951714ff62087b8c8802e05d14b7998826f3 Author: NIIBE Yutaka Date: Wed Sep 20 10:42:28 2017 +0900 agent: Fix cancellation handling for scdaemon. * agent/call-scd.c (cancel_inquire): Remove. (agent_card_pksign, agent_card_pkdecrypt, agent_card_writekey) (agent_card_scd): Don't call cancel_inquire. -- Cherry-picked master commit of: 9f5e50e7c85aa8b847d38010241ed570ac114fc3 Since libassuan 2.1.0, cancellation command "CAN" is handled within the library, by assuan_transact. So, cancel_inquire just caused spurious "CAN" command to scdaemon which resulted an error. Signed-off-by: NIIBE Yutaka diff --git a/agent/call-scd.c b/agent/call-scd.c index 16139fd..51d9abd 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -89,7 +89,6 @@ struct inq_needpin_parm_s const char *getpin_cb_desc; assuan_context_t passthru; /* If not NULL, pass unknown inquiries up to the caller. */ - int any_inq_seen; /* The next fields are used by inq_writekey_parm. */ const unsigned char *keydata; @@ -727,7 +726,6 @@ inq_needpin (void *opaque, const char *line) size_t pinlen; int rc; - parm->any_inq_seen = 1; if ((s = has_leading_keyword (line, "NEEDPIN"))) { line = s; @@ -811,30 +809,6 @@ hash_algo_option (int algo) } -static gpg_error_t -cancel_inquire (ctrl_t ctrl, gpg_error_t rc) -{ - gpg_error_t oldrc = rc; - - /* The inquire callback was called and transact returned a - cancel error. We assume that the inquired process sent a - CANCEL. The passthrough code is not able to pass on the - CANCEL and thus scdaemon would stuck on this. As a - workaround we send a CANCEL now. */ - rc = assuan_write_line (ctrl->scd_local->ctx, "CAN"); - if (!rc) { - char *line; - size_t len; - - rc = assuan_read_line (ctrl->scd_local->ctx, &line, &len); - if (!rc) - rc = oldrc; - } - - return rc; -} - - /* Create a signature using the current card. MDALGO is either 0 or * gives the digest algorithm. DESC_TEXT is an additional parameter * passed to GETPIN_CB. */ @@ -875,7 +849,6 @@ agent_card_pksign (ctrl_t ctrl, inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; - inqparm.any_inq_seen = 0; inqparm.keydata = NULL; inqparm.keydatalen = 0; @@ -888,9 +861,6 @@ agent_card_pksign (ctrl_t ctrl, put_membuf_cb, &data, inq_needpin, &inqparm, NULL, NULL); - if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || - gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) - rc = cancel_inquire (ctrl, rc); if (rc) { @@ -974,7 +944,6 @@ agent_card_pkdecrypt (ctrl_t ctrl, inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; - inqparm.any_inq_seen = 0; inqparm.keydata = NULL; inqparm.keydatalen = 0; snprintf (line, DIM(line), "PKDECRYPT %s", keyid); @@ -982,9 +951,6 @@ agent_card_pkdecrypt (ctrl_t ctrl, put_membuf_cb, &data, inq_needpin, &inqparm, padding_info_cb, r_padding); - if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || - gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) - rc = cancel_inquire (ctrl, rc); if (rc) { @@ -1111,15 +1077,11 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, parms.getpin_cb_arg = getpin_cb_arg; parms.getpin_cb_desc= NULL; parms.passthru = 0; - parms.any_inq_seen = 0; parms.keydata = keydata; parms.keydatalen = keydatalen; rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL, inq_writekey_parms, &parms, NULL, NULL); - if (parms.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || - gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) - rc = cancel_inquire (ctrl, rc); return unlock_scd (ctrl, rc); } @@ -1344,7 +1306,6 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline, inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.getpin_cb_desc = NULL; inqparm.passthru = assuan_context; - inqparm.any_inq_seen = 0; inqparm.keydata = NULL; inqparm.keydatalen = 0; @@ -1354,8 +1315,6 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline, pass_data_thru, assuan_context, inq_needpin, &inqparm, pass_status_thru, assuan_context); - if (inqparm.any_inq_seen && gpg_err_code(rc) == GPG_ERR_ASS_CANCELED) - rc = cancel_inquire (ctrl, rc); assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag); if (rc) commit 90e5f49b6a2e002d3c67a041a076f07aeb7a7f54 Author: NIIBE Yutaka Date: Wed Sep 20 10:06:43 2017 +0900 scd: Distinguish cancel by user and protocol error. * scd/apdu.h (SW_HOST_CANCELLED): New. * scd/apdu.c (host_sw_string): Support SW_HOST_CANCELLED. (pcsc_error_to_sw): Return SW_HOST_CANCELLED for PCSC_E_CANCELLED. * scd/iso7816.c (map_sw): Return GPG_ERR_INV_RESPONSE for SW_HOST_ABORTED and GPG_ERR_CANCELED for SW_HOST_CANCELLED. -- Cherry-picked master commit of: 2396055c096884d521c26b76f26263a146207c24 Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.c b/scd/apdu.c index af77570..274f2db 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -501,6 +501,7 @@ host_sw_string (long err) case SW_HOST_ABORTED: return "aborted"; case SW_HOST_NO_PINPAD: return "no pinpad"; case SW_HOST_ALREADY_CONNECTED: return "already connected"; + case SW_HOST_CANCELLED: return "cancelled"; default: return "unknown host status error"; } } @@ -607,7 +608,7 @@ pcsc_error_to_sw (long ec) { case 0: rc = 0; break; - case PCSC_E_CANCELLED: rc = SW_HOST_ABORTED; break; + case PCSC_E_CANCELLED: rc = SW_HOST_CANCELLED; break; case PCSC_E_NO_MEMORY: rc = SW_HOST_OUT_OF_CORE; break; case PCSC_E_TIMEOUT: rc = SW_HOST_CARD_IO_ERROR; break; case PCSC_E_NO_SERVICE: diff --git a/scd/apdu.h b/scd/apdu.h index 6240134..1392aab 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -71,7 +71,8 @@ enum { SW_HOST_NO_READER = 0x1000c, SW_HOST_ABORTED = 0x1000d, SW_HOST_NO_PINPAD = 0x1000e, - SW_HOST_ALREADY_CONNECTED = 0x1000f + SW_HOST_ALREADY_CONNECTED = 0x1000f, + SW_HOST_CANCELLED = 0x10010 }; struct dev_list; diff --git a/scd/iso7816.c b/scd/iso7816.c index e8b517e..627481f 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -94,8 +94,9 @@ map_sw (int sw) case SW_HOST_CARD_IO_ERROR: ec = GPG_ERR_EIO; break; case SW_HOST_GENERAL_ERROR: ec = GPG_ERR_GENERAL; break; case SW_HOST_NO_READER: ec = GPG_ERR_ENODEV; break; - case SW_HOST_ABORTED: ec = GPG_ERR_CANCELED; break; + case SW_HOST_ABORTED: ec = GPG_ERR_INV_RESPONSE; break; case SW_HOST_NO_PINPAD: ec = GPG_ERR_NOT_SUPPORTED; break; + case SW_HOST_CANCELLED: ec = GPG_ERR_CANCELED; break; default: if ((sw & 0x010000)) commit 6e422b5135c71f8fa859a3f4de51bf89e3ff5ac6 Author: NIIBE Yutaka Date: Tue Sep 19 12:28:43 2017 +0900 common: Fix gnupg_wait_processes. * common/exechelp-posix.c (gnupg_wait_processes): Loop for r_exitcodes even if we already see an error. -- Cherry-picked master commit of: eeb3da6eb717ed6a1a1069a7611eb37503e8672d The value stored by waitpid for exit code is encoded; It requires decoded by WEXITSTATUS macro, regardless of an error. For example, when one of processes is already exited and another is still running, it resulted wrong value of in r_exitcodes[n]. Signed-off-by: NIIBE Yutaka diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 7237993..3acf74a 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -784,30 +784,32 @@ gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, } } - if (ec == 0) - for (i = 0; i < count; i++) - { - if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]) == 127) - { - log_error (_("error running '%s': probably not installed\n"), - pgmnames[i]); - ec = GPG_ERR_CONFIGURATION; - } - else if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i])) - { - if (dummy) - log_error (_("error running '%s': exit status %d\n"), - pgmnames[i], WEXITSTATUS (r_exitcodes[i])); - else - r_exitcodes[i] = WEXITSTATUS (r_exitcodes[i]); - ec = GPG_ERR_GENERAL; - } - else if (!WIFEXITED (r_exitcodes[i])) - { - log_error (_("error running '%s': terminated\n"), pgmnames[i]); - ec = GPG_ERR_GENERAL; - } - } + for (i = 0; i < count; i++) + { + if (r_exitcodes[i] == -1) + continue; + + if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]) == 127) + { + log_error (_("error running '%s': probably not installed\n"), + pgmnames[i]); + ec = GPG_ERR_CONFIGURATION; + } + else if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i])) + { + if (dummy) + log_error (_("error running '%s': exit status %d\n"), + pgmnames[i], WEXITSTATUS (r_exitcodes[i])); + else + r_exitcodes[i] = WEXITSTATUS (r_exitcodes[i]); + ec = GPG_ERR_GENERAL; + } + else if (!WIFEXITED (r_exitcodes[i])) + { + log_error (_("error running '%s': terminated\n"), pgmnames[i]); + ec = GPG_ERR_GENERAL; + } + } xfree (dummy); return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); ----------------------------------------------------------------------- Summary of changes: agent/call-scd.c | 41 ---------------------------------------- common/exechelp-posix.c | 50 +++++++++++++++++++++++++------------------------ g10/gpgcompose.c | 2 +- scd/apdu.c | 3 ++- scd/apdu.h | 3 ++- scd/iso7816.c | 3 ++- 6 files changed, 33 insertions(+), 69 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 19 12:11:50 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 19 Feb 2019 12:11:50 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.12.0-131-g4c49417 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 4c49417cc0dbd7f34269aff00fccafba150af744 (commit) from f8312d7c333193582dcb5816198219b9564023f0 (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 4c49417cc0dbd7f34269aff00fccafba150af744 Author: Werner Koch Date: Tue Feb 19 12:11:22 2019 +0100 core,w32: Fix missing sentinel in dir name builder. * src/w32-util.c (_gpgme_get_gpgconf_path): Add NULL top strconcat. -- Fortunately this is called early and the stack like cleared out so that we have not seen wrong behaviour until now. We should really fix all these annoying HANDLE/int cast warnings and alike so that real bugs are not drowned by them. GnuPG-bug-id: 4369 Signed-off-by: Werner Koch diff --git a/src/w32-util.c b/src/w32-util.c index e37fb43..9802d9c 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -601,7 +601,7 @@ _gpgme_get_gpgconf_path (void) /* 5. Try to find gpgconf.exe relative to us. */ if (!gpgconf && inst_dir) { - char *dir = _gpgme_strconcat (inst_dir, "\\..\\..\\GnuPG\\bin"); + char *dir = _gpgme_strconcat (inst_dir, "\\..\\..\\GnuPG\\bin", NULL); gpgconf = find_program_in_dir (dir, name); free (dir); } ----------------------------------------------------------------------- Summary of changes: src/w32-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 20 12:02:26 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 20 Feb 2019 12:02:26 +0100 Subject: [git] Scute - branch, master, updated. scute-1.5.0-19-g6f61c17 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 "PKCS#11 token on top of gpg-agent". The branch, master has been updated via 6f61c173cf2b71b43f41f163d590ef127b68509e (commit) via 9a25f7bb80c292f05cc4b58c2b8caf5252bbccb0 (commit) via b623ff524e63391f01aa075686b7004e8a0ceb91 (commit) via cc91c168e4aecc292f95156a96d9fd96e449d8b1 (commit) from 5de05acba42c6eb76589c6cbbcfb2d7adbf2dc56 (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 6f61c173cf2b71b43f41f163d590ef127b68509e Author: Werner Koch Date: Wed Feb 20 11:42:07 2019 +0100 Update gpg-error.m4 and create ChangeLog. -- diff --git a/.gitignore b/.gitignore index 5074f03..338b953 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ m4/Makefile.in obj/ src/Makefile.in tests/Makefile.in +/VERSION diff --git a/ChangeLog b/ChangeLog index 20b4e01..ac678aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,593 +1 @@ -2010-04-21 Marcus Brinkmann - - Release 1.4.0. - - * configure.ac (NEED_LIBASSUAN_VERSION): Bump to 2.0.0. - (LIBSCUTE_LT_REVISION): Bump to 2. - -2009-12-08 Marcus Brinkmann - - * src/agent.c (agent_connect): Convert posix fd to assuan fd. - * src/cert-gpgsm.c (export_cert_compat): Likewise. - - * src/Makefile.am (libgpg-error.a, libassuan.a): Force symlink. - -2009-11-06 Marcus Brinkmann - - * src/cert-gpgsm.c (export_cert_compat, export_cert) - (scute_gpgsm_search_certs_by_grip) - (scute_gpgsm_search_certs_by_fpr): Call assuan_pipe_connect - instead of assuan_pipe_connect_ext. - * src/agent.c (agent_connect): Update use of assuan_socket_connect - and assuan_pipe_connect. - -2009-10-16 Marcus Brinkmann - - * src/p11-initialize.c (CK_DEFINE_FUNCTION): Fix code on - non-Windows. - -2009-10-08 Marcus Brinkmann - - * src/p11-initialize.c (C_Initialize): Call WSAStartup. - * src/p11-finalize.c (CK_DEFINE_FUNCTION): Call WSACleanup. - -2009-10-06 Marcus Brinkmann - - * src/pkcs11.h: Add support for GOST. By Andreas Jellinghaus. - -2009-09-23 Marcus Brinkmann - - * configure.ac (NEED_LIBASSUAN_VERSION): Update to 1.1.0. - (_ASSUAN_ONLY_GPG_ERROR): Remove. - * src/p11-initialize.c: Update to new Assuan interface. - * src/debug.c (_scute_debug_init): Remove call to - assuan_set_assuan_log_stream. - * src/agent.c (agent_connect): Allocate assuan context before - connecting to server. Release it on error. - * src/cert-gpgsm.c (export_cert_compat, export_cert) - (scute_gpgsm_search_certs_by_grip) - (scute_gpgsm_search_certs_by_fpr): Likewise. - -2009-07-22 Stef Walter - - * src/pkcs11.h: Make all constants UL that should be. - -2009-06-19 Werner Koch - - Release 1.3.0. - - * src/settings.h (SLOT_FIRMWARE_VERSION_MAJOR) - (SLOT_FIRMWARE_VERSION_MINOR, SLOT_HARDWARE_VERSION_MAJOR) - (SLOT_HARDWARE_VERSION_MINOR): Remove. - * src/p11-getslotinfo.c (CK_DEFINE_FUNCTION): Set firmware version - to Scute version and agent version to hardware version. - * src/agent.c (read_version_cb): New. - (agent_configure): Call that. - (agent_version_major, agent_version_minor): New. - (scute_agent_get_agent_version): New. - - * src/agent.c (SIG_LEN_2): Fix stupid c+p bug. - -2009-06-19 Marcus Brinkmann - - * src/Makefile.am (scute_deps): Add libgpg-error.a, libassuan.a. - (scute_libadd): New variable. - (libgpg-error.a, libassuan.a, clean-local): New targets. - (libscute_la_LIBADD): Add $(scute_libadd). - -2009-06-19 Werner Koch - - * src/agent.c (geteventcounter_status_cb): New. - (scute_agent_check_status): Check the eventcounter first. - -2009-06-19 Marcus Brinkmann - - * tests/t-getattribute.c (dump_object): Allow empty CKA_START_DATE - and CKA_END_DATE. - - * src/cert-object.c (scute_attr_prv): Always set CKA_START_DATE - and CKA_END_DATE. - -2009-06-19 Werner Koch - - * src/agent.c (MAX_SIGNATURE_LEN): Increase size to cope with 2048 - bit RSA. - (scute_agent_sign): Add a hack for 2048 bit RSA. - * tests/t-auth.c (sign_with_object): Increase SIZE to 256. - -2009-06-19 Marcus Brinkmann - - * libtool.m4: Removed. - * m4/libtool.m4, m4/ltoptions.m4, m4/ltsugar.m4, m4/ltversion.m4, - m4/lt~obsolete.m4: New files from libtool 2.2.6. - * configure.ac: Update to libtool 2.2.6. - (lt_cv_deplibs_check_method): Slightly evil hack to get libtool to - our thing. - (AC_DISABLE_STATIC, AC_LIBTOOL_WIN32_DLL, AC_LIBTOOL_RC) - (AC_PROG_LIBTOOL): Obsolete, replaced by ... - (LT_PREREQ, LT_INIT, LT_LANG): ... these new macro invocations. - * src/Makefile.am: Remove a bunch of rules for shared library. - (RCCOMPILE): New. - (LTRCCOMPILE): Use it here. - (.rc.lo): Add quoting. - -2009-06-19 Werner Koch - - * src/estream-printf.c, src/estream-printf.h: New. - * src/Makefile.am (sources): Add them. - * Makefile.am (SUBDIRS): Add m4/. - * m4/Makefile.am: New. - * m4/estream.m4: New. - * configure.ac (AC_REPLACE_FUNCS): Remove. - (estream_PRINTF_INIT): Add. - (AH_BOTTOM): Prefix estream fucntions. - (AC_FUNC_REALLOC) Remove because it uses AC_LIBOBJ which as - problems with the current libtool. The GNU guarantees for realloc - don't seem to be needed. - - * src/realloc.c: Remove - * src/vasprintf.c, src/stpcpy.c, src/stpcpy.h: Remove. - * src/support.h: Do not include stpcpy.h but define it inline. - Include estream-printf.h. - (vasprintf, asprintf, snprintf): Redefine to estream functions - - * src/agent.c (scute_agent_sign): s/sprintf/vsnprintf/. - -2009-06-18 Werner Koch - - * src/slots.c (slot_token_manufacturer): Update list. - -2009-04-23 Werner Koch - - * src/error-mapping.c (scute_gpg_err_to_ck): Add mappings to - CKR_PIN_INCORRECT and CKR_PIN_LOCKED. - -2008-12-03 Marcus Brinkmann - - * configure.ac: Enable AC_CONFIGU_MACRO_DIR. - * m4/ltsugar.m4, m4/libtool.m4, m4/ltversion.m4, - m4/lt~obsolete.m4, m4/ltoptions.m4: New files. - * config.guess, config.sub, ltmain.sh, configure.ac: Updated. - -2008-10-29 Marcus Brinkmann - - * configure.ac (_ASSUAN_ONLY_GPG_ERRORS): Define it. - * src/agent.c (default_inq_cb): Change return type to gpg_error_t - to silence gcc -W warning. - * src/cert-gpgsm.c (search_certs, export_cert_cb): Change type of - argument to silence gcc -W warning. - * src/p11-findobjects.c (CK_DEFINE_FUNCTION): Add explicit cast to - silence gcc -W warning. - * src/table.c (struct scute_table): Change signedness of - FIRST_FREE and LAST_USED members to silence gcc -W warning. - (scute_table_alloc): Change signedness of IDX for the same reason. - * tests/t-getslotinfo.c, tests/t-getsessioninfo.c, - tests/t-getmechanismlist.c, tests/t-auth.c, - tests/t-getattribute.c, tests/t-opensession.c, - tests/t-getslotlist.c, tests/t-getmechanisminfo.c, - tests/t-support.h, tests/t-closeallsessions.c, - tests/t-findobjects.c, tests/t-gettokeninfo.c: Change signedness - of some variables to silence gcc -W warnings. - -2008-10-21 Marcus Brinkmann - - * src/slots.c (slots_update_slot): Ignore card errors. - -2008-10-01 Marcus Brinkmann - - * src/agent.c (agent_connect): Set assuan log stream. - * src/p11-initialize.c: Include "debug.h". - (C_Initialize): Call _scute_debug_init. - * src/Makefile.am (sources): Add debug.c. - * src/debug.c: New file. - * src/debug.h: Rewritten. - * src/agent.c, src/cert-gpgsm.c, src/cert-object.c, - src/slots.c, src/error-mapping.c: More or improved or - adjusted debug output. - -2008-09-30 Marcus Brinkmann - - * src/cert-object.c [!CERT_PARSING]: Disable some certificate - parsing code. Unfortunately, we can't get rid of all of it for - now. - -2008-09-30 Marcus Brinkmann - - * src/get-path.c (find_program_in_inst_dir): New function. - (get_gpgsm_path, get_gpg_agent_path): Use it to check in install dir. - -2008-09-30 Werner Koch - - * src/Makefile.am (scute_DEPENDENCIES): Use .libs/versioninfo.o - - * AUTHORS (License): New. - - * Makefile.am (AUTOMAKE_OPTIONS): Do not distribute a gzip tarball. - (EXTRA_DIST): Distibute autogen.sh and README.SVN. - - * README.CVS: Replace by README.SVN. - - * configure.ac: Update bug address and some comments. - * autogen.sh: Update. - -2008-09-29 Marcus Brinkmann - - * src/gpgsm.c (struct search): New member WITH_CHAIN. - (search_cb): Only load chain if WITH_CHAIN is true. - (scute_gpgsm_get_cert): Call search_cb in the agent code path. - -2008-09-29 Marcus Brinkmann - - * src/slots.c (MIN): Remove macro. - (slot_token_maxpinlen, slot_token_pincount): Do not consider - second pincount, which meaning depends on the card version. - -2008-09-26 Marcus Brinkmann - - * src/agent.c: Include "cert.h". - (GET_CERT_INIT_SIZE): New symbol. - (struct get_cert_s): New struct. - (get_cert_data_cb, scute_agent_get_cert): New functions. - * src/gpgsm.c: Include "agent.h". - (scute_gpgsm_get_cert): Take extra argument NO. Use it to get the - certificate directly from the card, if possible. - * src/gpgsm.h (scute_gpgsm_get_cert): Add extra argument NO to - prototype. - * src/slots.c (slot_init): Pass extra argument to - scute_gpgsm_get_cert invocation. - * src/cert-object.c (scute_attr_prv, scute_attr_cert): Don't use - the fpr, timestamp and expire field of a certificate for now. - -2008-09-23 Marcus Brinkmann - - * src/agent.c (GET_CERT_INIT_SIZE): New symbol. - (struct get_cert_s): New struct. - (get_cert_data_cb, scute_agent_get_cert): New functions. - -2008-09-03 Marcus Brinkmann - - * src/Makefile.am (.rc.o): New rule. - - * src/Makefile.am (EXTRA_DIST): Add stpcpy.h. - -2008-09-02 Marcus Brinkmann - - * configure.ac: Post-release cleanup. - * doc/website/download.xhtml: Update. - -2008-09-02 Marcus Brinkmann - - * Released version 1.2.0. - - * doc/manual/Makefile.am (CLEANFILES): Add $(images_eps). - (images_eps): New variable. - (scute.dvi): Depend on $(images_eps) instead of $(images_pdf). - -2008-08-23 Marcus Brinkmann - - * src/Makefile.am [HAVE_W32_SYSTEM]: Build autonomous DLL. - -2008-08-23 Marcus Brinkmann - - * src/agent.c (gnupg_allow_set_foregound_window) - [!HAVE_W32_SYSTEM]: Define it. - -2008-08-23 Marcus Brinkmann - - * src/Makefile.am [HAVE_W32_SYSTEM]: Build autonomous DLL. - * src/dllmain.c (DllMain): New file. - * src/cert-gpgsm.c: Include "debug.h". Use - assuan_pipe_connect_ext instead of assuan_pipe_connect everywhere. - * src/agent.c (WINVER) [HAVE_W32_SYSTEM]: Define symbol. - [HAVE_W32_SYSTEM]: Include . Do this before including - . - (gnupg_allow_set_foregound_window): New function. - (agent_connect): Use Sleep() instead of _sleep(). - (default_inq_cb): New function, and use it in all transactions. - (agent_configure): Don't bail out if ttytname is not defined. Set - allow-pinentry-notify. - * tests/t-support.h [_WIN32]: Include . - (init_cryptoki) [_WIN32]: Call WSAStartup. - -2008-08-21 Marcus Brinkmann - - * src/scute.def: Start at @1 instead of @0. - -2008-08-21 Marcus Brinkmann - - * src/agent.c (agent_configure): Fix cut and paste error. - -2008-08-11 Marcus Brinkmann - - * src/agent.c (spawn_process_detachted) [! HAVE_W32_SYSTEM]: Remove. - (agent_configure): Ignore error with old versions of gpg-agent. - -2008-08-08 Marcus Brinkmann - - * configure.ac: Update svn macros. - (BUILD_REVISION, BUILD_FILEVERSION, BUILD_TIMESTAMP): New. - (AC_CONFIG_OUTPUT): Add src/versioninfo.rc. - (GPG_AGENT_DEFAULT, GPG_AGENT): New. - (AC_REPLACE_FUNCS): Add vasprintf and stpcpy. - (AC_CHECK_FUNCS): Add ttyname, localtime_r and timegm. - * src/stpcpy.h, src/stpcpy.c, src/realloc.c: New file from gnulib. - * src/vasprintf.c: New file from libiberty. - * src/support.h [!HAVE_STPCPY]: Include "stpcpy.h". - [!HAVE_TTYNAME]: Define simple replacement function. - (get_gpgsm_path, get_gpg_agent_path) - (default_homedir, make_filename): New prototypes. - * src/Makefile.am: Add W32 support. - (libscute_la_SOURCES): Add get-path.c. - (EXTRA_DIST): Add versioninfo.rc.in. - * src/versioninfo.rc.in: New file. - * src/get-path.c: New file. - * src/agent.c (PATHSEP_C): New macro. - (build_w32_commandline_copy) - (build_w32_commandline) [HAVE_W32_SYSTEM]: New functions. - (spawn_process_deatched): New function. - (agent_connect): Start gpg-agent if it is not running yet. - (agent_configure): Also pass xauthority and pinentry-user-data. - * src/cert-gpgsm.c (COMPAT_FALLBACK) [!HAVE_W32_SYSTEM]: New - macro. - (export_cert_compat) [!COMPAT_FALLBACK]: Remove. - (export_cert) [!COMPAT_FALLBACK]: Don't call export_cert_compat. - Don't create (unused) output pipe cruft. - * src/cert-object.c (time_to_ck_date) [!HAVE_LOCALTIME_R]: Fall - back to localtime. - * tests/t-getslotinfo.c (main) [WIN32]: Call _sleep instead sleep. - - * src/cryptoki.h (CRYPTOKI_EXPORTS): Define symbol. - * src/error-mapping.h: Do not include . - (scute_sys_to_ck): Change type of ERR to int. - * src/error-mapping.c: Do not include . - (scute_sys_to_ck): Change type of ERR to int. - * src/slots.c (slot_create_session): Change type of ERR to int. - -2007-05-03 Marcus Brinkmann - - Released version 1.1.0. - - * doc/manual/Makefile.am (images_pdf, CLEANFILES): New variables. - (scute.dvi, scute.pdf): New dependencies. - (%.eps, %.pdf): New rules. - * configure.ac: Check for convert and epstopdf. - - * doc/manual/scute.texi (Authentication With Service): Avoid - @indicateurl in TeX output, as this seems to be broken (in - texi2dvi 1.34). - - * doc/manual/Makefile.am (images, EXTRA_DIST): New variables. - -2007-04-30 Marcus Brinkmann - - * src/agent.h (scute_agent_is_trusted): New prototype. Include - . - * src/agent.c (scute_agent_is_trusted): New implementation. - * src/cert.h (struct cert): New member IS_TRUSTED. - * src/cert-gpgsm.c (export_cert): Set CERT->is_trusted. - * src/cert-object.c (scute_attr_cert): Set CKA_TRUSTED to - CERT->is_trusted. - * tests/t-getattribute.c: Support new option '--printable'. - - * src/table.c (scute_table_dealloc): Return, but not a value. - -2007-02-09 Marcus Brinkmann - - * src/pkcs11.h: Add definitions for SHA. - -2006-12-17 Marcus Brinkmann - - * src/pkcs11.h: Minor cosmetic changes. Require CRYPTOKI_GNU now - to switch on the GNU API, and do not check what CRYPTOKI_COMPAT is - defined to, just if it is defined at all. - - * src/pkcs11.h [__WIN32]: Changed to [_WIN32 || - CRYPTOKI_FORCE_WIN32] at the end. - Submitted by Alon Bar-Lev. - -2006-12-11 Marcus Brinkmann - - * src/pkcs11.h (CKO_VENDOR_DEFINED): Fixed syntax error. - -2006-12-10 Marcus Brinkmann - - * configure.ac (NEED_GPG_ERROR_VERSION): Bump to 1.4. - - * src/pkcs11.h [CRYPTOKI_COMPAT]: Rewrote the compatibility layer. - -2006-12-09 Marcus Brinkmann - - * src/pkcs11.h [__cplusplus]: Protect with extern "C". - Do not use the C++ keyword "template" in parameter lists. - Submitted by Alon Bar-Lev. - - * src/pkcs11.h [__WIN32]: Changed to [_WIN32 || - CRYPTOKI_FORCE_WIN32]. - (ck_rv_t): Changed to unsigned long. - (CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR, - CRYPTOKI_VERSION_REVISION): New macros. - (CKO_VENDOR_DEFINED, CKH_VENDOR_DEFINED, CKK_VENDOR_DEFINED, - CKC_VENDOR_DEFINED, CKA_VENDOR_DEFINED, CKM_VENDOR_DEFINED, - CKF_EXTENSION, CKR_VENDOR_DEFINED): Add cast to suppress compiler - warning. - Submitted by Alon Bar-Lev. - - * src/cryptoki.h (CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR): - Removed. - -2006-11-30 Marcus Brinkmann - - * m4/autobuild.m4: New file. - * configure.ac: Invoke AB_INIT. - -2006-11-29 Marcus Brinkmann - - * configure.ac (CFLAGS): Remove variable. - -2006-11-27 Marcus Brinkmann - - * src/pkcs11.h: Add more definitions provided by Andreas Jellinghaus. - - * README (Copyright and License): Update copyright notice. Also - for all other files. - * AUTHORS (Maintainer): Removed RSA Security Inc. - * include/pkcs11t.h, include/pkcs11f.h, include/pkcs11.h, - include/disclaimer.txt, include/cryptoki-w32.h, - include/cryptoki-generic.h, include/README, include/Makefile.am: - Files removed. - * configure.ac (AC_CONFIG_FILES): Removed include/Makefile. - * Makefile.am (SUBDIRS): Removed include directory. - -2006-11-24 Marcus Brinkmann - - * src/pkcs11.h: New file. - * src/Makefile.am (libscute_la_SOURCES): Add pkcs11.h. - * src/cryptoki.h: Include "pkcs11.h" instead of original PKCS #11 - header file. - * tests/t-support.h (mechanism_type_str): Remove most mechanisms. - -2006-11-23 Marcus Brinkmann - - * src/cert-gpgsm.c (search_certs_line): Don't overwrite CERT->uid. - -2006-11-21 Marcus Brinkmann - - * src/cert-gpgsm.c (search_certs_line): Fix off-by-one error. - (export_cert_cb): Fix bug if EXP->buffer_size is 0. - - * src/cert-gpgsm.c (cert_reset): Free CERT->cert_der if set. - (export_cert): Reimplement using data channel. - (export_cert_compat): This contains the old version for - compatibility. - * src/cert.h (MAX_CERT_SIZE): Macro removed. - (struct cert): Changed member CERT_DER into a pointer. - - * configure.ac (AC_CONFIG_FILES): Add doc/manual/Makefile. - * doc/Makefile.am (SUBDIRS): New variable. - * doc/manual/Makefile, doc/manual/scute.texi, doc/manual/gpl.texi, - doc/manual/mdate-sh, doc/manual/texinfo.tex, - doc/manual/firefox-cm.png, doc/manual/firefox-cm-view-detail.png, - doc/manual/firefox-cm-view.png, - doc/manual/firefox-dm-load-after.png, - doc/manual/firefox-dm-load-before.png, - doc/manual/firefox-dm-load.png, - doc/manual/firefox-dm-token-present.png, - doc/manual/firefox-pref.png, doc/manual/firefox-pref-view.png: New - files. - -2006-11-11 Marcus Brinkmann - - * Released version 1.0.0. - -2006-11-11 Marcus Brinkmann - - * src/error-mapping.c (scute_gpg_err_to_ck): Report error on debug - stream. - * src/slots.c (add_object): New function. - (slot_init): Rewritten using add_object. - * src/gpgsm.c: Include "gpgsm.h". - (struct search): Replace members ATTRP, ATTR_COUNTP, PRV_ATTRP, - PRV_ATTR_COUNTP by CERT_GET_CB, HOOK. - (search_cb): Rewritten to add all certificates for a certain key - (scute_gpgsm_get_cert): Take a callback function instead of - attribute pointers. - * gpgsm.h (scute_gpgsm_get_cert): Adjust prototype. - and also the certificate chain. - * src/cert.h (scute_gpgsm_search_certs_by_fpr): New prototype. - (struct cert): New member chain_id. - * src/cert-gpgsm.c (struct search_ctx_by_grip): Rename to ... - (struct search_ctx): ... this. Rename field GRIP to PATTERN, and - add new field FIELD. - (search_certs_by_grip): Rename function to ... - (search_certs): ... this. - (scute_gpgsm_search_certs_by_fpr): Change user of the above. - (scute_gpgsm_search_certs_by_fpr): New function. - (search_certs_line): Store chain ID. - -2006-11-07 Marcus Brinkmann - - * src/p11-gettokeninfo.c (C_GetTokenInfo): Fix assignment. - -2006-11-06 Marcus Brinkmann - - * doc/website/format/web.css: Set margin to 0. - - * configure.ac (AC_CONFIG_FILES): Add doc/Makefile. - Makefile.am (SUBDIRS): Add doc/. - doc/, doc/website/, doc/website/format: New directories. - doc/Makefile.am, doc/website/index.xhtml, - doc/website/documentation.xhtml, doc/website/download.xhtml, - doc/website/contact.xhtml, doc/website/format/web.css, - doc/website/format/scute-logo.svg, - doc/website/format/scute-border.jpg: New files. - -2006-10-30 Marcus Brinkmann - - * configure.ac (PACKAGE, VERSION): Define these variables. - * src/Makefile.am (libscute_la_CPPFLAGS): Fix include path for - VPATH builds. - - * configure.ac (VERSION_MAJOR, VERSION_MINOR): New variable - definitions. - * src/gpgsm.h: Fix syntax error. - * src/table.c, src/table.h: Rewritten. - * src/slots.c: Reorganized and rewritten to use the new table - interface. Include gpgsm.h. - * src/p11-signinit.c, src/p11-sign.c, src/p11-getslotlist.c, - src/p11-getsessioninfo.c, src/p11-getmechanismlist.c, - src/p11-getattributevalue.c, src/p11-findobjectsinit.c, - src/p11-findobjectsfinal.c, src/p11-findobjects.c, - src/p11-closesession.c: Adjust callers. - -2006-10-26 Marcus Brinkmann - - * src/settings.h: Require VERSION_MAJOR and VERSION_MINOR to be - defined. - - * src/p11-getinfo.c (CRYPTOKI_VERSION_MAJOR, - CRYPTOKI_VERSION_MINOR): Move macros to ... - * src/cryptoki.h (CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR): - ... here - - * src/gpgsm.c (gpgsm_get_cert): Rename to ... - (scute_gpgsm_get_cert): ... this. - * src/gpgsm.h: New file. - * src/Makefile.am (libscute_la_SOURCES): Add gpgsm.h. - * src/slots.c (gpgsm_get_cert): Remove prototype. - (slots_update_slot): Call scute_gpgsm_get_cert, not gpgsm_get_cert. - - * src/error-mapping.c (scute_gpg_err_to_ck): Map GPG_ERR_NO_AGENT - to CKR_GENERAL_ERROR. - * src/agent.h (struct agent_card_info_s): Remove member error. - Prefix external functions with scute_ if not already done so, also - for callers. - * src/agent.c: Include . Replace one-letter variable - names by proper ones. Replace assuan_error_t with gpg_error_t - everywhere. - (agent_connect, agent_simple_cmd, agent_configure): New functions. - (scute_agent_initialize): Use these new functions. - ing of common code. Lots of cleanups. - (scute_agent_finalize): Clear agent_ctx. Add debug message. - -2006-10-13 Werner Koch - - * src/cert-gpgsm.c (MAX_LINE_LEN): Increased. - - * src/locking.c: Include string.h for memset declaration. - - * configure.ac: New option --disable-optimization. - -2006-08-02 Marcus Brinkmann - - * Initial version. - - - Copyright 2006, 2007, 2008 g10 Code GmbH - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Dummy ChangeLog - the old one is build-aus/git-log-footer diff --git a/Makefile.am b/Makefile.am index 808a956..0054d99 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,7 +22,7 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip -EXTRA_DIST = autogen.sh README.GIT +EXTRA_DIST = autogen.sh README.GIT VERSION if RUN_TESTS tests = tests @@ -31,3 +31,33 @@ tests = endif SUBDIRS = m4 src ${tests} doc + +dist-hook: gen-ChangeLog + +distcheck-hook: + set -e; ( \ + pref="#+macro: scute_" ;\ + reldate="$$(date -u +%Y-%m-%d)" ;\ + echo "$${pref}ver $(PACKAGE_VERSION)" ;\ + echo "$${pref}date $${reldate}" ;\ + list='$(DIST_ARCHIVES)'; for i in $$list; do \ + case "$$i" in *.tar.bz2) \ + echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ + echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ + echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ + esac;\ + done ) | tee $(distdir).swdb + +.PHONY: gen-ChangeLog release sign-release + +gen_start_date = 2011-12-01T00:00:00 +gen-ChangeLog: + if test -d $(top_srcdir)/.git; then \ + (cd $(top_srcdir) && \ + $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ + --amend=build-aux/git-log-fix \ + --since=$(gen_start_date) ) > $(distdir)/cl-t; \ + cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\ + rm -f $(distdir)/ChangeLog; \ + mv $(distdir)/cl-t $(distdir)/ChangeLog; \ + fi diff --git a/autogen.sh b/autogen.sh index 10cc203..1c6e428 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,6 +1,6 @@ #! /bin/sh # autogen.sh -# Copyright (C) 2003, 2014 g10 Code GmbH +# Copyright (C) 2003, 2014, 2017, 2018 g10 Code GmbH # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without @@ -15,7 +15,7 @@ # configure it for the respective package. It is maintained as part of # GnuPG and source copied by other packages. # -# Version: 2014-06-06 +# Version: 2018-07-10 configure_ac="configure.ac" @@ -74,13 +74,23 @@ PRINT_HOST=no PRINT_BUILD=no tmp=$(dirname "$0") tsdir=$(cd "${tmp}"; pwd) -version_parts=3 if [ -n "${AUTOGEN_SH_SILENT}" ]; then SILENT=" --silent" fi if test x"$1" = x"--help"; then - echo "usage: ./autogen.sh [--silent] [--force] [--build-TYPE] [ARGS]" + echo "usage: ./autogen.sh [OPTIONS] [ARGS]" + echo " Options:" + echo " --silent Silent operation" + echo " --force Pass --force to autoconf" + echo " --find-version Helper for configure.ac" + echo " --git-build Run all commands to build from a Git" + echo " --print-host Print only the host triplet" + echo " --print-build Print only the build platform triplet" + echo " --build-TYPE Configure to cross build for TYPE" + echo "" + echo " ARGS are passed to configure in --build-TYPE mode." + echo " Configuration for this script is expected in autogen.rc" exit 0 fi if test x"$1" = x"--silent"; then @@ -149,6 +159,10 @@ case "$1" in SILENT=" --silent" shift ;; + --git-build) + myhost="git-build" + shift + ;; --build-w32) myhost="w32" shift @@ -177,6 +191,25 @@ esac die_p +# **** GIT BUILD **** +# This is a helper to build from git. +if [ "$myhost" = "git-build" ]; then + tmp="$(pwd)" + cd "$tsdir" || fatal "error cd-ing to $tsdir" + ./autogen.sh || fatal "error running ./autogen.sh" + cd "$tmp" || fatal "error cd-ing back to $tmp" + die_p + "$tsdir"/configure || fatal "error running $tsdir/configure" + die_p + make || fatal "error running make" + die_p + make check || fatal "error running male check" + die_p + exit 0 +fi +# **** end GIT BUILD **** + + # Source our configuration if [ -f "${tsdir}/autogen.rc" ]; then . "${tsdir}/autogen.rc" @@ -200,32 +233,41 @@ if [ "$myhost" = "find-version" ]; then minor="$3" micro="$4" - case "$version_parts" in - 2) - matchstr1="$package-$major.[0-9]*" - matchstr2="$package-$major-base" - vers="$major.$minor" - ;; - *) - matchstr1="$package-$major.$minor.[0-9]*" - matchstr2="$package-$major.$minor-base" - vers="$major.$minor.$micro" - ;; - esac + if [ -z "$package" -o -z "$major" -o -z "$minor" ]; then + echo "usage: ./autogen.sh --find-version PACKAGE MAJOR MINOR [MICRO]" >&2 + exit 1 + fi + + if [ -z "$micro" ]; then + matchstr1="$package-$major.[0-9]*" + matchstr2="$package-$major-base" + vers="$major.$minor" + else + matchstr1="$package-$major.$minor.[0-9]*" + matchstr2="$package-$major.$minor-base" + vers="$major.$minor.$micro" + fi beta=no if [ -e .git ]; then ingit=yes tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null) + tmp=$(echo "$tmp" | sed s/^"$package"//) if [ -n "$tmp" ]; then - tmp=$(echo "$tmp"|awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') + tmp=$(echo "$tmp" | sed s/^"$package"// \ + | awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') else tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null \ - | awk -F- '$4!=0{print"-beta"$4}') + | awk -F- '$4!=0{print"-beta"$4}') + if [ -z "$tmp" ]; then + tmp=$(git describe --match "${package}-default-base" \ + --long 2>/dev/null | awk -F- '$4!=0{print"-beta"$4}') + fi + fi [ -n "$tmp" ] && beta=yes rev=$(git rev-parse --short HEAD | tr -d '\n\r') - rvd=$((0x$(echo ${rev} | head -c 4))) + rvd=$((0x$(echo ${rev} | dd bs=1 count=4 2>/dev/null))) else ingit=no beta=yes @@ -311,7 +353,7 @@ if [ "$myhost" = "w32" ]; then $tsdir/configure --enable-maintainer-mode ${SILENT} \ --prefix=${w32root} \ --host=${host} --build=${build} SYSROOT=${w32root} \ - PKG_CONFIG_LIBDIR=${w32root} \ + PKG_CONFIG_LIBDIR=${w32root}/lib/pkgconfig \ ${configure_opts} ${extraoptions} "$@" rc=$? exit $rc @@ -417,13 +459,16 @@ fi # Check the git setup. if [ -d .git ]; then - CP="cp -a" - [ -z "${SILENT}" ] && CP="$CP -v" + CP="cp -p" + # If we have a GNU cp we can add -v + if cp --version >/dev/null 2>/dev/null; then + [ -z "${SILENT}" ] && CP="$CP -v" + fi if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then [ -z "${SILENT}" ] && cat < Release 1.4.0. @@ -130,7 +132,7 @@ * src/support.h: Do not include stpcpy.h but define it inline. Include estream-printf.h. (vasprintf, asprintf, snprintf): Redefine to estream functions - + * src/agent.c (scute_agent_sign): s/sprintf/vsnprintf/. 2009-06-18 Werner Koch @@ -262,7 +264,7 @@ * doc/manual/Makefile.am (CLEANFILES): Add $(images_eps). (images_eps): New variable. (scute.dvi): Depend on $(images_eps) instead of $(images_pdf). - + 2008-08-23 Marcus Brinkmann * src/Makefile.am [HAVE_W32_SYSTEM]: Build autonomous DLL. @@ -300,7 +302,7 @@ 2008-08-11 Marcus Brinkmann * src/agent.c (spawn_process_detachted) [! HAVE_W32_SYSTEM]: Remove. - (agent_configure): Ignore error with old versions of gpg-agent. + (agent_configure): Ignore error with old versions of gpg-agent. 2008-08-08 Marcus Brinkmann @@ -491,7 +493,7 @@ (search_cb): Rewritten to add all certificates for a certain key (scute_gpgsm_get_cert): Take a callback function instead of attribute pointers. - * gpgsm.h (scute_gpgsm_get_cert): Adjust prototype. + * gpgsm.h (scute_gpgsm_get_cert): Adjust prototype. and also the certificate chain. * src/cert.h (scute_gpgsm_search_certs_by_fpr): New prototype. (struct cert): New member chain_id. diff --git a/configure.ac b/configure.ac index 75262a6..9b0f4fd 100644 --- a/configure.ac +++ b/configure.ac @@ -104,6 +104,9 @@ AH_VERBATIM([_REENTRANT], # Checks for programs. AC_PROG_CC +# Note: A suitable gitlog-to-changelog script can be found in GnuPG master. +AC_CHECK_PROGS(GITLOG_TO_CHANGELOG, gitlog-to-changelog, [gitlog-to-changelog]) + # # Setup gcc specific options # diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 index e85f511..a9d572f 100644 --- a/m4/gpg-error.m4 +++ b/m4/gpg-error.m4 @@ -1,5 +1,5 @@ # gpg-error.m4 - autoconf macro to detect libgpg-error. -# Copyright (C) 2002, 2003, 2004 g10 Code GmbH +# Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018 g10 Code GmbH # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without @@ -8,58 +8,181 @@ # This file is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Last-changed: 2018-11-02 + dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS +dnl +dnl Test for libgpg-error and define GPG_ERROR_CFLAGS, GPG_ERROR_LIBS, +dnl GPG_ERROR_MT_CFLAGS, and GPG_ERROR_MT_LIBS. The _MT_ variants are +dnl used for programs requireing real multi thread support. +dnl +dnl If a prefix option is not used, the config script is first +dnl searched in $SYSROOT/bin and then along $PATH. If the used +dnl config script does not match the host specification the script +dnl is added to the gpg_config_script_warn variable. dnl AC_DEFUN([AM_PATH_GPG_ERROR], -[ AC_ARG_WITH(gpg-error-prefix, - AC_HELP_STRING([--with-gpg-error-prefix=PFX], - [prefix where GPG Error is installed (optional)]), - gpg_error_config_prefix="$withval", gpg_error_config_prefix="") - if test x$gpg_error_config_prefix != x ; then - if test x${GPG_ERROR_CONFIG+set} != xset ; then - GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config +[ AC_REQUIRE([AC_CANONICAL_HOST]) + gpg_error_config_prefix="" + dnl --with-libgpg-error-prefix=PFX is the preferred name for this option, + dnl since that is consistent with how our three siblings use the directory/ + dnl package name in --with-$dir_name-prefix=PFX. + AC_ARG_WITH(libgpg-error-prefix, + AC_HELP_STRING([--with-libgpg-error-prefix=PFX], + [prefix where GPG Error is installed (optional)]), + [gpg_error_config_prefix="$withval"]) + + dnl Accept --with-gpg-error-prefix and make it work the same as + dnl --with-libgpg-error-prefix above, for backwards compatibility, + dnl but do not document this old, inconsistently-named option. + AC_ARG_WITH(gpg-error-prefix,, + [gpg_error_config_prefix="$withval"]) + + if test x"${GPG_ERROR_CONFIG}" = x ; then + if test x"${gpg_error_config_prefix}" != x ; then + GPG_ERROR_CONFIG="${gpg_error_config_prefix}/bin/gpg-error-config" + else + case "${SYSROOT}" in + /*) + if test -x "${SYSROOT}/bin/gpg-error-config" ; then + GPG_ERROR_CONFIG="${SYSROOT}/bin/gpg-error-config" + fi + ;; + '') + ;; + *) + AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.]) + ;; + esac fi fi AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no) - min_gpg_error_version=ifelse([$1], ,0.0,$1) - AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version) + min_gpg_error_version=ifelse([$1], ,1.33,$1) ok=no - if test "$GPG_ERROR_CONFIG" != "no" ; then + + if test "$prefix" = NONE ; then + prefix_option_expanded=/usr/local + else + prefix_option_expanded="$prefix" + fi + if test "$exec_prefix" = NONE ; then + exec_prefix_option_expanded=$prefix_option_expanded + else + exec_prefix_option_expanded=$(prefix=$prefix_option_expanded eval echo $exec_prefix) + fi + libdir_option_expanded=$(prefix=$prefix_option_expanded exec_prefix=$exec_prefix_option_expanded eval echo $libdir) + + if test -f $libdir_option_expanded/pkgconfig/gpg-error.pc; then + gpgrt_libdir=$libdir_option_expanded + else + if crt1_path=$(${CC:-cc} -print-file-name=crt1.o 2>/dev/null); then + if possible_libdir=$(cd ${crt1_path%/*} && pwd 2>/dev/null); then + if test -f $possible_libdir/pkgconfig/gpg-error.pc; then + gpgrt_libdir=$possible_libdir + fi + fi + fi + fi + + if test "$GPG_ERROR_CONFIG" = "no" -a -n "$gpgrt_libdir"; then + AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no) + if test "$GPGRT_CONFIG" = "no"; then + unset GPGRT_CONFIG + else + GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" + if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then + GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error" + AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config]) + gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion` + else + unset GPGRT_CONFIG + fi + fi + else + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + fi + if test "$GPG_ERROR_CONFIG" != "no"; then req_major=`echo $min_gpg_error_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` req_minor=`echo $min_gpg_error_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version` major=`echo $gpg_error_config_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` minor=`echo $gpg_error_config_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` if test "$major" -gt "$req_major"; then ok=yes - else + else if test "$major" -eq "$req_major"; then if test "$minor" -ge "$req_minor"; then ok=yes fi fi fi + if test -z "$GPGRT_CONFIG" -a -n "$gpgrt_libdir"; then + if test "$major" -gt 1 -o "$major" -eq 1 -a "$minor" -ge 33; then + AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no) + if test "$GPGRT_CONFIG" = "no"; then + unset GPGRT_CONFIG + else + GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" + if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then + GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error" + AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config]) + else + unset GPGRT_CONFIG + fi + fi + fi + fi fi + AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version) if test $ok = yes; then - GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags` - GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs` - AC_MSG_RESULT(yes) + GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG --cflags` + GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG --libs` + if test -z "$GPGRT_CONFIG"; then + GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --mt --cflags 2>/dev/null` + GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --mt --libs 2>/dev/null` + else + GPG_ERROR_MT_CFLAGS=`$GPG_ERROR_CONFIG --variable=mtcflags 2>/dev/null` + GPG_ERROR_MT_CFLAGS="$GPG_ERROR_CFLAGS${GPG_ERROR_CFLAGS:+ }$GPG_ERROR_MT_CFLAGS" + GPG_ERROR_MT_LIBS=`$GPG_ERROR_CONFIG --variable=mtlibs 2>/dev/null` + GPG_ERROR_MT_LIBS="$GPG_ERROR_LIBS${GPG_ERROR_LIBS:+ }$GPG_ERROR_MT_LIBS" + fi + AC_MSG_RESULT([yes ($gpg_error_config_version)]) ifelse([$2], , :, [$2]) + if test -z "$GPGRT_CONFIG"; then + gpg_error_config_host=`$GPG_ERROR_CONFIG --host 2>/dev/null || echo none` + else + gpg_error_config_host=`$GPG_ERROR_CONFIG --variable=host 2>/dev/null || echo none` + fi + if test x"$gpg_error_config_host" != xnone ; then + if test x"$gpg_error_config_host" != x"$host" ; then + AC_MSG_WARN([[ +*** +*** The config script "$GPG_ERROR_CONFIG" was +*** built for $gpg_error_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-libgpg-error-prefix +*** to specify a matching config script or use \$SYSROOT. +***]]) + gpg_config_script_warn="$gpg_config_script_warn libgpg-error" + fi + fi else GPG_ERROR_CFLAGS="" GPG_ERROR_LIBS="" + GPG_ERROR_MT_CFLAGS="" + GPG_ERROR_MT_LIBS="" AC_MSG_RESULT(no) ifelse([$3], , :, [$3]) fi AC_SUBST(GPG_ERROR_CFLAGS) AC_SUBST(GPG_ERROR_LIBS) + AC_SUBST(GPG_ERROR_MT_CFLAGS) + AC_SUBST(GPG_ERROR_MT_LIBS) ]) - commit 9a25f7bb80c292f05cc4b58c2b8caf5252bbccb0 Author: Werner Koch Date: Wed Feb 20 10:33:05 2019 +0100 Remove GNU-isms from the doc Makefiles. Signed-off-by: Werner Koch diff --git a/doc/Makefile.am b/doc/Makefile.am index 3f77522..ceeff0c 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -19,9 +19,13 @@ ## Process this file with automake to produce Makefile.in -website = index.xhtml documentation.xhtml download.xhtml contact.xhtml \ - format/web.css format/scute-logo.svg format/scute-border.jpg - -EXTRA_DIST = $(addprefix website/, $(website)) +EXTRA_DIST = \ + website/contact.xhtml / + website/documentation.xhtml / + website/download.xhtml / + website/index.xhtml / + website/format/scute-border.jpg / + website/format/scute-logo.svg / + website/format/web.css SUBDIRS = manual diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index a3b8321..4d37147 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -19,8 +19,6 @@ ## Process this file with automake to produce Makefile.in -DISTCLEANFILES = scute.tmp - images = firefox-cm.png firefox-cm-view-detail.png firefox-cm-view.png \ firefox-dm-load-after.png firefox-dm-load-before.png \ firefox-dm-load.png firefox-dm-token-present.png firefox-pref.png \ @@ -29,22 +27,40 @@ images = firefox-cm.png firefox-cm-view-detail.png firefox-cm-view.png \ libreoffice-certificate-selection.png \ libreoffice-digital-signatures.png libreoffice-pdf-signature.png -images_eps = $(images:.png=.eps) +# The same as images but eps suffix. +images_eps = firefox-cm.eps firefox-cm-view-detail.eps firefox-cm-view.eps \ + firefox-dm-load-after.eps firefox-dm-load-before.eps \ + firefox-dm-load.eps firefox-dm-token-present.eps firefox-pref.eps \ + firefox-pref-view.eps firefox-bad-pin.eps \ + thunderbird-account-settings.eps thunderbird-smime-button.eps \ + libreoffice-certificate-selection.eps \ + libreoffice-digital-signatures.eps libreoffice-pdf-signature.eps + EXTRA_DIST = $(images) -CLEANFILES = $(images_eps) + +CLEANFILES = $(images_eps) +DISTCLEANFILES = scute.tmp + +BUILT_SOURCES = $(images_eps) info_TEXINFOS = scute.texi scute_TEXINFOS = lesser.texi -scute.html: scute.texi $(foreach i,$(images),scute.html/$(i)) - $(MAKEINFO) --html --output "$@" "$<" -scute.html/%.png: %.png - @mkdir -p scute.html - cp -v "$<" "$@" - -scute.dvi: $(images_eps) -scute.pdf: $(images) +.png.eps: + $(CONVERT) `test -f '$<' || echo '$(srcdir)/'`$< $@ -%.eps : %.png +.png.pdf: $(CONVERT) `test -f '$<' || echo '$(srcdir)/'`$< $@ + + +# Do not include the generated EPS files. +dist-hook: + cd $(distdir) && rm -f $(images_eps) + + +# Make sure that scute.texi is touched if any other source file has +# been modified. This is required so that the version.texi magic +# updates the release date. +scute.texi : $(scute_TEXINFOS) $(images) + touch $(srcdir)/scute.texi diff --git a/doc/manual/scute.texi b/doc/manual/scute.texi index b27da91..1d699a9 100644 --- a/doc/manual/scute.texi +++ b/doc/manual/scute.texi @@ -30,7 +30,7 @@ license can be found in the section entitled ``Library Copying''. The Scute Manual 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 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. @end ifinfo @@ -60,7 +60,7 @@ license can be found in the section entitled ``Library Copying''. The Scute Manual 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. +lesser General Public License for more details. @end titlepage @page commit b623ff524e63391f01aa075686b7004e8a0ceb91 Author: Werner Koch Date: Wed Feb 20 09:35:28 2019 +0100 Update libtool and add usual defines for macOS. * m4/libtool.m4: Update from gpgme. * configure.ac (_DARWIN_C_SOURCE): Define from macOS. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 5c4a98a..75262a6 100644 --- a/configure.ac +++ b/configure.ac @@ -204,6 +204,7 @@ AC_DEFINE_UNQUOTED(VERSION_MINOR, $VERSION_MINOR, [Minor version number]) # all safety checks here. We are driving without seat belts now! # http://lists.cairographics.org/archives/cairo/2009-April/016962.html lt_cv_deplibs_check_method=pass_all + LT_PREREQ([2.2.6]) LT_INIT([win32-dll disable-static]) LT_LANG([Windows Resource]) @@ -218,6 +219,11 @@ case "${host}" in *-*-gnu*) have_ld_version_script=yes ;; + *-apple-darwin*) + AC_DEFINE(_DARWIN_C_SOURCE, 900000L, + Expose all libc features (__DARWIN_C_FULL).) + AC_DEFINE(_XOPEN_SOURCE, 500, Activate POSIX interface on MacOS X) + ;; esac AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") diff --git a/m4/libtool.m4 b/m4/libtool.m4 index d7c043f..0d340c7 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -34,7 +34,7 @@ m4_define([_LT_COPYING], [dnl # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# can be downloaded from https://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) @@ -1196,7 +1196,7 @@ fi # Invoke $ECHO with all args, space-separated. func_echo_all () { - $ECHO "$*" + $ECHO "$*" } case "$ECHO" in @@ -1312,7 +1312,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -1324,19 +1324,9 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*) - LD="${LD-ld} -m elf32lppclinux" + LD="${LD-ld} -m elf_i386" ;; - powerpc64-*) + ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1355,10 +1345,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - powerpcle-*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*) + ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -1701,8 +1688,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else @@ -2526,6 +2512,17 @@ freebsd* | dragonfly*) esac ;; +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -2642,7 +2639,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) +linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no @@ -3258,6 +3255,10 @@ freebsd* | dragonfly*) fi ;; +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -3296,7 +3297,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) +linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -4048,7 +4049,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4347,7 +4348,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) @@ -4772,7 +4773,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; @@ -5149,7 +5150,7 @@ _LT_EOF shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; @@ -6148,7 +6149,7 @@ if test "$_lt_caught_CXX_error" != yes; then shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; @@ -6189,7 +6190,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; @@ -6240,6 +6241,9 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; + gnu*) + ;; + haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -6401,7 +6405,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler commit cc91c168e4aecc292f95156a96d9fd96e449d8b1 Author: Werner Koch Date: Wed Feb 20 09:29:42 2019 +0100 Make C_Sign error handling spec compliant. * src/slots.c (session_sign): Clear the flag sign-initialized flag on error. * src/p11-signinit.c (C_SignInit): Minor rework. * src/p11-sign.c (C_Sign): Ditto. Signed-off-by: Werner Koch diff --git a/src/p11-sign.c b/src/p11-sign.c index 870f08c..4f2ae7d 100644 --- a/src/p11-sign.c +++ b/src/p11-sign.c @@ -37,8 +37,12 @@ * If the function returns CKR_BUFFER_TOO_SMALL no further C_SignInit * is required, instead the function can be called again with a larger * buffer. On a successful operation CKR_OK is returned and other - * signatures may be created without an new C_SignInit. On all other + * signatures may be created without a new C_SignInit. On all other * return codes a new C_SignInit is required. + * + * In contrast to the specs the return code CKR_ARGUMENTS_BAD may not + * require a new C_SignInit because this can be considered a bug in + * the caller's code. */ CK_RV CK_SPEC C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, @@ -46,7 +50,7 @@ C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, { CK_RV err = CKR_OK; slot_iterator_t slot; - session_iterator_t session; + session_iterator_t sid; if (pData == NULL_PTR || pulSignatureLen == NULL_PTR) return CKR_ARGUMENTS_BAD; @@ -55,18 +59,11 @@ C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, if (err) return err; - err = slots_lookup_session (hSession, &slot, &session); - if (err) - goto out; - - /* FIXME: Check that C_SignInit has been called. */ - - err = session_sign (slot, session, pData, ulDataLen, - pSignature, pulSignatureLen); + err = slots_lookup_session (hSession, &slot, &sid); + if (!err) + err = session_sign (slot, sid, pData, ulDataLen, + pSignature, pulSignatureLen); - out: - /* FIXME: Update the flag which indicates whether C_SignInit has - * been called. */ scute_global_unlock (); return err; } diff --git a/src/p11-signinit.c b/src/p11-signinit.c index 2c54502..a529262 100644 --- a/src/p11-signinit.c +++ b/src/p11-signinit.c @@ -38,7 +38,7 @@ C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, { CK_RV err = CKR_OK; slot_iterator_t slot; - session_iterator_t session; + session_iterator_t sid; if (pMechanism == NULL_PTR || pMechanism->mechanism != CKM_RSA_PKCS) return CKR_ARGUMENTS_BAD; @@ -50,13 +50,10 @@ C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, if (err) return err; - err = slots_lookup_session (hSession, &slot, &session); - if (err) - goto out; - - err = session_set_signing_key (slot, session, hKey); + err = slots_lookup_session (hSession, &slot, &sid); + if (!err) + err = session_set_signing_key (slot, sid, hKey); - out: scute_global_unlock (); return err; } diff --git a/src/slots.c b/src/slots.c index c97bbb8..ca6a015 100644 --- a/src/slots.c +++ b/src/slots.c @@ -992,7 +992,8 @@ session_get_search_result (slot_iterator_t id, session_iterator_t sid, } -/* Set the signing key for session SID in slot ID to KEY. */ +/* Set the signing key for session SID in slot ID to KEY. This is the + * core of C_SignInit. */ CK_RV session_set_signing_key (slot_iterator_t id, session_iterator_t sid, object_iterator_t key) @@ -1027,8 +1028,7 @@ session_set_signing_key (slot_iterator_t id, session_iterator_t sid, } -/* FIXME: The description is wrong: - Set the signing key for session SID in slot ID to KEY. */ +/* The core of C_Sign - see there for a description. */ CK_RV session_sign (slot_iterator_t id, session_iterator_t sid, CK_BYTE_PTR pData, CK_ULONG ulDataLen, @@ -1036,6 +1036,7 @@ session_sign (slot_iterator_t id, session_iterator_t sid, { struct slot *slot = scute_table_data (slots, id); struct session *session = scute_table_data (slot->sessions, sid); + int rc; gpg_error_t err; CK_ATTRIBUTE_PTR attr; CK_ULONG attr_count; @@ -1051,24 +1052,36 @@ session_sign (slot_iterator_t id, session_iterator_t sid, if (!session->signing_key) return CKR_OPERATION_NOT_INITIALIZED; - err = slot_get_object (id, session->signing_key, &attr, &attr_count); - if (err) - return err; + rc = slot_get_object (id, session->signing_key, &attr, &attr_count); + if (rc) + goto leave; if (attr_count == (CK_ULONG) -1) - return CKR_KEY_HANDLE_INVALID; + { + rc = CKR_KEY_HANDLE_INVALID; + goto leave; + } if (attr->ulValueLen != sizeof (key_class) || memcmp (attr->pValue, &key_class, sizeof (key_class))) - return CKR_KEY_HANDLE_INVALID; + { + rc = CKR_KEY_HANDLE_INVALID; + goto leave; + } /* Find the CKA_ID */ for (i = 0; i < attr_count; i++) if (attr[i].type == CKA_ID) break; if (i == attr_count) - return CKR_GENERAL_ERROR; + { + rc = CKR_GENERAL_ERROR; + goto leave; + } if (attr[i].ulValueLen >= sizeof key_id - 1) - return CKR_GENERAL_ERROR; + { + rc = CKR_GENERAL_ERROR; + goto leave; + } strncpy (key_id, attr[i].pValue, attr[i].ulValueLen); key_id[attr[i].ulValueLen] = 0; DEBUG (DBG_INFO, "Found CKA_ID '%s'", key_id); @@ -1076,16 +1089,19 @@ session_sign (slot_iterator_t id, session_iterator_t sid, ; if (*keyref) keyref++; /* Point to the grip. */ - DEBUG (DBG_INFO, "Using keyref '%s'", keyref); sig_len = *pulSignatureLen; err = scute_agent_sign (keyref, pData, ulDataLen, pSignature, &sig_len); - /* Take care of error codes which are not mapped by default. */ if (gpg_err_code (err) == GPG_ERR_INV_LENGTH) - return CKR_BUFFER_TOO_SMALL; + rc = CKR_BUFFER_TOO_SMALL; else if (gpg_err_code (err) == GPG_ERR_INV_ARG) - return CKR_ARGUMENTS_BAD; + rc = CKR_ARGUMENTS_BAD; else - return scute_gpg_err_to_ck (err); + rc = scute_gpg_err_to_ck (err); + + leave: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) + session->signing_key = 0; + return rc; } ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 + ChangeLog | 594 +--------------------------------- Makefile.am | 32 +- autogen.sh | 95 ++++-- build-aux/git-log-fix | 3 + ChangeLog => build-aux/git-log-footer | 10 +- configure.ac | 9 + doc/Makefile.am | 12 +- doc/manual/Makefile.am | 42 ++- doc/manual/scute.texi | 4 +- m4/gpg-error.m4 | 159 +++++++-- m4/libtool.m4 | 64 ++-- src/p11-sign.c | 23 +- src/p11-signinit.c | 11 +- src/slots.c | 46 ++- 15 files changed, 382 insertions(+), 723 deletions(-) create mode 100644 build-aux/git-log-fix copy ChangeLog => build-aux/git-log-footer (99%) hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 20 13:17:08 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 20 Feb 2019 13:17:08 +0100 Subject: [git] Scute - branch, master, updated. scute-1.5.0-20-ga3dc060 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 "PKCS#11 token on top of gpg-agent". The branch, master has been updated via a3dc060e32a52e3a094c3af84e432c832b511da9 (commit) from 6f61c173cf2b71b43f41f163d590ef127b68509e (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 a3dc060e32a52e3a094c3af84e432c832b511da9 Author: Werner Koch Date: Wed Feb 20 13:14:46 2019 +0100 Fix gcc warnings when building for Windows. * m4/estream.m4: Remove file. * configure.ac (estream_PRINTF_INIT): Remove. Estream is part of libgpg-error. (AC_CHECK_FUNCS): Move to a later place. * src/agent.c [W32]: Explictly include winsock2.h to avoid a warning. (gnupg_allow_set_foregound_window): Fix printf warning. * src/support.h (ttyname): Mark unsused arg. (stpcpy): Move to ... * src/get-path.c (my_stpcpy): here. Use macros to get around warning pertaining to the gcc built-in. (dlopen): Mark unused arg. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 9b0f4fd..e36f56d 100644 --- a/configure.ac +++ b/configure.ac @@ -262,13 +262,6 @@ AC_SUBST(BUILD_REVISION_DEC) AC_SUBST(BUILD_TIMESTAMP) AC_SUBST(BUILD_FILEVERSION) -# Checks for libraries. - -AC_CHECK_FUNCS([ttyname localtime_r timegm stpcpy]) - -# Run the checks needed for estream-printf.c -estream_PRINTF_INIT - # The error code library. Error codes are sent over the IPC layer and # have to be interpreted. AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", @@ -416,6 +409,7 @@ AC_HEADER_STDBOOL AC_C_INLINE # Checks for library functions. +AC_CHECK_FUNCS([ttyname localtime_r timegm stpcpy]) # Check for programs needed for the manual. AC_CHECK_PROG(CONVERT, convert, convert) diff --git a/m4/Makefile.am b/m4/Makefile.am index bff7b15..cbcd9a8 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -1,2 +1,2 @@ -EXTRA_DIST = estream.m4 autobuild.m4 gpg-error.m4 libassuan.m4 libtool.m4 \ +EXTRA_DIST = autobuild.m4 gpg-error.m4 libassuan.m4 libtool.m4 \ ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4 diff --git a/m4/estream.m4 b/m4/estream.m4 deleted file mode 100644 index 4b6c745..0000000 --- a/m4/estream.m4 +++ /dev/null @@ -1,48 +0,0 @@ -dnl Autoconf macros for libestream -dnl Copyright (C) 2007 g10 Code GmbH -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl estream_PRINTF_INIT -dnl Prepare build of source included estream-printf.c -dnl -AC_DEFUN([estream_PRINTF_INIT], -[ - AC_MSG_NOTICE([checking system features for estream-printf]) - AC_TYPE_LONG_LONG_INT - AC_TYPE_LONG_DOUBLE - AC_TYPE_INTMAX_T - AC_TYPE_UINTMAX_T - AC_CHECK_TYPES([ptrdiff_t]) - AC_CHECK_SIZEOF([unsigned long]) - AC_CHECK_SIZEOF([void *]) - AC_CACHE_CHECK([for nl_langinfo and THOUSANDS_SEP], - estream_cv_langinfo_thousands_sep, - [AC_TRY_LINK([#include ], - [char* cs = nl_langinfo(THOUSANDS_SEP); return !cs;], - estream_cv_langinfo_thousands_sep=yes, - estream_cv_langinfo_thousands_sep=no) - ]) - if test $estream_cv_langinfo_thousands_sep = yes; then - AC_DEFINE(HAVE_LANGINFO_THOUSANDS_SEP, 1, - [Define if you have and nl_langinfo(THOUSANDS_SEP).]) - fi -]) - - -dnl estream_INIT -dnl Prepare build of source included estream.c -dnl -AC_DEFUN([estream_INIT], -[ - AC_REQUIRE([estream_PRINTF_INIT]) - AC_MSG_NOTICE([checking system features for estream]) - -]) diff --git a/src/agent.c b/src/agent.c index df9cdc1..6228af9 100644 --- a/src/agent.c +++ b/src/agent.c @@ -30,11 +30,12 @@ #include #ifdef HAVE_W32_SYSTEM -#define PATHSEP_C ';' -#define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */ -#include +# define PATHSEP_C ';' +# define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */ +# include +# include #else -#define PATHSEP_C ':' +# define PATHSEP_C ':' #endif #include @@ -64,8 +65,8 @@ gnupg_allow_set_foregound_window (pid_t pid) return; #ifdef HAVE_W32_SYSTEM else if (!AllowSetForegroundWindow (pid)) - DEBUG (DBG_CRIT, "AllowSetForegroundWindow(%lu) failed: %i\n", - (unsigned long)pid, GetLastError ()); + DEBUG (DBG_CRIT, "AllowSetForegroundWindow(%lu) failed: %u\n", + (unsigned long)pid, (unsigned int)GetLastError ()); #endif } diff --git a/src/get-path.c b/src/get-path.c index 521c727..58491fe 100644 --- a/src/get-path.c +++ b/src/get-path.c @@ -25,13 +25,30 @@ #include #include #ifdef HAVE_W32_SYSTEM -#include -#include -#include +# include +# include +# include #endif #include "support.h" +#ifndef HAVE_STPCPY +static char * +my_stpcpy (char *a, const char *b) +{ + while( *b ) + *a++ = *b++; + *a = 0; + + return (char*)a; +} +# undef stpcpy +# define stpcpy(a,b) my_stpcpy ((a), (b)) +#endif /* !HAVE_STPCPY */ + + + + #ifdef HAVE_W32_SYSTEM #define RTLD_LAZY 0 @@ -39,6 +56,7 @@ static __inline__ void * dlopen (const char * name, int flag) { void * hd = LoadLibrary (name); + (void)flag; return hd; } diff --git a/src/p11-finalize.c b/src/p11-finalize.c index 7dbd00b..834046a 100644 --- a/src/p11-finalize.c +++ b/src/p11-finalize.c @@ -22,8 +22,8 @@ #include #endif #ifdef HAVE_W32_SYSTEM -#define __USE_W32_SOCKETS 1 -#include +# include +# include #endif #include "cryptoki.h" diff --git a/src/p11-initialize.c b/src/p11-initialize.c index 386df0e..6202cb5 100644 --- a/src/p11-initialize.c +++ b/src/p11-initialize.c @@ -26,7 +26,8 @@ #ifdef HAVE_W32_SYSTEM #define __USE_W32_SOCKETS 1 -#include +# include +# include #endif #include diff --git a/src/support.h b/src/support.h index 34f67d2..b51f3ac 100644 --- a/src/support.h +++ b/src/support.h @@ -65,23 +65,11 @@ scute_copy_string (char *dest, const char *src, int max_len) static inline char * ttyname (int fd) { + (void)fd; return NULL; } #endif /* !HAVE_TTYNAME */ -#ifndef HAVE_STPCPY -static inline char * -stpcpy (char *a, const char *b) -{ - while( *b ) - *a++ = *b++; - *a = 0; - - return (char*)a; -} -#endif /* !HAVE_STPCPY */ - - const char *get_gpgsm_path (void); const char *get_gpg_connect_agent_path (void); diff --git a/tests/t-getslotinfo.c b/tests/t-getslotinfo.c index 7633e82..caf02c7 100644 --- a/tests/t-getslotinfo.c +++ b/tests/t-getslotinfo.c @@ -146,7 +146,7 @@ main (int argc, char *argv[]) if (loop) { #ifdef WIN32 - _sleep (2); + Sleep (2*1000); #else sleep (2); /* Why? */ #endif ----------------------------------------------------------------------- Summary of changes: configure.ac | 8 +------- m4/Makefile.am | 2 +- m4/estream.m4 | 48 ------------------------------------------------ src/agent.c | 13 +++++++------ src/get-path.c | 24 +++++++++++++++++++++--- src/p11-finalize.c | 4 ++-- src/p11-initialize.c | 3 ++- src/support.h | 14 +------------- tests/t-getslotinfo.c | 2 +- 9 files changed, 36 insertions(+), 82 deletions(-) delete mode 100644 m4/estream.m4 hooks/post-receive -- PKCS#11 token on top of gpg-agent http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 04:32:45 2019 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 21 Feb 2019 04:32:45 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-378-g64b7c6f 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 64b7c6fd1945bc206cf56979633dfca8a7494374 (commit) from c395f8315362793409be54aca630ce6e903ea984 (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 64b7c6fd1945bc206cf56979633dfca8a7494374 Author: NIIBE Yutaka Date: Thu Feb 21 12:26:09 2019 +0900 tests: Add "disable-scdaemon" in gpg-agent.conf. * tests/openpgp/defs.scm: Add "disable-scdaemon". Remove "scdaemon-program". * tests/gpgme/gpgme-defs.scm, tests/gpgsm/gpgsm-defs.scm: Likewise. * tests/inittests, tests/pkits/inittests: Add "disable-scdaemon" -- Before this change, running "make check" accesses USB device by scdaemon on host computer. If there is any smartcard/token available, it may affect test results. Because default key choice depends on smartcard/token availability now and existing tests have nothing about testing smartcard/token, disabling scdaemon is good. Signed-off-by: NIIBE Yutaka diff --git a/tests/gpgme/gpgme-defs.scm b/tests/gpgme/gpgme-defs.scm index 0de589f..bc40b3c 100644 --- a/tests/gpgme/gpgme-defs.scm +++ b/tests/gpgme/gpgme-defs.scm @@ -67,8 +67,7 @@ (create-file "gpg-agent.conf" (string-append "pinentry-program " (tool 'pinentry)) - (string-append "scdaemon-program " (tool 'scdaemon)) - ) + "disable-scdaemon") (start-agent) diff --git a/tests/gpgsm/gpgsm-defs.scm b/tests/gpgsm/gpgsm-defs.scm index f118642..848bc75 100644 --- a/tests/gpgsm/gpgsm-defs.scm +++ b/tests/gpgsm/gpgsm-defs.scm @@ -67,10 +67,7 @@ "faked-system-time 1008241200") (create-file "gpg-agent.conf" (string-append "pinentry-program " (tool 'pinentry)) - (if (assoc "scdaemon" gpg-components) - (string-append "scdaemon-program " (tool 'scdaemon)) - "# No scdaemon available") - ) + "disable-scdaemon") (start-agent) (create-file "trustlist.txt" diff --git a/tests/inittests b/tests/inittests index 6fbccfb..9090674 100755 --- a/tests/inittests +++ b/tests/inittests @@ -85,6 +85,7 @@ EOF cat > gpg-agent.conf < trustlist.txt < gpg-agent.conf < 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 bd15aa34ab8ad10adbb7540a8845b4a2600437b6 (commit) from 64b7c6fd1945bc206cf56979633dfca8a7494374 (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 bd15aa34ab8ad10adbb7540a8845b4a2600437b6 Author: NIIBE Yutaka Date: Thu Feb 21 15:16:11 2019 +0900 scd: Handle ack button timeout as GPG_ERR_TIMEOUT. * scd/apdu.h (SW_ACK_TIMEOUT): New. * scd/iso7816.c (map_sw): Return GPG_ERR_TIMEOUT for SW_ACK_TIMEOUT. Signed-off-by: NIIBE Yutaka diff --git a/scd/apdu.h b/scd/apdu.h index 1392aab..89df45c 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -31,6 +31,7 @@ enum { SW_EOF_REACHED = 0x6282, SW_TERM_STATE = 0x6285, /* Selected file is in termination state. */ SW_EEPROM_FAILURE = 0x6581, + SW_ACK_TIMEOUT = 0x6600, /* OpenPGPcard: Ack timeout. */ SW_WRONG_LENGTH = 0x6700, SW_SM_NOT_SUP = 0x6882, /* Secure Messaging is not supported. */ SW_CC_NOT_SUP = 0x6884, /* Command Chaining is not supported. */ diff --git a/scd/iso7816.c b/scd/iso7816.c index 758de5b..a9cd730 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -67,6 +67,7 @@ map_sw (int sw) case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break; case SW_TERM_STATE: ec = GPG_ERR_OBJ_TERM_STATE; break; case SW_WRONG_LENGTH: ec = GPG_ERR_INV_VALUE; break; + case SW_ACK_TIMEOUT: ec = GPG_ERR_TIMEOUT; break; case SW_SM_NOT_SUP: ec = GPG_ERR_NOT_SUPPORTED; break; case SW_CC_NOT_SUP: ec = GPG_ERR_NOT_SUPPORTED; break; case SW_CHV_WRONG: ec = GPG_ERR_BAD_PIN; break; ----------------------------------------------------------------------- Summary of changes: scd/apdu.h | 1 + scd/iso7816.c | 1 + 2 files changed, 2 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 07:53:08 2019 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 21 Feb 2019 07:53:08 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-380-g2013cb5 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 2013cb5ee667610de35f8b92c2f979f5caa09d4c (commit) from bd15aa34ab8ad10adbb7540a8845b4a2600437b6 (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 2013cb5ee667610de35f8b92c2f979f5caa09d4c Author: NIIBE Yutaka Date: Thu Feb 21 15:50:43 2019 +0900 scd: Clear CHV status on timeout error. * scd/app-openpgp.c (clear_chv_status): New. (do_change_pin): Use clear_chv_status. (do_sign): Call clear_chv_status on GPG_ERR_TIMEOUT. (do_auth, do_decipher): Likewise. Signed-off-by: NIIBE Yutaka diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index ae87d19..d7243cc 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2568,6 +2568,42 @@ do_writecert (app_t app, ctrl_t ctrl, } +static gpg_error_t +clear_chv_status (app_t app, int chvno) +{ + unsigned char apdu[4]; + gpg_error_t err; + + if (!app->app_local->extcap.is_v2) + return GPG_ERR_UNSUPPORTED_OPERATION; + + apdu[0] = 0x00; + apdu[1] = ISO7816_VERIFY; + apdu[2] = 0xff; + apdu[3] = 0x80+chvno; + + err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_INV_VALUE) + err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + return err; + } + + if (chvno == 1) + { + apdu[3]++; + err = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); + app->did_chv1 = app->did_chv2 = 0; + } + else if (chvno == 2) + app->did_chv2 = 0; + else if (chvno == 3) + app->did_chv3 = 0; + + return err; +} + /* Handle the PASSWD command. The following combinations are possible: @@ -2623,38 +2659,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, pininfo.minlen = minlen; if ((flags & APP_CHANGE_FLAG_CLEAR)) - { - unsigned char apdu[4]; - - if (!app->app_local->extcap.is_v2) - return GPG_ERR_UNSUPPORTED_OPERATION; - - apdu[0] = 0x00; - apdu[1] = ISO7816_VERIFY; - apdu[2] = 0xff; - apdu[3] = 0x80+chvno; - - rc = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); - if (rc) - { - if (rc == GPG_ERR_INV_VALUE) - rc = GPG_ERR_UNSUPPORTED_OPERATION; - return rc; - } - - if (chvno == 1) - { - apdu[3]++; - rc = iso7816_apdu_direct (app->slot, apdu, 4, 0, NULL, NULL, NULL); - app->did_chv1 = app->did_chv2 = 0; - } - else if (chvno == 2) - app->did_chv2 = 0; - else if (chvno == 3) - app->did_chv3 = 0; - - return rc; - } + return clear_chv_status (app, chvno); if (reset_mode && chvno == 3) { @@ -4501,7 +4506,9 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, } rc = iso7816_compute_ds (app->slot, exmode, data, datalen, le_value, outdata, outdatalen); - if (!rc && app->force_chv1) + if (gpg_err_code (rc) == GPG_ERR_TIMEOUT) + clear_chv_status (app, 1); + else if (!rc && app->force_chv1) app->did_chv1 = 0; return rc; @@ -4610,6 +4617,8 @@ do_auth (app_t app, const char *keyidstr, rc = iso7816_internal_authenticate (app->slot, exmode, indata, indatalen, le_value, outdata, outdatalen); + if (gpg_err_code (rc) == GPG_ERR_TIMEOUT) + clear_chv_status (app, 1); } return rc; } @@ -4833,7 +4842,7 @@ do_decipher (app_t app, const char *keyidstr, indata, indatalen, le_value, padind, outdata, outdatalen); xfree (fixbuf); - if (app->app_local->keyattr[1].key_type == KEY_TYPE_ECC) + if (!rc && app->app_local->keyattr[1].key_type == KEY_TYPE_ECC) { unsigned char prefix = 0; @@ -4857,6 +4866,8 @@ do_decipher (app_t app, const char *keyidstr, *outdatalen = *outdatalen + 1; } } + if (gpg_err_code (rc) == GPG_ERR_TIMEOUT) + clear_chv_status (app, 1); if (gpg_err_code (rc) == GPG_ERR_CARD /* actual SW is 0x640a */ && app->app_local->manufacturer == 5 ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 79 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 34 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 08:52:37 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Feb 2019 08:52:37 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-383-g3384ba6 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 3384ba6c1c421cfa674dbd8294dc655d7320534e (commit) via 5ecc7a02609dde65096ddb12e0ff8f6bce3b774a (commit) via d7a54ca461ad75e4fab77a2f1b25986c7637762a (commit) from 2013cb5ee667610de35f8b92c2f979f5caa09d4c (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 3384ba6c1c421cfa674dbd8294dc655d7320534e Author: Werner Koch Date: Thu Feb 21 08:42:33 2019 +0100 card: Print the keyref in the listing. * tools/gpg-card-tool.c (list_one_kinfo): Print the keyref. -- The named keys are nice but knowing the actual keyref mapping to them is also useful. Signed-off-by: Werner Koch diff --git a/tools/card-tool-yubikey.c b/tools/card-tool-yubikey.c index a03915a..996bbf0 100644 --- a/tools/card-tool-yubikey.c +++ b/tools/card-tool-yubikey.c @@ -169,7 +169,7 @@ set_ul_config_value (struct ykapps_s *yk, * application and thus its transport again. */ if (bitflag == YKAPP_USB_ENABLED && !(ul & (0x08|0x10|0x20))) { - log_info ("Enabling PIV so that at least one CCI transport is enabled\n"); + log_info ("Enabling PIV to have at least one CCID transport\n"); ul |= 0x10; } diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 2bc2e5f..a13a6bd 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -631,6 +631,7 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp) goto leave; } print_keygrip (fp, kinfo->grip); + tty_fprintf (fp, " keyref .....: %s\n", kinfo->keyref); if (!scd_readkey (kinfo->keyref, &s_pkey)) { char *tmp = pubkey_algo_string (s_pkey); commit 5ecc7a02609dde65096ddb12e0ff8f6bce3b774a Author: Werner Koch Date: Thu Feb 21 08:40:59 2019 +0100 scd: Don't let the "undefined" app cause a conflict error. * scd/app.c (check_conflict): Ignore "undefined". Signed-off-by: Werner Koch diff --git a/scd/app.c b/scd/app.c index 2e2729e..8d4d1c0 100644 --- a/scd/app.c +++ b/scd/app.c @@ -121,6 +121,9 @@ check_conflict (app_t app, const char *name) if (!app || !name || (app->apptype && !ascii_strcasecmp (app->apptype, name))) return 0; + if (app->apptype && !strcmp (app->apptype, "UNDEFINED")) + return 0; + log_info ("application '%s' in use - can't switch\n", app->apptype? app->apptype : ""); commit d7a54ca461ad75e4fab77a2f1b25986c7637762a Author: Werner Koch Date: Thu Feb 21 08:51:27 2019 +0100 sm: Prepare algo mapping to handle values > 255. * sm/misc.c (transform_sigval): Allow for larger values of MDALGO and PKALGO. -- Libgcrypt already defines larger values for them, so we should be prepared in case we use them in the future. Signed-off-by: Werner Koch diff --git a/sm/misc.c b/sm/misc.c index 4672f26..9545293 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -204,41 +204,44 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, return err; /* Map the hash algorithm to an OID. */ - switch (mdalgo | (pkalgo << 8)) + if (mdalgo < 0 || mdalgo > (1<<15) || pkalgo < 0 || pkalgo > (1<<15)) + return gpg_error (GPG_ERR_DIGEST_ALGO); + + switch (mdalgo | (pkalgo << 16)) { - case GCRY_MD_SHA1 | (GCRY_PK_RSA << 8): + case GCRY_MD_SHA1 | (GCRY_PK_RSA << 16): oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */ break; - case GCRY_MD_SHA256 | (GCRY_PK_RSA << 8): + case GCRY_MD_SHA256 | (GCRY_PK_RSA << 16): oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */ break; - case GCRY_MD_SHA384 | (GCRY_PK_RSA << 8): + case GCRY_MD_SHA384 | (GCRY_PK_RSA << 16): oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */ break; - case GCRY_MD_SHA512 | (GCRY_PK_RSA << 8): + case GCRY_MD_SHA512 | (GCRY_PK_RSA << 16): oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */ break; - case GCRY_MD_SHA224 | (GCRY_PK_ECC << 8): + case GCRY_MD_SHA224 | (GCRY_PK_ECC << 16): oid = "1.2.840.10045.4.3.1"; /* ecdsa-with-sha224 */ break; - case GCRY_MD_SHA256 | (GCRY_PK_ECC << 8): + case GCRY_MD_SHA256 | (GCRY_PK_ECC << 16): oid = "1.2.840.10045.4.3.2"; /* ecdsa-with-sha256 */ break; - case GCRY_MD_SHA384 | (GCRY_PK_ECC << 8): + case GCRY_MD_SHA384 | (GCRY_PK_ECC << 16): oid = "1.2.840.10045.4.3.3"; /* ecdsa-with-sha384 */ break; - case GCRY_MD_SHA512 | (GCRY_PK_ECC << 8): + case GCRY_MD_SHA512 | (GCRY_PK_ECC << 16): oid = "1.2.840.10045.4.3.4"; /* ecdsa-with-sha512 */ break; - case GCRY_MD_SHA512 | (GCRY_PK_EDDSA << 8): + case GCRY_MD_SHA512 | (GCRY_PK_EDDSA << 16): oid = "1.3.101.112"; /* ed25519 */ break; ----------------------------------------------------------------------- Summary of changes: scd/app.c | 3 +++ sm/misc.c | 23 +++++++++++++---------- tools/card-tool-yubikey.c | 2 +- tools/gpg-card-tool.c | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 10:21:46 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Feb 2019 10:21:46 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.3.2-22-g11430ca 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 11430ca2a097e54efd72412b241dc9e65fd3c6c7 (commit) from 5af56045e25714e2b86a6555d8d976eae47ee748 (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 11430ca2a097e54efd72412b241dc9e65fd3c6c7 Author: Andre Heinecke Date: Thu Feb 21 10:18:53 2019 +0100 Cleanly remove gpgol_sigstatus * src/mapihelp.cpp (get_gpgolsigstatus_tag), (mapi_has_sig_status, mapi_test_sig_status, mapi_get_sig_status) (mapi_set_sig_status): Removed. (mapi_change_message_class): Dont mark non crypto messages. * src/mimemaker.cpp (finalize_message restore_msg_from_moss): Do not set sigstatus. -- The sigstatus is not used by current code and is never read. The save changes caused by the property required a modification and additional sync for unencrypted messages. So we need to remove setting it. diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index acd28c8..9f4499e 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -190,20 +190,6 @@ get_gpgolattachtype_tag (LPMESSAGE message, ULONG *r_tag) } -/* Return the property tag for GpgOL Sig Status. */ -int -get_gpgolsigstatus_tag (LPMESSAGE message, ULONG *r_tag) -{ - TSTART; - if (!(*r_tag = create_gpgol_tag (message, L"GpgOL Sig Status", __func__))) - { - TRETURN -1; - } - *r_tag |= PT_STRING8; - TRETURN 0; -} - - /* Return the property tag for GpgOL Protect IV. */ int get_gpgolprotectiv_tag (LPMESSAGE message, ULONG *r_tag) @@ -1621,13 +1607,8 @@ mapi_change_message_class (LPMESSAGE message, int sync_override, if (!newvalue) { - /* We use our Sig-Status property to mark messages which passed - this function. This helps us to avoid later tests. */ - if (!mapi_has_sig_status (message)) - { - mapi_set_sig_status (message, "#"); - need_save = 1; - } + log_debug ("%s:%s Message is not a crypto message.", + SRCNAME, __func__); } else { @@ -2848,138 +2829,6 @@ mapi_test_attach_hidden (LPATTACH attach) - -/* Returns True if MESSAGE has the GpgOL Sig Status property. */ -int -mapi_has_sig_status (LPMESSAGE msg) -{ - TSTART; - HRESULT hr; - LPSPropValue propval = NULL; - ULONG tag; - int yes; - - if (get_gpgolsigstatus_tag (msg, &tag) ) - { - TRETURN 0; /* Error: Assume No. */ - } - hr = HrGetOneProp ((LPMAPIPROP)msg, tag, &propval); - if (FAILED (hr)) - { - TRETURN 0; /* No. */ - } - if (PROP_TYPE (propval->ulPropTag) == PT_STRING8) - yes = 1; - else - yes = 0; - - MAPIFreeBuffer (propval); - TRETURN yes; -} - - -/* Returns True if MESSAGE has a GpgOL Sig Status property and that it - is not set to unchecked. */ -int -mapi_test_sig_status (LPMESSAGE msg) -{ - TSTART; - HRESULT hr; - LPSPropValue propval = NULL; - ULONG tag; - int yes; - - if (get_gpgolsigstatus_tag (msg, &tag) ) - { - TRETURN 0; /* Error: Assume No. */ - } - hr = HrGetOneProp ((LPMAPIPROP)msg, tag, &propval); - if (FAILED (hr)) - { - TRETURN 0; /* No. */ - } - - /* We TRETURN False if we have an unknown signature status (?) or the - message has been sent by us and not yet checked (@). */ - if (PROP_TYPE (propval->ulPropTag) == PT_STRING8) - yes = !(propval->Value.lpszA && (!strcmp (propval->Value.lpszA, "?") - || !strcmp (propval->Value.lpszA, "@"))); - else - yes = 0; - - MAPIFreeBuffer (propval); - TRETURN yes; -} - - -/* Return the signature status as an allocated string. Will never - return NULL. */ -char * -mapi_get_sig_status (LPMESSAGE msg) -{ - TSTART; - HRESULT hr; - LPSPropValue propval = NULL; - ULONG tag; - char *retstr; - - if (get_gpgolsigstatus_tag (msg, &tag) ) - { - TRETURN xstrdup ("[Error getting tag for sig status]"); - } - hr = HrGetOneProp ((LPMAPIPROP)msg, tag, &propval); - if (FAILED (hr)) - { - TRETURN xstrdup (""); - } - if (PROP_TYPE (propval->ulPropTag) == PT_STRING8) - retstr = xstrdup (propval->Value.lpszA); - else - retstr = xstrdup ("[Sig status has an invalid type]"); - - MAPIFreeBuffer (propval); - TRETURN retstr; -} - - - - -/* Set the signature status property to STATUS_STRING. There are a - few special values: - - "#" The message is not of interest to us. - "@" The message has been created and signed or encrypted by us. - "?" The signature status has not been checked. - "!" The signature verified okay - "~" The signature was not fully verified. - "-" The signature is bad - - Note that this function does not call SaveChanges. */ -int -mapi_set_sig_status (LPMESSAGE message, const char *status_string) -{ - TSTART; - HRESULT hr; - SPropValue prop; - - if (get_gpgolsigstatus_tag (message, &prop.ulPropTag) ) - { - TRETURN -1; - } - prop.Value.lpszA = xstrdup (status_string); - hr = HrSetOneProp (message, &prop); - xfree (prop.Value.lpszA); - if (hr) - { - log_error ("%s:%s: can't set %s property: hr=%#lx\n", - SRCNAME, __func__, "GpgOL Sig Status", hr); - TRETURN -1; - } - - TRETURN 0; -} - - /* When sending a message we need to fake the message class so that OL processes it according to our needs. However, if we later try to get the message class from the sent message, OL still has the SMIME diff --git a/src/mapihelp.h b/src/mapihelp.h index b167b3d..53a7a77 100644 --- a/src/mapihelp.h +++ b/src/mapihelp.h @@ -41,7 +41,6 @@ extern "C" { void log_mapi_property (LPMESSAGE message, ULONG prop, const char *propname); int get_gpgololdmsgclass_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgolattachtype_tag (LPMESSAGE message, ULONG *r_tag); -int get_gpgolsigstatus_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgolprotectiv_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgollastdecrypted_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgolmimeinfo_tag (LPMESSAGE message, ULONG *r_tag); @@ -82,11 +81,6 @@ LPSTREAM mapi_get_attach_as_stream (LPMESSAGE message, char *mapi_get_attach (LPMESSAGE message, mapi_attach_item_t *item, size_t *r_nbytes); int mapi_mark_moss_attach (LPMESSAGE message, mapi_attach_item_t *item); -int mapi_has_sig_status (LPMESSAGE msg); -int mapi_test_sig_status (LPMESSAGE msg); -char *mapi_get_sig_status (LPMESSAGE msg); - -int mapi_set_sig_status (LPMESSAGE message, const char *status_string); int mapi_set_gpgol_msg_class (LPMESSAGE message, const char *name); diff --git a/src/mimemaker.cpp b/src/mimemaker.cpp index acec070..be51ae6 100644 --- a/src/mimemaker.cpp +++ b/src/mimemaker.cpp @@ -1193,15 +1193,6 @@ finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table, return -1; } - /* Set a special property so that we are later able to identify - messages signed or encrypted by us. */ - if (mapi_set_sig_status (message, "@")) - { - log_error ("%s:%s: error setting sigstatus", - SRCNAME, __func__); - return -1; - } - /* We also need to set the message class into our custom property. This override is at least required for encrypted messages. */ @@ -1622,14 +1613,6 @@ restore_msg_from_moss (LPMESSAGE message, LPDISPATCH moss_att, goto done; } - /* Set a special property so that we are later able to identify - messages signed or encrypted by us. */ - if (mapi_set_sig_status (message, "@")) - { - log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__); - goto done; - } - err = 0; done: xfree (orig); ----------------------------------------------------------------------- Summary of changes: src/mapihelp.cpp | 155 +----------------------------------------------------- src/mapihelp.h | 6 --- src/mimemaker.cpp | 17 ------ 3 files changed, 2 insertions(+), 176 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 13:06:25 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Feb 2019 13:06:25 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.12.0-133-g73b2f40 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 73b2f40ae5e6881991dea609b0781373b28d7d30 (commit) via 6175025c822678102c3f089e37952aa84b19a3ec (commit) from 4c49417cc0dbd7f34269aff00fccafba150af744 (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 73b2f40ae5e6881991dea609b0781373b28d7d30 Author: Andre Heinecke Date: Thu Feb 21 13:05:55 2019 +0100 cpp: Add ostream operators for import result * lang/cpp/src/importresult.cpp: Add ostream operators. * lang/cpp/src/importresult.h: Update accordingly. diff --git a/lang/cpp/src/importresult.cpp b/lang/cpp/src/importresult.cpp index 05943ca..20a3174 100644 --- a/lang/cpp/src/importresult.cpp +++ b/lang/cpp/src/importresult.cpp @@ -35,6 +35,9 @@ #include #include +#include +#include +#include class GpgME::ImportResult::Private { @@ -224,3 +227,42 @@ GpgME::Import::Status GpgME::Import::status() const } return static_cast(result); } + +std::ostream &GpgME::operator<<(std::ostream &os, + const GpgME::ImportResult &result) +{ + os << "GpgME::ImportResult("; + if (!result.isNull()) { + os << "\n considered: " << result.numConsidered() + << "\n without UID: " << result.numKeysWithoutUserID() + << "\n imported: " << result.numImported() + << "\n RSA Imported: " << result.numRSAImported() + << "\n unchanged: " << result.numUnchanged() + << "\n newUserIDs: " << result.newUserIDs() + << "\n newSubkeys: " << result.newSubkeys() + << "\n newSignatures: " << result.newSignatures() + << "\n newRevocations: " << result.newRevocations() + << "\n numSecretKeysConsidered: " << result.numSecretKeysConsidered() + << "\n numSecretKeysImported: " << result.numSecretKeysImported() + << "\n numSecretKeysUnchanged: " << result.numSecretKeysUnchanged() + << "\n" + << "\n notImported: " << result.notImported() + << "\n numV3KeysSkipped: " << result.numV3KeysSkipped() + << "\n imports:\n"; + const std::vector imp = result.imports(); + std::copy(imp.begin(), imp.end(), + std::ostream_iterator(os, "\n")); + } + return os << ')'; +} + +std::ostream &GpgME::operator<<(std::ostream &os, const GpgME::Import &imp) +{ + os << "GpgME::Import("; + if (!imp.isNull()) { + os << "\n fpr: " << (imp.fingerprint() ? imp.fingerprint() : "null") + << "\n status: " << imp.status() + << "\n err: " << imp.error(); + } + return os << ')'; +} diff --git a/lang/cpp/src/importresult.h b/lang/cpp/src/importresult.h index 0547679..bcd956c 100644 --- a/lang/cpp/src/importresult.h +++ b/lang/cpp/src/importresult.h @@ -129,7 +129,10 @@ private: unsigned int idx; }; -} +GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const ImportResult &irs); +GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Import &imp); + +} // namespace GpgME GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(ImportResult) GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Import) commit 6175025c822678102c3f089e37952aa84b19a3ec Author: Andre Heinecke Date: Thu Feb 21 13:04:54 2019 +0100 cpp: Make GpgME::Data::toKeys really const * lang/cpp/src/data.cpp (GpgME::Data::toKeys): Rewind afterards. -- This fixes unexpected behavior that the seek pointer is changed after calling the const toKeys. diff --git a/lang/cpp/src/data.cpp b/lang/cpp/src/data.cpp index 547ec76..7a93cbc 100644 --- a/lang/cpp/src/data.cpp +++ b/lang/cpp/src/data.cpp @@ -256,6 +256,8 @@ std::vector GpgME::Data::toKeys(Protocol proto) const while (!gpgme_op_keylist_next (ctx->impl()->ctx, &key)) { ret.push_back(GpgME::Key(key, false)); } + gpgme_data_seek (d->data, 0, SEEK_SET); + delete ctx; return ret; } ----------------------------------------------------------------------- Summary of changes: lang/cpp/src/data.cpp | 2 ++ lang/cpp/src/importresult.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ lang/cpp/src/importresult.h | 5 ++++- 3 files changed, 48 insertions(+), 1 deletion(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 13:16:24 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Feb 2019 13:16:24 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.3.2-27-g36c42a1 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 36c42a1333166ac8ec1a276a6d1708aaf7e6d06e (commit) via 164881717c62699062f9b48199bfdcb1ef3ccc6b (commit) via 1a5280cc790459ca6c386e7ba4adf4f3b4097db2 (commit) via c0f058f976cba9c1e2b6192b5ca4af6831088dae (commit) via 210b349732cad9071ac2c6eca0e5cca398ebe145 (commit) from 11430ca2a097e54efd72412b241dc9e65fd3c6c7 (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 36c42a1333166ac8ec1a276a6d1708aaf7e6d06e Author: Andre Heinecke Date: Thu Feb 21 13:09:50 2019 +0100 Read autocrypt header for autoimport * src/common_indep.h (autocrypt_s): Data transfer struct. * src/keycache.cpp (KeyCache::import_pgp_key_data): Fix and add more debugging. * src/mail.cpp (Mail::preProcessMessage_m): Check for autocrypt headers even on non crypto mails. (Mail::decryptVerify_o): Parse autocrypt header for crypto mails. * src/mapihelp.cpp (get_message_content_type_cb): Renamed to parse_headers_cb. (ac_get_value): New helper. (prepare_key_data): New helper. (mapi_get_header_info): General function for additional header info. * src/mapihelp.h: Update accordingly. * src/parsecontroller.cpp (handle_autocrypt_info): New helper. (ParseController::parse): Handle autocrypt info on demand. * src/parsecontroller.h: Update accordingly. -- Ideally we want to do the import in the parse step as it is then in the background thread. But for unencrypted mails we have to do in in the pre processing because afterwards we no longer look at the unencrypted mail. mapi_get_header_info is intended as a new one time parse function to get some more info from the headers. For now it only supports autocrypt header. diff --git a/src/common_indep.h b/src/common_indep.h index 0a71914..c8df4d3 100644 --- a/src/common_indep.h +++ b/src/common_indep.h @@ -323,6 +323,16 @@ char *generate_boundary (char *buffer); #ifdef __cplusplus } + +#include +#include +struct autocrypt_s +{ + bool exists; + std::string pref; + std::string addr; + GpgME::Data data; +}; #endif #endif // COMMON_INDEP_H diff --git a/src/keycache.cpp b/src/keycache.cpp index 9d6f5d2..75d8058 100644 --- a/src/keycache.cpp +++ b/src/keycache.cpp @@ -1468,9 +1468,34 @@ KeyCache::import_pgp_key_data (const GpgME::Data &data) } log_debug ("Importing keys: %s", ss.str().c_str()); } - const auto result = ctx->importKeys(keys); + const auto result = ctx->importKeys(data); - log_debug ("%s:%s: Import result from attached key err: %s", - SRCNAME, __func__, result.error ().asString ()); + if ((opt.enable_debug & DBG_DATA)) + { + std::stringstream ss; + ss << result; + log_debug ("%s:%s: Import result: %s details:\n %s", + SRCNAME, __func__, result.error ().asString (), + ss.str().c_str()); + if (result.error()) + { + GpgME::Data out; + if (ctx->getAuditLog(out, GpgME::Context::DiagnosticAuditLog)) + { + log_error ("%s:%s: Failed to get diagnostics", + SRCNAME, __func__); + } + else + { + log_debug ("%s:%s: Diagnostics: \n%s\n", + SRCNAME, __func__, out.toString().c_str()); + } + } + } + else + { + log_debug ("%s:%s: Import result: %s", + SRCNAME, __func__, result.error ().asString ()); + } TRETURN !result.error(); } diff --git a/src/mail.cpp b/src/mail.cpp index fe4a106..45e252e 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -310,6 +310,19 @@ Mail::preProcessMessage_m () if (m_type == MSGTYPE_UNKNOWN) { + /* For unknown messages we still need to check for autocrypt + headers. If the mails are crypto messages the autocrypt + stuff is handled in the parsecontroller. */ + autocrypt_s ac; + if (mapi_get_header_info (message, ac)) + { + if (ac.exists) + { + log_debug ("%s:%s: Importing autocrypt header from unencrypted " + "mail.", SRCNAME, __func__); + KeyCache::import_pgp_key_data (ac.data); + } + } gpgol_release (message); TRETURN 0; } @@ -1159,6 +1172,32 @@ Mail::decryptVerify_o () m_parser = std::shared_ptr (new ParseController (cipherstream, m_type)); m_parser->setSender(GpgME::UserID::addrSpecFromString(getSender_o ().c_str())); + + if (opt.autoimport) + { + /* Handle autocrypt header. As we want to have the import + of the header in the same thread as the parser we leave it + to the parser. */ + auto message = MAKE_SHARED (get_oom_message (m_mailitem)); + if (!message) + { + /* Hmmm */ + STRANGEPOINT; + } + else + { + autocrypt_s ainfo; + if (!mapi_get_header_info ((LPMESSAGE)message.get(), ainfo)) + { + STRANGEPOINT; + } + else if (ainfo.exists) + { + m_parser->setAutocryptInfo (ainfo); + } + } + } + log_data ("%s:%s: Parser for \"%s\" is %p", SRCNAME, __func__, getSubject_o ().c_str(), m_parser.get()); gpgol_release (cipherstream); diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp index 9f4499e..8d2cc01 100644 --- a/src/mapihelp.cpp +++ b/src/mapihelp.cpp @@ -3094,7 +3094,7 @@ set_gpgol_draft_info_flags (LPMESSAGE message, int flags) /* Helper for mapi_get_msg_content_type() */ static int -get_message_content_type_cb (void *dummy_arg, +parse_headers_cb (void *dummy_arg, rfc822parse_event_t event, rfc822parse_t msg) { TSTART; @@ -3133,7 +3133,7 @@ mapi_get_message_content_type (LPMESSAGE message, *r_smtype = NULL; /* Read the headers into an rfc822 object. */ - msg = rfc822parse_open (get_message_content_type_cb, NULL); + msg = rfc822parse_open (parse_headers_cb, NULL); if (!msg) { log_error ("%s:%s: rfc822parse_open failed", @@ -3559,3 +3559,129 @@ mapi_mark_or_create_moss_attach (LPMESSAGE message, msgtype_t msgtype) mapi_release_attach_table (table); TRETURN 0; /* No original attachment - this should not happen. */ } + +static std::string +ac_get_value (const char *header, const char *what) +{ + TSTART; + if (!header || !what) + { + STRANGEPOINT; + TRETURN std::string(); + } + + const char *s = strstr (header, what); + if (!s) + { + log_debug ("%s:%s: could not find %s in autocrypt header", + SRCNAME, __func__, what); + TRETURN std::string(); + } + /* As we found it we can be sure that this is not out + of bounds. */ + s += strlen (what); + + if (*s != '=') + { + log_debug ("%s:%s: No equal sign after %s in autocrypt header %s", + SRCNAME, __func__, what, s); + TRETURN std::string(); + } + + /* Move over the = sign. */ + s++; + + /* Find the sep */ + const char *s2 = strchr (s, ';'); + if (!s2) + { + /* No seperator found. Assume the rest is the value */ + TRETURN s; + } + + /* From the equal to the ; is our value. */ + TRETURN std::string (s, s2 - s); +} + +static GpgME::Data +prepare_key_data (const std::string &d) +{ + TSTART; + if (d.empty()) + { + STRANGEPOINT; + TRETURN GpgME::Data(); + } + + /* Prepare the keydata */ + b64_state_t base64; /* The state of the Base-64 decoder. */ + b64_init (&base64); + + /* strdup and not xstrdup as we want GpgME to take over */ + char *b64decoded = strdup (d.c_str()); + size_t len = b64_decode (&base64, b64decoded, strlen(b64decoded)); + + if (!len) + { + log_error ("%s:%s: Invalid base64 in %s", SRCNAME, __func__, + b64decoded); + xfree (b64decoded); + TRETURN GpgME::Data(); + } + + auto data = GpgME::Data (b64decoded, len, false /* take ownership */); + + TRETURN data; +} + +bool +mapi_get_header_info (LPMESSAGE message, + autocrypt_s &r_autocrypt) +{ + TSTART; + rfc822parse_t msg; + + /* Read the headers into an rfc822 object. */ + msg = rfc822parse_open (parse_headers_cb, NULL); + if (!msg) + { + log_error ("%s:%s: rfc822parse_open failed", + SRCNAME, __func__); + TRETURN false; + } + + const std::string hdrStr = mapi_get_header (message); + if (hdrStr.empty()) + { + + log_error ("%s:%s: failed to get headers", + SRCNAME, __func__); + rfc822parse_close (msg); + TRETURN false; + } + + size_t length; + const char *header_lines = hdrStr.c_str(); + const char *s; + while ((s = strchr (header_lines, '\n'))) + { + length = (s - header_lines); + if (length && s[-1] == '\r') + length--; + + rfc822parse_insert (msg, (const unsigned char*)header_lines, length); + header_lines = s+1; + } + + const char *ac_field = rfc822parse_get_field (msg, "Autocrypt", -1, 0); + if (ac_field) + { + r_autocrypt.exists = true; + r_autocrypt.addr = ac_get_value (ac_field, "addr"); + r_autocrypt.data = prepare_key_data (ac_get_value (ac_field, "keydata")); + r_autocrypt.pref = ac_get_value (ac_field, "prefer-encrypt"); + } + + rfc822parse_close (msg); + TRETURN true; +} diff --git a/src/mapihelp.h b/src/mapihelp.h index 53a7a77..be42711 100644 --- a/src/mapihelp.h +++ b/src/mapihelp.h @@ -117,9 +117,20 @@ int mapi_body_to_attachment (LPMESSAGE message); /* Get malloced uid of a message */ char * mapi_get_uid (LPMESSAGE message); + #ifdef __cplusplus } #include + +/* Parse the headers for additional useful fields. + + r_autocrypt_info: Information about the autocrypt header. + + A return value of false indicates an error. Check the + individual info fields "exists" values to check if + the header exists in the message */ +bool mapi_get_header_info (LPMESSAGE message, + autocrypt_s &r_autocrypt_info); std::string mapi_get_header (LPMESSAGE message); #endif #endif /*MAPIHELP_H*/ diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 309e587..0a97fdb 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -285,6 +285,28 @@ ParseController::setSender(const std::string &sender) TRETURN; } +static void +handle_autocrypt_info (const autocrypt_s &info) +{ + TSTART; + if (info.pref.size() && info.pref != "mutual") + { + log_debug ("%s:%s: Autocrypt preference is %s which is unhandled.", + SRCNAME, __func__, info.pref.c_str()); + TRETURN; + } + +#ifndef BUILD_TESTS + if (!KeyCache::import_pgp_key_data (info.data)) + { + log_error ("%s:%s: Failed to import", SRCNAME, __func__); + } +#endif + /* No need to free b64decoded as gpgme_data_release handles it */ + + TRETURN; +} + static bool is_valid_chksum(const GpgME::Signature &sig) { @@ -328,6 +350,11 @@ ParseController::parse() auto inputType = input.type (); + if (m_autocrypt_info.exists) + { + handle_autocrypt_info (m_autocrypt_info); + } + if (inputType == Data::Type::PGPSigned) { verify = true; diff --git a/src/parsecontroller.h b/src/parsecontroller.h index 44465b8..d88ff19 100644 --- a/src/parsecontroller.h +++ b/src/parsecontroller.h @@ -98,6 +98,9 @@ public: bool shouldBlockHtml() const { return m_block_html; } + void setAutocryptInfo (const autocrypt_s & info) + { m_autocrypt_info = info; } + private: /* State variables */ MimeDataProvider *m_inputprovider; @@ -108,6 +111,7 @@ private: GpgME::VerificationResult m_verify_result; std::string m_sender; bool m_block_html; + autocrypt_s m_autocrypt_info; /* Autocrypt info about the mail */ }; #endif /* PARSECONTROLLER_H */ commit 164881717c62699062f9b48199bfdcb1ef3ccc6b Author: Andre Heinecke Date: Thu Feb 21 13:08:40 2019 +0100 Add cast to MAKE_SHARED macro * src/oomhelp.h (MAKE_SHARED): Cast to IDispatch. -- This allows to make shared stuff like IMessage. diff --git a/src/oomhelp.h b/src/oomhelp.h index 762f578..3de691e 100644 --- a/src/oomhelp.h +++ b/src/oomhelp.h @@ -155,7 +155,7 @@ typedef std::shared_ptr shared_disp_t; /* Function to contain the gpgol_release macro */ void release_disp (LPDISPATCH obj); -#define MAKE_SHARED(X) shared_disp_t (X, &release_disp) +#define MAKE_SHARED(X) shared_disp_t ((LPDISPATCH)X, &release_disp) /* Return the malloced name of an COM+ object. */ char *get_object_name (LPUNKNOWN obj); commit 1a5280cc790459ca6c386e7ba4adf4f3b4097db2 Author: Andre Heinecke Date: Thu Feb 21 13:07:15 2019 +0100 Add whitespace removal helper to cpphelp * src/cpphelp.cpp, src/cpphelp.h (remove_whitespace): New. diff --git a/src/cpphelp.cpp b/src/cpphelp.cpp index 434a368..fb56e22 100644 --- a/src/cpphelp.cpp +++ b/src/cpphelp.cpp @@ -80,6 +80,12 @@ trim(std::string &s) } void +remove_whitespace (std::string &s) +{ + s.erase(remove_if(s.begin(), s.end(), isspace), s.end()); +} + +void join(const std::vector& v, const char *c, std::string& s) { s.clear(); diff --git a/src/cpphelp.h b/src/cpphelp.h index de10dee..9167f29 100644 --- a/src/cpphelp.h +++ b/src/cpphelp.h @@ -37,6 +37,7 @@ void release_cArray (char **carray); void rtrim (std::string &s); void ltrim (std::string &s); void trim (std::string &s); +void remove_whitespace (std::string &s); /* Join a string vector */ void join(const std::vector& v, const char *c, std::string& s); commit c0f058f976cba9c1e2b6192b5ca4af6831088dae Author: Andre Heinecke Date: Thu Feb 21 13:06:37 2019 +0100 Minor string fix * src/addin-options.cpp: Remove period at the end of an option. diff --git a/src/addin-options.cpp b/src/addin-options.cpp index 2e40bc5..17c50ed 100644 --- a/src/addin-options.cpp +++ b/src/addin-options.cpp @@ -84,7 +84,7 @@ i18n_noops[] = { N_("Also &with untrusted keys"), /* TRANSLATORS: Included means here both attached keys and keys from the * headers */ - N_("&Import any keys included in mails."), + N_("&Import any keys included in mails"), /* TRANSLATORS: Included means here both attached keys and keys from the * headers */ N_("Import OpenPGP keys from mail attachments or from mail headers."), commit 210b349732cad9071ac2c6eca0e5cca398ebe145 Author: Andre Heinecke Date: Thu Feb 21 12:38:00 2019 +0100 Fix crash when sending encrypted mail * src/cryptcontroller.cpp (CryptController::update_mail_mapi): Check if att_table exists before accessing it. -- This was a regression caused by cf221afd which never made it into a release. diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp index 2f7bae5..53fc420 100644 --- a/src/cryptcontroller.cpp +++ b/src/cryptcontroller.cpp @@ -1021,7 +1021,7 @@ CryptController::update_mail_mapi () /* When we forward e.g. a crypto mail we have sent the message has a MOSSTEMPL. We need to remove that. T4321 */ - for (ULONG pos=0; !att_table[pos].end_of_table; pos++) + for (ULONG pos=0; att_table && !att_table[pos].end_of_table; pos++) { if (att_table[pos].attach_type == ATTACHTYPE_MOSSTEMPL) { ----------------------------------------------------------------------- Summary of changes: src/addin-options.cpp | 2 +- src/common_indep.h | 10 ++++ src/cpphelp.cpp | 6 +++ src/cpphelp.h | 1 + src/cryptcontroller.cpp | 2 +- src/keycache.cpp | 31 ++++++++++-- src/mail.cpp | 39 +++++++++++++++ src/mapihelp.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++++++- src/mapihelp.h | 11 ++++ src/oomhelp.h | 2 +- src/parsecontroller.cpp | 27 ++++++++++ src/parsecontroller.h | 4 ++ 12 files changed, 257 insertions(+), 8 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 15:17:08 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 21 Feb 2019 15:17:08 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.3.2-28-g815c500 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 815c500864db46e7bc4a9f5d4b8ccd942e60fd15 (commit) from 36c42a1333166ac8ec1a276a6d1708aaf7e6d06e (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 815c500864db46e7bc4a9f5d4b8ccd942e60fd15 Author: Andre Heinecke Date: Thu Feb 21 15:16:49 2019 +0100 Add minimalistic protected-headers support * src/mail.cpp (Mail::parsing_done): Update subject if one was taken from a protected header. * src/mailitem-events.cpp (prop_blacklist): Ignore subject related changes. * src/mimedataprovider.cpp (t2body): Handle protected headers. (MimeDataProvider::finalize): Convert subject to a string. (MimeDataProvider::get_internal_subject): New. * src/parsecontroller.cpp (ParseController::get_internal_subject): New accessor. * src/parsecontroller.h, src/mimedataprovider.h: Update accordingly. -- This is still bad but a little less bad then it was before. We still ignore to and from from the protected headers but at least we show the subject now.1 diff --git a/src/mail.cpp b/src/mail.cpp index 45e252e..db137b1 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -1495,6 +1495,12 @@ Mail::parsing_done() m_decrypt_result = m_parser->decrypt_result (); m_verify_result = m_parser->verify_result (); + const auto subject = m_parser->get_internal_subject (); + if (!subject.empty ()) + { + put_oom_string (m_mailitem, "Subject", subject.c_str ()); + } + m_crypto_flags = 0; if (!m_decrypt_result.isNull()) { diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp index fa12d88..5be58e7 100644 --- a/src/mailitem-events.cpp +++ b/src/mailitem-events.cpp @@ -47,6 +47,8 @@ const wchar_t *prop_blacklist[] = { L"OutlookInternalVersion", L"ReceivedTime", L"InternetCodepage", + L"ConversationIndex", + L"Subject", NULL }; typedef enum diff --git a/src/mimedataprovider.cpp b/src/mimedataprovider.cpp index 25e576c..6afcdcd 100644 --- a/src/mimedataprovider.cpp +++ b/src/mimedataprovider.cpp @@ -186,6 +186,7 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg) char *p; int is_text = 0; int is_text_attachment = 0; + int is_protected_headers = 0; char *filename = NULL; char *cid = NULL; char *charset = NULL; @@ -341,6 +342,15 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg) else if (!strcmp (ctmain, "text")) { is_text = !strcmp (ctsub, "html")? 2:1; + is_protected_headers = (!strcmp (ctsub, "rfc822-headers") && + rfc822parse_query_parameter (field, + "protected-headers", -1)); + if (is_protected_headers) + { + log_data ("%s:%s: Found protected headers.", + SRCNAME, __func__); + provider->m_had_protected_headers = true; + } } else if (ctx->nesting_level == 1 && !provider->signature() && !strcmp (ctmain, "application") @@ -383,14 +393,18 @@ t2body (MimeDataProvider *provider, rfc822parse_t msg) } } rfc822parse_release_field (field); /* (Content-type) */ - ctx->in_data = 1; + if (!is_protected_headers) + { + ctx->in_data = 1; + } log_data ("%s:%s: this body: nesting=%d partno=%d is_text=%d" - " charset=\"%s\"\n body_seen=%d is_text_attachment=%d", + " charset=\"%s\"\n body_seen=%d is_text_attachment=%d" + " is_protected_headers=%d", SRCNAME, __func__, ctx->nesting_level, ctx->part_counter, is_text, ctx->mimestruct_cur->charset?ctx->mimestruct_cur->charset:"", - ctx->body_seen, is_text_attachment); + ctx->body_seen, is_text_attachment, is_protected_headers); /* If this is a text part, decide whether we treat it as one of our bodies. @@ -1077,6 +1091,25 @@ MimeDataProvider::create_attachment() void MimeDataProvider::finalize () { TSTART; + + if (m_had_protected_headers) + { + const char *subject = rfc822parse_get_field (m_mime_ctx->msg, + "Subject", -1, + nullptr); + if (subject) + { + log_debug ("%s:%s: Found subject %s", SRCNAME, __func__, subject); + if (strlen (subject) <= strlen ("Subject: ")) + { + STRANGEPOINT; + } + else + { + m_internal_subject = subject + strlen ("Subject: "); + } + } + } if (m_rawbuf.size ()) { m_rawbuf += "\r\n"; @@ -1115,3 +1148,9 @@ const std::string &MimeDataProvider::get_body_charset() const TSTART; TRETURN m_body_charset; } + +const std::string &MimeDataProvider::get_internal_subject () const +{ + TSTART; + TRETURN m_internal_subject; +} diff --git a/src/mimedataprovider.h b/src/mimedataprovider.h index 40e1c18..17b5549 100644 --- a/src/mimedataprovider.h +++ b/src/mimedataprovider.h @@ -116,11 +116,14 @@ public: {return m_attachments;} const std::string &get_html_charset() const; const std::string &get_body_charset() const; + const std::string &get_internal_subject() const; void set_has_html_body(bool value) {m_has_html_body = value;} /* Finalize the bodys */ void finalize (); + + bool m_had_protected_headers; private: #ifdef HAVE_W32_SYSTEM /* Collect the data from mapi. */ @@ -154,5 +157,7 @@ private: bool m_has_html_body; /* Collect everything */ bool m_collect_everything; + /* Internal Protected Headers subject */ + std::string m_internal_subject; }; #endif // MIMEDATAPROVIDER_H diff --git a/src/parsecontroller.cpp b/src/parsecontroller.cpp index 0a97fdb..872f7e1 100644 --- a/src/parsecontroller.cpp +++ b/src/parsecontroller.cpp @@ -696,3 +696,14 @@ ParseController::get_attachments() const TRETURN std::vector >(); } } + +std::string +ParseController::get_internal_subject() const +{ + TSTART; + if (m_outputprovider) + { + TRETURN m_outputprovider->get_internal_subject (); + } + TRETURN std::string(); +} diff --git a/src/parsecontroller.h b/src/parsecontroller.h index d88ff19..3b7d456 100644 --- a/src/parsecontroller.h +++ b/src/parsecontroller.h @@ -101,6 +101,8 @@ public: void setAutocryptInfo (const autocrypt_s & info) { m_autocrypt_info = info; } + std::string get_internal_subject() const; + private: /* State variables */ MimeDataProvider *m_inputprovider; ----------------------------------------------------------------------- Summary of changes: src/mail.cpp | 6 ++++++ src/mailitem-events.cpp | 2 ++ src/mimedataprovider.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/mimedataprovider.h | 5 +++++ src/parsecontroller.cpp | 11 +++++++++++ src/parsecontroller.h | 2 ++ 6 files changed, 68 insertions(+), 3 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 21 17:33:40 2019 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Feb 2019 17:33:40 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.2.7-386-gc1000c6 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 c1000c673814e552923cf1361346d7dfeee55608 (commit) via 7317aeb3f448c98dcfa9c04f49b9a69d81c26776 (commit) via 5e21ef2d556ca65b7869bf16ab465f3511601e1e (commit) from 3384ba6c1c421cfa674dbd8294dc655d7320534e (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 c1000c673814e552923cf1361346d7dfeee55608 Author: Werner Koch Date: Thu Feb 21 17:32:39 2019 +0100 sm: Fix certificate creation with key on card. * sm/certreqgen.c (create_request): Fix for certmode. -- When using an existing key from a card for certificate signing (in contrast to the default of generating a CSR), the code tried to use the same key for signing instead of the Signing-Key parameter. It is perfectly okay to use the regular signing path via gpg-agent for certificate creation - only self-signed certificates with a key on the card require the direct use of the card key (via "SCD PKSIGN"). Signed-off-by: Werner Koch diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 01fba30..d5c857b 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -1314,7 +1314,7 @@ create_request (ctrl_t ctrl, log_info ("about to sign the %s for key: &%s\n", certmode? "certificate":"CSR", hexgrip); - if (carddirect) + if (carddirect && !certmode) rc = gpgsm_scd_pksign (ctrl, carddirect, NULL, gcry_md_read (md, mdalgo), gcry_md_get_algo_dlen (mdalgo), commit 7317aeb3f448c98dcfa9c04f49b9a69d81c26776 Author: Werner Koch Date: Thu Feb 21 12:43:07 2019 +0100 card: Print usage info for each key. * tools/card-call-scd.c (learn_status_cb): Handle extended KEYPARIRINFO. * tools/card-tool.h (struct key_info_s): Add field 'usage'. * tools/gpg-card-tool.c (list_one_kinfo): Show usage flags. Signed-off-by: Werner Koch diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 8610da8..83e9ba0 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -890,28 +890,59 @@ learn_status_cb (void *opaque, const char *line) else if (!memcmp (keyword, "KEYPAIRINFO", keywordlen)) { /* The format of such a line is: - * KEYPARINFO + * KEYPAIRINFO [usage] */ - const char *hexgrp = line; + char *hexgrp, *usage; - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; + line_buffer = pline = xstrdup (line); - keyref = line; + hexgrp = pline; + while (*pline && !spacep (pline)) + pline++; + while (spacep (pline)) + pline++; + + keyref = pline; + while (*pline && !spacep (pline)) + pline++; + if (*pline) + { + *pline++ = 0; + while (spacep (pline)) + pline++; + usage = pline; + while (*pline && !spacep (pline)) + pline++; + *pline = 0; + } + else + usage = ""; /* Check whether we already have an item for the keyref. */ kinfo = find_kinfo (parm, keyref); if (!kinfo) /* New entry. */ kinfo = create_kinfo (parm, keyref); - else /* Existing entry - clear the grip. */ - memset (kinfo->grip, 0, sizeof kinfo->grip); + else /* Existing entry - clear grip and usage */ + { + memset (kinfo->grip, 0, sizeof kinfo->grip); + kinfo->usage = 0; + } /* Set or update the grip. Note that due to the * calloc/memset an erroneous too short grip will be nul * padded on the right. */ unhexify_fpr (hexgrp, kinfo->grip, sizeof kinfo->grip); + /* Parse and set the usage. */ + for (; *usage; usage++) + { + switch (*usage) + { + case 's': kinfo->usage |= GCRY_PK_USAGE_SIGN; break; + case 'c': kinfo->usage |= GCRY_PK_USAGE_CERT; break; + case 'a': kinfo->usage |= GCRY_PK_USAGE_AUTH; break; + case 'e': kinfo->usage |= GCRY_PK_USAGE_ENCR; break; + } + } } break; diff --git a/tools/card-tool.h b/tools/card-tool.h index f83ebf9..5598ae5 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -127,7 +127,7 @@ struct key_info_s unsigned char fprlen; /* Use length of the next item. */ unsigned char fpr[32]; /* The binary fingerprint of length FPRLEN. */ u32 created; /* The time the key was created. */ - + unsigned int usage; /* Usage flags. (GCRY_PK_USAGE_*) */ char keyref[1]; /* String with the keyref (e.g. OPENPGP.1). */ }; typedef struct key_info_s *key_info_t; diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index a13a6bd..eb723d7 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -621,6 +621,7 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp) key_info_t ki; const char *s; gcry_sexp_t s_pkey; + int any; if (firstkinfo && kinfo) { @@ -630,8 +631,25 @@ list_one_kinfo (key_info_t firstkinfo, key_info_t kinfo, estream_t fp) tty_fprintf (fp, "[none]\n"); goto leave; } + print_keygrip (fp, kinfo->grip); - tty_fprintf (fp, " keyref .....: %s\n", kinfo->keyref); + tty_fprintf (fp, " keyref .....: %s", kinfo->keyref); + if (kinfo->usage) + { + any = 0; + tty_fprintf (fp, " ("); + if ((kinfo->usage & GCRY_PK_USAGE_SIGN)) + { tty_fprintf (fp, "sign"); any=1; } + if ((kinfo->usage & GCRY_PK_USAGE_CERT)) + { tty_fprintf (fp, "%scert", any?",":""); any=1; } + if ((kinfo->usage & GCRY_PK_USAGE_AUTH)) + { tty_fprintf (fp, "%sauth", any?",":""); any=1; } + if ((kinfo->usage & GCRY_PK_USAGE_ENCR)) + { tty_fprintf (fp, "%sencr", any?",":""); any=1; } + tty_fprintf (fp, ")"); + } + tty_fprintf (fp, "\n"); + if (!scd_readkey (kinfo->keyref, &s_pkey)) { char *tmp = pubkey_algo_string (s_pkey); commit 5e21ef2d556ca65b7869bf16ab465f3511601e1e Author: Werner Koch Date: Thu Feb 21 09:24:37 2019 +0100 scd: Extend KEYPAIRINFO by key usage info. * scd/app-openpgp.c (send_keypair_info): Append usage string. * scd/app-piv.c (struct data_object_s): Remove column 'binary'. Add column 'usage'. (dump_all_do): Adjust for removed 'binary'. (send_keypair_and_cert_info): Append usage string. Signed-off-by: Werner Koch diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index d7243cc..b6ead64 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1785,6 +1785,7 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key) unsigned char grip[20]; char gripstr[41]; char idbuf[50]; + const char *usage; err = get_public_key (app, keyno); if (err) @@ -1802,10 +1803,19 @@ send_keypair_info (app_t app, ctrl_t ctrl, int key) bin2hex (grip, 20, gripstr); + switch (keyno) + { + case 0: usage = "sc"; break; + case 1: usage = "e"; break; + case 2: usage = "sa"; break; + default: usage = ""; break; + } + sprintf (idbuf, "OPENPGP.%d", keyno+1); send_status_info (ctrl, "KEYPAIRINFO", gripstr, 40, idbuf, strlen (idbuf), + usage, strlen (usage), NULL, (size_t)0); leave: diff --git a/scd/app-piv.c b/scd/app-piv.c index 9e355b4..edb00bf 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -90,52 +90,88 @@ struct data_object_s unsigned int acr_contact:2; /* 0=always, 1=VCI, 2=PIN, 3=PINorOCC */ unsigned int acr_contactless:2; /* 0=always, 1=VCI, 2=VCIandPIN, 3=VCIand(PINorOCC) */ - unsigned int binary:1; /* Data is not human readable. */ unsigned int dont_cache:1; /* Data item will not be cached. */ unsigned int flush_on_error:1; /* Flush cached item on error. */ unsigned int keypair:1; /* Has a public key for a keypair. */ - char keyref[3]; /* The key reference. */ - char *oidsuffix; /* Suffix of the OID, prefix is "2.16.840.1.101.3.7." */ - char *desc; /* Description of the DO. */ + const char keyref[3]; /* The key reference. */ + const char *oidsuffix; /* Suffix of the OID. */ + const char *usage; /* Usage string for a keypair or NULL. */ + const char *desc; /* Description of the DO. */ }; typedef struct data_object_s *data_object_t; static struct data_object_s data_objects[] = { - { 0x5FC107, 1, 0,1, 1, 0,0, 0, "", "1.219.0", "Card Capability Container"}, - { 0x5FC102, 1, 0,0, 1, 0,0, 0, "", "2.48.0", "Cardholder Unique Id" }, - { 0x5FC105, 1, 0,1, 1, 0,0, 1, "9A", "2.1.1", "Cert PIV Authentication" }, - { 0x5FC103, 1, 2,2, 1, 0,0, 0, "", "2.96.16", "Cardholder Fingerprints" }, - { 0x5FC106, 1, 0,1, 1, 0,0, 0, "", "2.144.0", "Security Object" }, - { 0x5FC108, 1, 2,2, 1, 0,0, 0, "", "2.96.48", "Cardholder Facial Image" }, - { 0x5FC101, 1, 0,0, 1, 0,0, 1, "9E", "2.5.0", "Cert Card Authentication"}, - { 0x5FC10A, 0, 0,1, 1, 0,0, 1, "9C", "2.1.0", "Cert Digital Signature" }, - { 0x5FC10B, 0, 0,1, 1, 0,0, 1, "9D", "2.1.2", "Cert Key Management" }, - { 0x5FC109, 0, 3,3, 0, 0,0, 0, "", "2.48.1", "Printed Information" }, - { 0x7E, 0, 0,0, 1, 0,0, 0, "", "2.96.80", "Discovery Object" }, - { 0x5FC10C, 0, 0,1, 1, 0,0, 0, "", "2.96.96", "Key History Object" }, - { 0x5FC10D, 0, 0,1, 1, 0,0, 0, "82", "2.16.1", "Retired Cert Key Mgm 1" }, - { 0x5FC10E, 0, 0,1, 1, 0,0, 0, "83", "2.16.2", "Retired Cert Key Mgm 2" }, - { 0x5FC10F, 0, 0,1, 1, 0,0, 0, "84", "2.16.3", "Retired Cert Key Mgm 3" }, - { 0x5FC110, 0, 0,1, 1, 0,0, 0, "85", "2.16.4", "Retired Cert Key Mgm 4" }, - { 0x5FC111, 0, 0,1, 1, 0,0, 0, "86", "2.16.5", "Retired Cert Key Mgm 5" }, - { 0x5FC112, 0, 0,1, 1, 0,0, 0, "87", "2.16.6", "Retired Cert Key Mgm 6" }, - { 0x5FC113, 0, 0,1, 1, 0,0, 0, "88", "2.16.7", "Retired Cert Key Mgm 7" }, - { 0x5FC114, 0, 0,1, 1, 0,0, 0, "89", "2.16.8", "Retired Cert Key Mgm 8" }, - { 0x5FC115, 0, 0,1, 1, 0,0, 0, "8A", "2.16.9", "Retired Cert Key Mgm 9" }, - { 0x5FC116, 0, 0,1, 1, 0,0, 0, "8B", "2.16.10", "Retired Cert Key Mgm 10" }, - { 0x5FC117, 0, 0,1, 1, 0,0, 0, "8C", "2.16.11", "Retired Cert Key Mgm 11" }, - { 0x5FC118, 0, 0,1, 1, 0,0, 0, "8D", "2.16.12", "Retired Cert Key Mgm 12" }, - { 0x5FC119, 0, 0,1, 1, 0,0, 0, "8E", "2.16.13", "Retired Cert Key Mgm 13" }, - { 0x5FC11A, 0, 0,1, 1, 0,0, 0, "8F", "2.16.14", "Retired Cert Key Mgm 14" }, - { 0x5FC11B, 0, 0,1, 1, 0,0, 0, "90", "2.16.15", "Retired Cert Key Mgm 15" }, - { 0x5FC11C, 0, 0,1, 1, 0,0, 0, "91", "2.16.16", "Retired Cert Key Mgm 16" }, - { 0x5FC11D, 0, 0,1, 1, 0,0, 0, "92", "2.16.17", "Retired Cert Key Mgm 17" }, - { 0x5FC11E, 0, 0,1, 1, 0,0, 0, "93", "2.16.18", "Retired Cert Key Mgm 18" }, - { 0x5FC11F, 0, 0,1, 1, 0,0, 0, "94", "2.16.19", "Retired Cert Key Mgm 19" }, - { 0x5FC120, 0, 0,1, 1, 0,0, 0, "95", "2.16.20", "Retired Cert Key Mgm 20" }, - { 0x5FC121, 0, 2,2, 1, 0,0, 0, "", "2.16.21", "Cardholder Iris Images" }, - { 0x7F61, 0, 0,0, 1, 0,0, 0, "", "2.16.22", "BIT Group Template" }, - { 0x5FC122, 0, 0,0, 1, 0,0, 0, "", "2.16.23", "SM Cert Signer" }, - { 0x5FC123, 0, 3,3, 1, 0,0, 0, "", "2.16.24", "Pairing Code Ref Data" }, + { 0x5FC107, 1, 0,1, 0,0, 0, "", "1.219.0", NULL, + "Card Capability Container"}, + { 0x5FC102, 1, 0,0, 0,0, 0, "", "2.48.0", NULL, + "Cardholder Unique Id" }, + { 0x5FC105, 1, 0,1, 0,0, 1, "9A", "2.1.1", "a", + "Cert PIV Authentication" }, + { 0x5FC103, 1, 2,2, 0,0, 0, "", "2.96.16", NULL, + "Cardholder Fingerprints" }, + { 0x5FC106, 1, 0,1, 0,0, 0, "", "2.144.0", NULL, + "Security Object" }, + { 0x5FC108, 1, 2,2, 0,0, 0, "", "2.96.48", NULL, + "Cardholder Facial Image" }, + { 0x5FC101, 1, 0,0, 0,0, 1, "9E", "2.5.0", "a", + "Cert Card Authentication"}, + { 0x5FC10A, 0, 0,1, 0,0, 1, "9C", "2.1.0", "sc", + "Cert Digital Signature" }, + { 0x5FC10B, 0, 0,1, 0,0, 1, "9D", "2.1.2", "e", + "Cert Key Management" }, + { 0x5FC109, 0, 3,3, 0,0, 0, "", "2.48.1", NULL, + "Printed Information" }, + { 0x7E, 0, 0,0, 0,0, 0, "", "2.96.80", NULL, + "Discovery Object" }, + { 0x5FC10C, 0, 0,1, 0,0, 0, "", "2.96.96", NULL, + "Key History Object" }, + { 0x5FC10D, 0, 0,1, 0,0, 0, "82", "2.16.1", "e", + "Retired Cert Key Mgm 1" }, + { 0x5FC10E, 0, 0,1, 0,0, 0, "83", "2.16.2", "e", + "Retired Cert Key Mgm 2" }, + { 0x5FC10F, 0, 0,1, 0,0, 0, "84", "2.16.3", "e", + "Retired Cert Key Mgm 3" }, + { 0x5FC110, 0, 0,1, 0,0, 0, "85", "2.16.4", "e", + "Retired Cert Key Mgm 4" }, + { 0x5FC111, 0, 0,1, 0,0, 0, "86", "2.16.5", "e", + "Retired Cert Key Mgm 5" }, + { 0x5FC112, 0, 0,1, 0,0, 0, "87", "2.16.6", "e", + "Retired Cert Key Mgm 6" }, + { 0x5FC113, 0, 0,1, 0,0, 0, "88", "2.16.7", "e", + "Retired Cert Key Mgm 7" }, + { 0x5FC114, 0, 0,1, 0,0, 0, "89", "2.16.8", "e", + "Retired Cert Key Mgm 8" }, + { 0x5FC115, 0, 0,1, 0,0, 0, "8A", "2.16.9", "e", + "Retired Cert Key Mgm 9" }, + { 0x5FC116, 0, 0,1, 0,0, 0, "8B", "2.16.10", "e", + "Retired Cert Key Mgm 10" }, + { 0x5FC117, 0, 0,1, 0,0, 0, "8C", "2.16.11", "e", + "Retired Cert Key Mgm 11" }, + { 0x5FC118, 0, 0,1, 0,0, 0, "8D", "2.16.12", "e", + "Retired Cert Key Mgm 12" }, + { 0x5FC119, 0, 0,1, 0,0, 0, "8E", "2.16.13", "e", + "Retired Cert Key Mgm 13" }, + { 0x5FC11A, 0, 0,1, 0,0, 0, "8F", "2.16.14", "e", + "Retired Cert Key Mgm 14" }, + { 0x5FC11B, 0, 0,1, 0,0, 0, "90", "2.16.15", "e", + "Retired Cert Key Mgm 15" }, + { 0x5FC11C, 0, 0,1, 0,0, 0, "91", "2.16.16", "e", + "Retired Cert Key Mgm 16" }, + { 0x5FC11D, 0, 0,1, 0,0, 0, "92", "2.16.17", "e", + "Retired Cert Key Mgm 17" }, + { 0x5FC11E, 0, 0,1, 0,0, 0, "93", "2.16.18", "e", + "Retired Cert Key Mgm 18" }, + { 0x5FC11F, 0, 0,1, 0,0, 0, "94", "2.16.19", "e", + "Retired Cert Key Mgm 19" }, + { 0x5FC120, 0, 0,1, 0,0, 0, "95", "2.16.20", "e", + "Retired Cert Key Mgm 20" }, + { 0x5FC121, 0, 2,2, 0,0, 0, "", "2.16.21", NULL, + "Cardholder Iris Images" }, + { 0x7F61, 0, 0,0, 0,0, 0, "", "2.16.22", NULL, + "BIT Group Template" }, + { 0x5FC122, 0, 0,0, 0,0, 0, "", "2.16.23", NULL, + "SM Cert Signer" }, + { 0x5FC123, 0, 3,3, 0,0, 0, "", "2.16.24", NULL, + "Pairing Code Ref Data" }, { 0 } /* Other key reference values without a data object: * "00" Global PIN (not cleared by application switching) @@ -396,7 +432,10 @@ dump_all_do (int slot) } else { - if (data_objects[i].binary) + if (data_objects[i].tag == 0x5FC109) + log_info ("DO '%s': '%.*s'\n", data_objects[i].desc, + (int)buflen, buffer); + else { log_info ("DO '%s': ", data_objects[i].desc); if (buflen > 16 && opt.verbose < 2) @@ -407,10 +446,6 @@ dump_all_do (int slot) else log_printhex (buffer, buflen, ""); } - else - log_info ("DO '%s': '%.*s'\n", - data_objects[i].desc, - (int)buflen, buffer); } xfree (buffer); buffer = NULL; @@ -1079,15 +1114,19 @@ send_keypair_and_cert_info (app_t app, ctrl_t ctrl, data_object_t dobj, char *keygripstr = NULL; int got_cert; char idbuf[50]; + const char *usage; err = get_keygrip_by_tag (app, dobj->tag, &keygripstr, &got_cert); if (err) goto leave; + usage = dobj->usage? dobj->usage : ""; + snprintf (idbuf, sizeof idbuf, "PIV.%s", dobj->keyref); send_status_info (ctrl, "KEYPAIRINFO", keygripstr, strlen (keygripstr), idbuf, strlen (idbuf), + usage, strlen (usage), NULL, (size_t)0); if (!only_keypair && got_cert) { diff --git a/scd/command.c b/scd/command.c index 237faf0..b4098e4 100644 --- a/scd/command.c +++ b/scd/command.c @@ -354,7 +354,7 @@ static const char hlp_learn[] = "\n" "are implemented. These strings are aliases for the AID\n" "\n" - " S KEYPAIRINFO \n" + " S KEYPAIRINFO []\n" "\n" "If there is no certificate yet stored on the card a single 'X' is\n" "returned as the keygrip. In addition to the keypair info, information\n" ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 10 ++++ scd/app-piv.c | 129 ++++++++++++++++++++++++++++++++------------------ scd/command.c | 2 +- sm/certreqgen.c | 2 +- tools/card-call-scd.c | 49 +++++++++++++++---- tools/card-tool.h | 2 +- tools/gpg-card-tool.c | 20 +++++++- 7 files changed, 156 insertions(+), 58 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 22 06:49:16 2019 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Fri, 22 Feb 2019 06:49:16 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-2.3.2-31-g5e21862 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 5e218623fd5d8e1793bf833d1fbbfc961e2c5784 (commit) via 0d8baad07bced3db6f008a475d6fc0afdf5ff18c (commit) via bd4516dd3aa7ede9ac3852797d2ac2ad84cd69a1 (commit) from 815c500864db46e7bc4a9f5d4b8ccd942e60fd15 (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 5e218623fd5d8e1793bf833d1fbbfc961e2c5784 Author: Andre Heinecke Date: Fri Feb 22 06:47:18 2019 +0100 Add decrypt permanently feature * src/gpgoladdin.cpp (GpgolRibbonExtender::GetIDsOfNames), (GpgolRibbonExtender::Invoke), (GetCustomUI_MIME): Add decrypt permanently. * src/mail.cpp (Mail::decryptPermanently_o): New. * src/ribbon-callbacks.cpp (decrypt_permanently): Wire up. diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp index c098a0b..4cc8c75 100644 --- a/src/gpgoladdin.cpp +++ b/src/gpgoladdin.cpp @@ -718,6 +718,7 @@ GpgolRibbonExtender::GetIDsOfNames (REFIID riid, LPOLESTR *rgszNames, ID_MAPPER (L"printDecrypted", ID_CMD_PRINT_DECRYPTED) ID_MAPPER (L"openContactKey", ID_CMD_OPEN_CONTACT_KEY) ID_MAPPER (L"overrideFileClose", ID_CMD_FILE_CLOSE) + ID_MAPPER (L"decryptPermanently", ID_CMD_DECRYPT_PERMANENTLY) } if (cNames > 1) @@ -805,6 +806,8 @@ GpgolRibbonExtender::Invoke (DISPID dispid, REFIID riid, LCID lcid, } case ID_CMD_PRINT_DECRYPTED: return print_decrypted (parms->rgvarg[0].pdispVal); + case ID_CMD_DECRYPT_PERMANENTLY: + return decrypt_permanently (parms->rgvarg[0].pdispVal); case ID_GET_IS_CRYPTO_MAIL: return get_is_crypto_mail (parms->rgvarg[0].pdispVal, result); case ID_CMD_OPEN_CONTACT_KEY: @@ -1035,6 +1038,13 @@ GetCustomUI_MIME (BSTR RibbonID, BSTR * RibbonXml) " getVisible=\"getIsCrypto\"" " insertAfterMso=\"FilePrintQuick\"" " />" + "