Merge branch 'STABLE-BRANCH-2-2' into master
authorWerner Koch <wk@gnupg.org>
Mon, 18 Dec 2017 15:38:02 +0000 (16:38 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 18 Dec 2017 15:42:59 +0000 (16:42 +0100)
--

Signed-off-by: Werner Koch <wk@gnupg.org>
82 files changed:
AUTHORS
NEWS
README
agent/agent.h
agent/call-pinentry.c
agent/call-scd.c
agent/command-ssh.c
agent/command.c
agent/cvt-openpgp.c
agent/divert-scd.c
agent/pkdecrypt.c
agent/protect.c
common/Makefile.am
common/asshelp.c
common/exechelp-posix.c
common/exechelp-w32.c
common/exechelp-w32ce.c
common/exechelp.h
common/logging.c
common/logging.h
common/miscellaneous.c
common/pkscreening.c [new file with mode: 0644]
common/pkscreening.h [new file with mode: 0644]
common/sysutils.c
common/util.h
configure.ac
dirmngr/crlcache.c
dirmngr/dirmngr.c
dirmngr/http.c
dirmngr/misc.c
doc/DETAILS
doc/HACKING
doc/Makefile.am
doc/examples/README
doc/examples/qualified.txt [moved from doc/qualified.txt with 98% similarity]
doc/gpgsm.texi
doc/howto-create-a-server-cert.texi
doc/wks.texi
g10/call-agent.c
g10/card-util.c
g10/ecdh.c
g10/encrypt.c
g10/getkey.c
g10/gpg.c
g10/gpg.h
g10/gpgcompose.c
g10/keyedit.c
g10/keygen.c
g10/keyid.c
g10/keylist.c
g10/main.h
g10/misc.c
g10/options.h
g10/pubkey-enc.c
g10/sig-check.c
g10/tdbdump.c
g10/tofu.c
g13/call-syshelp.c
g13/g13tuple.c
kbx/kbxutil.c
scd/apdu.c
scd/apdu.h
scd/app-openpgp.c
scd/app-p15.c
scd/iso7816.c
sm/certchain.c
sm/certcheck.c
sm/certdump.c
sm/certreqgen-ui.c
sm/certreqgen.c
sm/decrypt.c
sm/fingerprint.c
sm/gpgsm.c
sm/gpgsm.h
sm/import.c
sm/keylist.c
sm/qualified.c
sm/verify.c
tests/openpgp/Makefile.am
tests/openpgp/all-tests.scm
tests/openpgp/defs.scm
tools/gpgconf-comp.c

diff --git a/AUTHORS b/AUTHORS
index d27dfb6..dd86d53 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -38,15 +38,185 @@ List of Copyright holders
 Authors with a FSF copyright assignment
 =======================================
 
-The list of authors who signed a FSF copyright assignment is kept in
-the GIT master branch's copy of this file.
+Ales Nyakhaychyk <nyakhaychyk@i1fn.linux.by> Translations [be]
+
+Andrey Jivsov <openpgp@brainhub.org>  Assigns past and future changes for ECC.
+    (g10/ecdh.c.  other changes to support ECC)
+
+Ben Kibbey  <bjk@luxsci.net>  Assigns past and future changes.
+
+Birger Langkjer <birger.langkjer@image.dk> Translations [da]
+
+Maxim Britov <maxim.britov@gmail.com> Translations [ru]
+
+Daniel Resare  <daniel@resare.com> Translations [sv]
+Per Tunedal    <per@clipanish.com> Translations [sv]
+Daniel Nylander <po@danielnylander.se> Translations [sv]
+
+Daiki Ueno <ueno@unixuser.org>  Assigns Past and Future Changes.
+    (changed:passphrase.c and related code)
+
+David Shaw <dshaw@jabberwocky.com> Assigns past and future changes.
+    (all in keyserver/,
+     a lot of changes in g10/ see the ChangeLog,
+     bug fixes here and there)
+
+Dokianakis Theofanis <madf@hellug.gr> Translations [el]
+
+Edmund GRIMLEY EVANS <edmundo@rano.org> Translations [eo]
+
+Florian Weimer <fw@deneb.enyo.de>  Assigns past and future changes
+    (changed:g10/parse-packet.c, include/iobuf.h, util/iobuf.c)
+
+g10 Code GmbH   <info@g10code.com>  Assigns past and future changes
+    (all work since 2001 as indicated by mail addresses in ChangeLogs)
+
+Gaël Quéri  <gael@lautre.net>  Translations [fr]
+    (fixed a lot of typos)
+
+Gregory Steuck <steuck@iname.com> Translations [ru]
+
+Nagy Ferenc László <nfl@nfllab.com> Translations [hu]
+
+Ivo Timmermans <itimmermans@bigfoot.com> Translations [nl]
+
+Jacobo Tarri'o Barreiro <jtarrio@iname.com> Translations [gl]
+
+Janusz Aleksander Urbanowicz <alex@bofh.torun.pl> Translations [pl]
+Jakub Bogusz <qboosh@pld-linux.org> Translations [pl]
+
+Jedi Lin <Jedi@idej.org> Translations [zh-tw]
+
+Jouni Hiltunen <jouni.hiltunen@kolumbus.fi> Translations [fi]
+Tommi Vainikainen <Tommi.Vainikainen@iki.fi> Translations [fi]
+
+Laurentiu Buzdugan <lbgnupg@rolix.org> Translations [ro]
+
+Magda Procha'zkova'  <magda@math.muni.cz> Translations [cs]
+
+Michael Roth  <mroth@nessie.de>  Assigns changes.
+    (wrote cipher/des.c., changes and bug fixes all over the place)
+
+Michal Majer <mmajer@econ.umb.sk> Translations [sk]
+
+Marco d'Itri <md@linux.it> Translations [it]
+
+Marcus Brinkmann  <marcus@g10code.de>
+    (gpgconf and fixes all over the place)
+
+Matthew Skala <mskala@ansuz.sooke.bc.ca>  Disclaimer
+    (wrote cipher/twofish.c)
+
+Moritz Schulte  <moritz@g10code.com>
+   (ssh support gpg-agent)
+
+Niklas Hernaeus <nh@df.lth.se> Disclaimer
+    (weak key patches)
+
+Nilgun Belma Buguner <nilgun@technologist.com> Translations [tr]
+
+Nils Ellmenreich  <nils 'at' infosun.fmi.uni-passau.de>
+                                      Assigns past and future changes
+    (configure.in, cipher/rndlinux.c, FAQ)
+
+Paul Eggert <eggert@twinsun.com>
+    (configuration macros for LFS)
+
+Pavel I. Shajdo <pshajdo@gmail.com> Translations [ru]
+    (man pages)
+
+Pedro Morais <morais@poli.org> Translations [pt_PT]
+
+Rémi Guyomarch        <rguyom@mail.dotcom.fr> Assigns past and future changes.
+    (g10/compress.c, g10/encr-data.c,
+     g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
+
+Stefan Bellon   <sbellon@sbellon.de> Assigns past and future changes.
+   (All patches to support RISC OS)
+
+Timo Schulz     <twoaday@freakmail.de> Assigns past and future changes.
+   (util/w32reg.c, g10/passphrase.c, g10/hkp.c)
+
+Tedi Heriyanto <tedi_h@gmx.net> Translations [id]
+
+Thiago Jung Bauermann <jungmann@cwb.matrix.com.br> Translations [pt_BR]
+Rafael Caetano dos Santos <rcaetano@linux.ime.usp.br> Translations [pt_BR]
+
+Toomas Soome <tsoome@ut.ee> Translations [et]
+
+Urko Lusa <ulusa@euskalnet.net> Translations [es_ES]
+
+Walter Koch <koch@u32.de>  Translations [de]
+
+Werner Koch  <wk@gnupg.org>  Assigns GNU Privacy Guard and future changes.
+    (started the whole thing, wrote the S/MIME extensions, the
+     smartcard daemon and the gpg-agent)
+
+Yosiaki IIDA <iida@ring.gr.jp> Translations [ja]
+
+Yuri Chornoivan, yurchor at ukr dot net: Translations [uk]
+
+Yutaka Niibe   Assigns Past and Future Changes
+     (scd/)
 
 
 Authors with a DCO
 ==================
 
-The list of authors who signed the Developer's Certificate of Origin
-is kept in the GIT master branch's copy of this file.
+Andre Heinecke <aheinecke@intevation.de>
+2014-09-19:4525694.FcpLvWDUFT@esus:
+
+Andreas Schwier <andreas.schwier@cardcontact.de>
+2014-07-22:53CED1D8.1010306@cardcontact.de:
+
+Christian Aistleitner <christian@quelltextlich.at>
+2013-05-26:20130626112332.GA2228@quelltextlich.at:
+
+Damien Goutte-Gattat <dgouttegattat@incenp.org>
+2015-01-17:54BA49AA.2040708@incenp.org:
+
+Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+2014-09-24:87oau6w9q7.fsf@alice.fifthhorseman.net:
+
+Hans of Guardian <hans@guardianproject.info>
+2013-06-26:D84473D7-F3F7-43D5-A9CE-16580B88D574@guardianproject.info:
+
+Ineiev <ineiev@gnu.org>
+2017-05-09:20170509121611.GH25850@gnu.org:
+
+Jonas Borgström <jonas@borgstrom.se>
+2013-08-29:521F1E7A.5080602@borgstrom.se:
+
+Joshua Rogers <git@internot.info>
+2014-12-22:5497FE75.7010503@internot.info:
+
+Kyle Butt <kylebutt@gmail.com>
+2013-05-29:CAAODAYLbCtqOG6msLLL0UTdASKWT6u2ptxsgUQ1JpusBESBoNQ@mail.gmail.com:
+
+Stefan Tomanek <tomanek@internet-sicherheit.de>
+2014-01-30:20140129234449.GY30808@zirkel.wertarbyte.de:
+
+Tobias Mueller <muelli@cryptobitch.de>
+2016-11-23:1479937342.11180.3.camel@cryptobitch.de:
+
+Werner Koch <wk@gnupg.org>
+2013-03-29:87620ahchj.fsf@vigenere.g10code.de:
+
+William L. Thomson Jr. <wlt@o-sinc.com>
+2017-05-23:assp.0316398ca8.20170523093623.00a17d03@o-sinc.com:
+
+Yann E. MORIN <yann.morin.1998@free.fr>
+2016-07-10:20160710093202.GA3688@free.fr:
+
+Arnaud Fontaine <arnaud.fontaine at ssi.gouv.fr>
+2016-10-17:580484F4.8040806@ssi.gouv.fr:
+
+Phil Pennock <phil.pennock@spodhuis.org>
+Phil Pennock <phil@pennock-tech.com>
+2017-01-19:20170119061225.GA26207@breadbox.private.spodhuis.org:
+
+Rainer Perske <rainer.perske@uni-muenster.de>
+2017-10-24:permail-2017102014511105be2aed00002fc6-perske@message-id.uni-muenster.de:
 
 
 Other authors
diff --git a/NEWS b/NEWS
index f59b9cd..b0bb8ba 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,7 @@
-Noteworthy changes in version 2.2.4 (unreleased)
+Noteworthy changes in version 2.3.0 (unreleased)
 ------------------------------------------------
 
-
-Noteworthy changes in version 2.2.3 (2017-11-20)
-------------------------------------------------
+  Changes also found in 2.2.3:
 
   * gpgsm: Fix initial keybox creation on Windows. [#3507]
 
@@ -20,9 +18,7 @@ Noteworthy changes in version 2.2.3 (2017-11-20)
   * agent: Improve robustness of the shutdown pending
     state. [Git#7ffedfab89]
 
-
-Noteworthy changes in version 2.2.2 (2017-11-07)
-------------------------------------------------
+  Changes also found in 2.2.2:
 
   * gpg: Avoid duplicate key imports by concurrently running gpg
     processes. [#3446]
@@ -63,11 +59,7 @@ Noteworthy changes in version 2.2.2 (2017-11-07)
 
   * Add configure option --enable-werror.  [#2423]
 
-  See-also: gnupg-announce/2017q4/000416.html
-
-
-Noteworthy changes in version 2.2.1 (2017-09-19)
-------------------------------------------------
+  Changes also found in 2.2.1:
 
   * gpg: Fix formatting of the user id in batch mode key generation
     if only "name-email" is given.
@@ -87,7 +79,11 @@ Noteworthy changes in version 2.2.1 (2017-09-19)
     certificates are configured.  If build with GNUTLS, this was
     already the case.
 
-  See-also: gnupg-announce/2017q3/000415.html
+  Release dates of 2.2.x versions:
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  Version 2.2.1 (2017-09-19)
+  Version 2.2.2 (2017-11-07)
+  Version 2.2.3 (2017-11-20)
 
 
 Noteworthy changes in version 2.2.0 (2017-08-28)
diff --git a/README b/README
index 23f705a..f4b549c 100644 (file)
--- a/README
+++ b/README
@@ -26,7 +26,8 @@
 
   Note that the 2.0 series of GnuPG will reach end-of-life on
   2017-12-31.  It is not possible to install a 2.2.x version along
-  with any 2.0.x version.
+  with any 2.0.x version.  However, it is possible to install GnuPG
+  1.4 along with any 2.x version.
 
 
 * BUILD INSTRUCTIONS
index c2d8579..687635d 100644 (file)
@@ -230,6 +230,7 @@ struct server_control_s
   char *lc_ctype;
   char *lc_messages;
   unsigned long client_pid;
+  int client_uid;
 
   /* The current pinentry mode.  */
   pinentry_mode_t pinentry_mode;
index a088681..af4eb06 100644 (file)
@@ -598,8 +598,9 @@ start_pinentry (ctrl_t ctrl)
         nodename = utsbuf.nodename;
 #endif /*!HAVE_W32_SYSTEM*/
 
-      if ((optstr = xtryasprintf ("OPTION owner=%lu %s",
-                                  ctrl->client_pid, nodename)))
+      if ((optstr = xtryasprintf ("OPTION owner=%lu/%d %s",
+                                  ctrl->client_pid, ctrl->client_uid,
+                                  nodename)))
         {
           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
                            NULL);
index cf61a35..6ce0cdd 100644 (file)
@@ -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)
index 9d45a18..866f439 100644 (file)
@@ -255,6 +255,11 @@ static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
 static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
 
 
+struct peer_info_s
+{
+  unsigned long pid;
+  int uid;
+};
 
 /* Global variables.  */
 
@@ -3581,10 +3586,11 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
 
 
 /* Return the peer's pid.  */
-static unsigned long
-get_client_pid (int fd)
+static void
+get_client_info (int fd, struct peer_info_s *out)
 {
-  pid_t client_pid = (pid_t)0;
+  pid_t client_pid = (pid_t)(-1);
+  uid_t client_uid = (uid_t)-1;
 
 #ifdef SO_PEERCRED
   {
@@ -3599,8 +3605,10 @@ get_client_pid (int fd)
       {
 #if defined (HAVE_STRUCT_SOCKPEERCRED_PID) || defined (HAVE_STRUCT_UCRED_PID)
         client_pid = cr.pid;
+        client_uid = cr.uid;
 #elif defined (HAVE_STRUCT_UCRED_CR_PID)
         client_pid = cr.cr_pid;
+        client_pid = cr.cr_uid;
 #else
 #error "Unknown SO_PEERCRED struct"
 #endif
@@ -3611,6 +3619,7 @@ get_client_pid (int fd)
     socklen_t len = sizeof (pid_t);
 
     getsockopt (fd, SOL_LOCAL, LOCAL_PEERPID, &client_pid, &len);
+    getsockopt (fd, SOL_LOCAL, LOCAL_PEERUID, &client_uid, &len);
   }
 #elif defined (LOCAL_PEEREID)
   {
@@ -3619,6 +3628,7 @@ get_client_pid (int fd)
 
     if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
       client_pid = unp.unp_pid;
+      client_uid = unp.unp_euid;
   }
 #elif defined (HAVE_GETPEERUCRED)
   {
@@ -3626,7 +3636,8 @@ get_client_pid (int fd)
 
     if (getpeerucred (fd, &ucred) != -1)
       {
-        client_pid= ucred_getpid (ucred);
+        client_pid = ucred_getpid (ucred);
+       client_uid = ucred_geteuid (ucred);
         ucred_free (ucred);
       }
   }
@@ -3634,7 +3645,8 @@ get_client_pid (int fd)
   (void)fd;
 #endif
 
-  return (unsigned long)client_pid;
+  out->pid = (client_pid == (pid_t)(-1)? 0 : (unsigned long)client_pid);
+  out->uid = (int)client_uid;
 }
 
 
@@ -3645,12 +3657,15 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
   estream_t stream_sock = NULL;
   gpg_error_t err;
   int ret;
+  struct peer_info_s peer_info;
 
   err = agent_copy_startup_env (ctrl);
   if (err)
     goto out;
 
-  ctrl->client_pid = get_client_pid (FD2INT(sock_client));
+  get_client_info (FD2INT(sock_client), &peer_info);
+  ctrl->client_pid = peer_info.pid;
+  ctrl->client_uid = peer_info.uid;
 
   /* Create stream from socket.  */
   stream_sock = es_fdopen (FD2INT(sock_client), "r+");
index 0916f88..7c7e8a4 100644 (file)
@@ -874,7 +874,7 @@ static const char hlp_genkey[] =
   "\n"
   "  C: GENKEY\n"
   "  S: INQUIRE KEYPARAM\n"
-  "  C: D (genkey (rsa (nbits  2048)))\n"
+  "  C: D (genkey (rsa (nbits 3072)))\n"
   "  C: END\n"
   "  S: D (public-key\n"
   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
@@ -3347,7 +3347,7 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
 
   for (;;)
     {
-      pid_t client_pid;
+      assuan_peercred_t client_creds;
 
       rc = assuan_accept (ctx);
       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
@@ -3360,12 +3360,20 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
           break;
         }
 
-      client_pid = assuan_get_pid (ctx);
-      ctrl->server_local->connect_from_self = (client_pid == getpid ());
-      if (client_pid != ASSUAN_INVALID_PID)
-        ctrl->client_pid = (unsigned long)client_pid;
+      rc = assuan_get_peercred (ctx, &client_creds);
+      if (rc)
+        {
+          log_info ("Assuan get_peercred failed: %s\n", gpg_strerror (rc));
+          client_creds->pid = assuan_get_pid (ctx);
+          ctrl->client_uid = -1;
+        }
+      ctrl->server_local->connect_from_self =
+        (client_creds->pid == getpid ());
+      if (client_creds->pid != ASSUAN_INVALID_PID)
+        ctrl->client_pid = (unsigned long)client_creds->pid;
       else
         ctrl->client_pid = 0;
+      ctrl->client_uid = client_creds->uid;
 
       rc = assuan_process (ctx);
       if (rc)
index ee12221..c4d0334 100644 (file)
@@ -878,11 +878,11 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp, int dontcare_exist,
   log_debug ("XXX pubkey_algo=%d\n", pubkey_algo);
   log_debug ("XXX is_protected=%d\n", is_protected);
   log_debug ("XXX protect_algo=%d\n", protect_algo);
-  log_printhex ("XXX iv", iv, ivlen);
+  log_printhex (iv, ivlen, "XXX iv");
   log_debug ("XXX ivlen=%d\n", ivlen);
   log_debug ("XXX s2k_mode=%d\n", s2k_mode);
   log_debug ("XXX s2k_algo=%d\n", s2k_algo);
-  log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt);
+  log_printhex (s2k_salt, sizeof s2k_salt, "XXX s2k_salt");
   log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count);
   log_debug ("XXX curve='%s'\n", curve);
   for (idx=0; skey[idx]; idx++)
index 88b35cd..b85b490 100644 (file)
@@ -169,7 +169,7 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
   memcpy (frame, asn, asnlen);
   memcpy (frame+asnlen, digest, digestlen);
   if (DBG_CRYPTO)
-    log_printhex ("encoded hash:", frame, asnlen+digestlen);
+    log_printhex (frame, asnlen+digestlen, "encoded hash:");
 
   *r_val = frame;
   *r_len = asnlen+digestlen;
index 46697ba..06a8e0b 100644 (file)
@@ -64,8 +64,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
 
   if (DBG_CRYPTO)
     {
-      log_printhex ("keygrip:", ctrl->keygrip, 20);
-      log_printhex ("cipher: ", ciphertext, ciphertextlen);
+      log_printhex (ctrl->keygrip, 20, "keygrip:");
+      log_printhex (ciphertext, ciphertextlen, "cipher: ");
     }
   rc = agent_key_from_file (ctrl, NULL, desc_text,
                             ctrl->keygrip, &shadow_info,
index 7b5abf2..16ae715 100644 (file)
@@ -163,7 +163,7 @@ calibrate_s2k_count_one (unsigned long count)
 
 
 /* Measure the time we need to do the hash operations and deduce an
-   S2K count which requires about 100ms of time.  */
+   S2K count which requires roughly some targeted amount of time.  */
 static unsigned long
 calibrate_s2k_count (void)
 {
@@ -175,11 +175,11 @@ calibrate_s2k_count (void)
       ms = calibrate_s2k_count_one (count);
       if (opt.verbose > 1)
         log_info ("S2K calibration: %lu -> %lums\n", count, ms);
-      if (ms > 100)
+      if (ms > AGENT_S2K_CALIBRATION)
         break;
     }
 
-  count = (unsigned long)(((double)count / ms) * 100);
+  count = (unsigned long)(((double)count / ms) * AGENT_S2K_CALIBRATION);
   count /= 1024;
   count *= 1024;
   if (count < 65536)
index fcbe7ea..94318da 100644 (file)
@@ -94,7 +94,8 @@ common_sources = \
        name-value.c name-value.h \
        recsel.c recsel.h \
        ksba-io-support.c ksba-io-support.h \
-       compliance.c compliance.h
+       compliance.c compliance.h \
+       pkscreening.c pkscreening.h
 
 
 if HAVE_W32_SYSTEM
index f3a92f9..5209ea6 100644 (file)
@@ -93,7 +93,7 @@ my_libassuan_log_handler (assuan_context_t ctx, void *hook,
     return 0; /* Temporary disabled.  */
 
   if (msg)
-    log_string (GPGRT_LOG_DEBUG, msg);
+    log_string (GPGRT_LOGLVL_DEBUG, msg);
 
   return 1;
 }
@@ -307,6 +307,71 @@ unlock_spawning (lock_spawn_t *lock, const char *name)
     }
 }
 
+
+/* Helper for start_new_gpg_agent and start_new_dirmngr.
+ * Values for WHICH are:
+ *   0 - Start gpg-agent
+ *   1 - Start dirmngr
+ * SECS give the number of seconds to wait.  SOCKNAME is the name of
+ * the socket to connect.  VERBOSE is the usual verbose flag. CTX is
+ * the assuan context.  DID_SUCCESS_MSG will be set to 1 if a success
+ * messages has been printed.
+ */
+static gpg_error_t
+wait_for_sock (int secs, int which, const char *sockname,
+               int verbose, assuan_context_t ctx, int *did_success_msg)
+{
+  gpg_error_t err = 0;
+  int target_us = secs * 1000000;
+  int elapsed_us = 0;
+  /*
+   * 977us * 1024 = just a little more than 1s.
+   * so we will double this timeout 10 times in the first
+   * second, and then switch over to 1s checkins.
+   */
+  int next_sleep_us = 977;
+  int lastalert = secs+1;
+  int secsleft;
+
+  while (elapsed_us < target_us)
+    {
+      if (verbose)
+        {
+          secsleft = (target_us - elapsed_us + 999999)/1000000;
+          /* log_clock ("left=%d last=%d targ=%d elap=%d next=%d\n", */
+          /*            secsleft, lastalert, target_us, elapsed_us, */
+          /*            next_sleep_us); */
+          if (secsleft < lastalert)
+            {
+              log_info (which == 1?
+                        _("waiting for the dirmngr to come up ... (%ds)\n"):
+                        _("waiting for the agent to come up ... (%ds)\n"),
+                        secsleft);
+              lastalert = secsleft;
+            }
+        }
+      gnupg_usleep (next_sleep_us);
+      elapsed_us += next_sleep_us;
+      err = assuan_socket_connect (ctx, sockname, 0, 0);
+      if (!err)
+        {
+          if (verbose)
+            {
+              log_info (which == 1?
+                        _("connection to the dirmngr established\n"):
+                        _("connection to the agent established\n"));
+              *did_success_msg = 1;
+            }
+          break;
+        }
+      next_sleep_us *= 2;
+      if (next_sleep_us > 1000000)
+        next_sleep_us = 1000000;
+    }
+  return err;
+}
+
+
 /* Try to connect to the agent via socket or start it if it is not
    running and AUTOSTART is set.  Handle the server's initial
    greeting.  Returns a new assuan context at R_CTX or an error
@@ -433,25 +498,8 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
             log_error ("failed to start agent '%s': %s\n",
                        agent_program, gpg_strerror (err));
           else
-            {
-              for (i=0; i < SECS_TO_WAIT_FOR_AGENT; i++)
-                {
-                  if (verbose)
-                    log_info (_("waiting for the agent to come up ... (%ds)\n"),
-                              SECS_TO_WAIT_FOR_AGENT - i);
-                  gnupg_sleep (1);
-                  err = assuan_socket_connect (ctx, sockname, 0, 0);
-                  if (!err)
-                    {
-                      if (verbose)
-                        {
-                          log_info (_("connection to agent established\n"));
-                          did_success_msg = 1;
-                        }
-                      break;
-                    }
-                }
-            }
+            err = wait_for_sock (SECS_TO_WAIT_FOR_AGENT, 0,
+                                 sockname, verbose, ctx, &did_success_msg);
         }
 
       unlock_spawning (&lock, "agent");
@@ -468,7 +516,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
     }
 
   if (debug && !did_success_msg)
-    log_debug ("connection to agent established\n");
+    log_debug ("connection to the agent established\n");
 
   err = assuan_transact (ctx, "RESET",
                          NULL, NULL, NULL, NULL, NULL, NULL);
@@ -485,7 +533,7 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
                                 NULL, NULL, NULL, NULL, NULL, NULL))
             {
               if (verbose)
-                log_info (_("connection to agent is in restricted mode\n"));
+                log_info (_("connection to the agent is in restricted mode\n"));
               err = 0;
             }
         }
@@ -542,7 +590,7 @@ start_new_dirmngr (assuan_context_t *r_ctx,
         dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
 
       if (verbose)
-        log_info (_("no running Dirmngr - starting '%s'\n"),
+        log_info (_("no running dirmngr - starting '%s'\n"),
                   dirmngr_program);
 
       if (status_cb)
@@ -584,29 +632,8 @@ start_new_dirmngr (assuan_context_t *r_ctx,
             log_error ("failed to start the dirmngr '%s': %s\n",
                        dirmngr_program, gpg_strerror (err));
           else
-            {
-              int i;
-
-              for (i=0; i < SECS_TO_WAIT_FOR_DIRMNGR; i++)
-                {
-                  if (verbose)
-                    log_info (_("waiting for the dirmngr "
-                                "to come up ... (%ds)\n"),
-                              SECS_TO_WAIT_FOR_DIRMNGR - i);
-                  gnupg_sleep (1);
-                  err = assuan_socket_connect (ctx, sockname, 0, 0);
-                  if (!err)
-                    {
-                      if (verbose)
-                        {
-                          log_info (_("connection to the dirmngr"
-                                      " established\n"));
-                          did_success_msg = 1;
-                        }
-                      break;
-                    }
-                }
-            }
+            err = wait_for_sock (SECS_TO_WAIT_FOR_DIRMNGR, 1,
+                                 sockname, verbose, ctx, &did_success_msg);
         }
 
       unlock_spawning (&lock, "dirmngr");
index 7237993..425f2b4 100644 (file)
@@ -1,6 +1,6 @@
 /* exechelp.c - Fork and exec helpers for POSIX
- * Copyright (C) 2004, 2007, 2008, 2009,
- *               2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2007-2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2006-2012, 2014-2017 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -26,6 +26,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: (LGPL-3.0+ OR GPL-2.0+)
  */
 
 #include <config.h>
@@ -784,30 +785,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);
index 2c44e2c..fddcbb6 100644 (file)
@@ -1,6 +1,6 @@
 /* exechelp-w32.c - Fork and exec helpers for W32.
- * Copyright (C) 2004, 2007, 2008, 2009,
- *               2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2007-2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2006-2012, 2014-2017 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -26,6 +26,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: (LGPL-3.0+ OR GPL-2.0+)
  */
 
 #include <config.h>
index ec9f014..3d68a01 100644 (file)
@@ -1,6 +1,6 @@
 /* exechelp-w32.c - Fork and exec helpers for W32CE.
- * Copyright (C) 2004, 2007, 2008, 2009,
- *               2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2007-2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2010-2012, 2014-2016 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -26,6 +26,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: (LGPL-3.0+ OR GPL-2.0+)
  */
 
 #include <config.h>
index 2b40ba0..9e1f56f 100644 (file)
@@ -1,5 +1,6 @@
 /* exechelp.h - Definitions for the fork and exec helpers
  * Copyright (C) 2004, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2006-2012, 2014-2017 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -25,6 +26,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: (LGPL-3.0+ OR GPL-2.0+)
  */
 
 #ifndef GNUPG_COMMON_EXECHELP_H
index c4eaca4..88860e7 100644 (file)
 #include "logging.h"
 #include "sysutils.h"
 
+#if defined(GPGRT_ENABLE_LOG_MACROS) && defined(log_debug_string)
+      /* Nothing to do; the libgpgrt functions are used.  */
+#else /* Use our own logging functions.  */
+
 #ifdef HAVE_W32_SYSTEM
 # ifndef S_IRWXG
 #  define S_IRGRP S_IRUSR
@@ -885,7 +889,7 @@ log_logv (int level, const char *fmt, va_list arg_ptr)
  * Note that PREFIX is an additional string and independent of the
  * prefix set by log_set_prefix.  */
 void
-log_logv_with_prefix (int level, const char *prefix,
+log_logv_prefix (int level, const char *prefix,
                       const char *fmt, va_list arg_ptr)
 {
   do_logv (level, 0, NULL, prefix, fmt, arg_ptr);
@@ -977,7 +981,7 @@ log_debug (const char *fmt, ...)
  * printed with LFs expanded to include the prefix and a final --end--
  * marker.  */
 void
-log_debug_with_string (const char *string, const char *fmt, ...)
+log_debug_string (const char *string, const char *fmt, ...)
 {
   va_list arg_ptr ;
 
@@ -1011,7 +1015,7 @@ log_flush (void)
    dump, with TEXT just an empty string, print a trailing linefeed,
    otherwise print an entire debug line. */
 void
-log_printhex (const char *text, const void *buffer, size_t length)
+log_printhex (const void *buffer, size_t length, const char *text)
 {
   if (text && *text)
     log_debug ("%s ", text);
@@ -1039,14 +1043,16 @@ log_printsexp () {}
 is found in sexputils.c
 */
 
-
+/* Print a microsecond timestamp followed by a FORMAT.  */
 void
-log_clock (const char *string)
+log_clock (const char *fmt, ...)
 {
-#if 0
+#if ENABLE_LOG_CLOCK
   static unsigned long long initial;
   struct timespec tv;
   unsigned long long now;
+  char clockbuf[50];
+  va_list arg_ptr;
 
   if (clock_gettime (CLOCK_REALTIME, &tv))
     {
@@ -1059,11 +1065,21 @@ log_clock (const char *string)
   if (!initial)
     initial = now;
 
-  log_debug ("[%6llu] %s", (now - initial)/1000, string);
-#else
-  /* You need to link with -ltr to enable the above code.  */
-  log_debug ("[not enabled in the source] %s", string);
-#endif
+  snprintf (clockbuf, sizeof clockbuf, "[%6llu] ", (now - initial)/1000);
+  va_start (arg_ptr, fmt);
+  do_logv (GPGRT_LOG_DEBUG, 0, NULL, clockbuf, fmt, arg_ptr);
+  va_end (arg_ptr);
+
+#else /*!ENABLE_LOG_CLOCK*/
+
+  /* You may need to link with -ltr to use the above code.  */
+  va_list arg_ptr;
+
+  va_start (arg_ptr, fmt);
+  do_logv (GPGRT_LOG_DEBUG, 0, NULL, "[no clock] ", fmt, arg_ptr);
+  va_end (arg_ptr);
+
+#endif  /*!ENABLE_LOG_CLOCK*/
 }
 
 
@@ -1101,3 +1117,5 @@ _log_assert (const char *expr, const char *file, int line)
   abort (); /* Never called; just to make the compiler happy.  */
 }
 #endif /*!GPGRT_HAVE_MACRO_FUNCTION*/
+
+#endif /* Use our own logging functions.  */
index e1bf56b..5a82be4 100644 (file)
 #include "mischelp.h"
 #include "w32help.h"
 
+#if defined(GPGRT_ENABLE_LOG_MACROS) && defined(log_debug_string)
+  /* We use the libgpg-error provided log functions.  but we need one
+   * more function:  */
+# ifdef GPGRT_HAVE_MACRO_FUNCTION
+#  define BUG() bug_at ( __FILE__, __LINE__, __FUNCTION__)
+static inline void bug_at (const char *file, int line, const char *func)
+                           GPGRT_ATTR_NORETURN;
+static inline void
+bug_at (const char *file, int line, const char *func)
+{
+  gpgrt_log (GPGRT_LOGLVL_BUG, "there is a bug at %s:%d:%s\n",
+             file, line, func);
+  abort ();
+}
+# else
+#  define BUG() bug_at ( __FILE__, __LINE__)
+static inline void bug_at (const char *file, int line)
+                           GPGRT_ATTR_NORETURN;
+static inline void
+bug_at (const char *file, int line)
+{
+  gpgrt_log (GPGRT_LOGLVL_BUG, "there is a bug at %s:%d\n", file, line);
+  abort ();
+}
+# endif /*!GPGRT_HAVE_MACRO_FUNCTION*/
+
+
+#else /* Use gnupg internal logging functions.  */
+
 int  log_get_errorcount (int clear);
 void log_inc_errorcount (void);
 void log_set_file( const char *name );
@@ -88,18 +117,27 @@ enum jnlib_log_levels {
     GPGRT_LOG_BUG,
     GPGRT_LOG_DEBUG
 };
+#define GPGRT_LOGLVL_BEGIN  GPGRT_LOG_BEGIN
+#define GPGRT_LOGLVL_CONT   GPGRT_LOG_CONT
+#define GPGRT_LOGLVL_INFO   GPGRT_LOG_INFO
+#define GPGRT_LOGLVL_WARN   GPGRT_LOG_WARN
+#define GPGRT_LOGLVL_ERROR  GPGRT_LOG_ERROR
+#define GPGRT_LOGLVL_FATAL  GPGRT_LOG_FATAL
+#define GPGRT_LOGLVL_BUG    GPGRT_LOG_BUG
+#define GPGRT_LOGLVL_DEBUG  GPGRT_LOG_DEBUG
+
 void log_log (int level, const char *fmt, ...) GPGRT_ATTR_PRINTF(2,3);
 void log_logv (int level, const char *fmt, va_list arg_ptr);
-void log_logv_with_prefix (int level, const char *prefix,
-                           const char *fmt, va_list arg_ptr);
+void log_logv_prefix (int level, const char *prefix,
+                      const char *fmt, va_list arg_ptr);
 void log_string (int level, const char *string);
 void log_bug (const char *fmt, ...)    GPGRT_ATTR_NR_PRINTF(1,2);
 void log_fatal (const char *fmt, ...)  GPGRT_ATTR_NR_PRINTF(1,2);
 void log_error (const char *fmt, ...)  GPGRT_ATTR_PRINTF(1,2);
 void log_info (const char *fmt, ...)   GPGRT_ATTR_PRINTF(1,2);
 void log_debug (const char *fmt, ...)  GPGRT_ATTR_PRINTF(1,2);
-void log_debug_with_string (const char *string, const char *fmt,
-                            ...) GPGRT_ATTR_PRINTF(2,3);
+void log_debug_string (const char *string, const char *fmt,
+                       ...) GPGRT_ATTR_PRINTF(2,3);
 void log_printf (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2);
 void log_flush (void);
 
@@ -107,9 +145,9 @@ void log_flush (void);
    raw dump, with TEXT being an empty string, print a trailing
    linefeed, otherwise print an entire debug line with TEXT followed
    by the hexdump and a final LF.  */
-void log_printhex (const char *text, const void *buffer, size_t length);
-
-void log_clock (const char *string);
+void log_printhex (const void *buffer, size_t length, const char *text);
 
+void log_clock (const char *fmt, ...) GPGRT_ATTR_PRINTF(1,2);
 
+#endif /* Use gnupg internal logging functions.  */
 #endif /*GNUPG_COMMON_LOGGING_H*/
index caeb66f..7997a1a 100644 (file)
@@ -45,14 +45,14 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
   /* Map the log levels.  */
   switch (level)
     {
-    case GCRY_LOG_CONT: level = GPGRT_LOG_CONT; break;
-    case GCRY_LOG_INFO: level = GPGRT_LOG_INFO; break;
-    case GCRY_LOG_WARN: level = GPGRT_LOG_WARN; break;
-    case GCRY_LOG_ERROR:level = GPGRT_LOG_ERROR; break;
-    case GCRY_LOG_FATAL:level = GPGRT_LOG_FATAL; break;
-    case GCRY_LOG_BUG:  level = GPGRT_LOG_BUG; break;
-    case GCRY_LOG_DEBUG:level = GPGRT_LOG_DEBUG; break;
-    default:            level = GPGRT_LOG_ERROR; break;
+    case GCRY_LOG_CONT: level = GPGRT_LOGLVL_CONT; break;
+    case GCRY_LOG_INFO: level = GPGRT_LOGLVL_INFO; break;
+    case GCRY_LOG_WARN: level = GPGRT_LOGLVL_WARN; break;
+    case GCRY_LOG_ERROR:level = GPGRT_LOGLVL_ERROR; break;
+    case GCRY_LOG_FATAL:level = GPGRT_LOGLVL_FATAL; break;
+    case GCRY_LOG_BUG:  level = GPGRT_LOGLVL_BUG; break;
+    case GCRY_LOG_DEBUG:level = GPGRT_LOGLVL_DEBUG; break;
+    default:            level = GPGRT_LOGLVL_ERROR; break;
     }
   log_logv (level, fmt, arg_ptr);
 }
diff --git a/common/pkscreening.c b/common/pkscreening.c
new file mode 100644 (file)
index 0000000..a3bfb47
--- /dev/null
@@ -0,0 +1,159 @@
+/* pkscreening.c - Screen public keys for vulnerabilities
+ * Copyright (C) 2017 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file 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 file 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 Lesser General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+
+#include "util.h"
+#include "pkscreening.h"
+
+
+/* Helper */
+static inline gpg_error_t
+my_error (gpg_err_code_t ec)
+{
+  return gpg_err_make (default_errsource, ec);
+}
+
+
+/* Emulation of the new gcry_mpi_get_ui function.  */
+static gpg_error_t
+my_mpi_get_ui (unsigned int *v, gcry_mpi_t a)
+{
+  gpg_error_t err;
+  unsigned char buf[8];
+  size_t n;
+  int i, mul;
+
+  if (gcry_mpi_cmp_ui (a, 16384) > 0)
+    return my_error (GPG_ERR_ERANGE); /* Clearly too large for our purpose.  */
+
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, a);
+  if (err)
+    return err;
+
+  *v = 0;
+  for (i = n - 1, mul = 1; i >= 0; i--, mul *= 256)
+    *v += mul * buf[i];
+
+  return 0;
+}
+
+
+/* Detect whether the MODULUS of a public RSA key is affected by the
+ * ROCA vulnerability as found in the Infinion RSA library
+ * (CVE-2017-15361).  Returns 0 if not affected, GPG_ERR_TRUE if
+ * affected, GPG_ERR_BAD_MPI if an opaque RSA was passed, or other
+ * error codes if something weird happened  */
+gpg_error_t
+screen_key_for_roca (gcry_mpi_t modulus)
+{
+  static struct {
+    unsigned int prime_ui;
+    const char *print_hex;
+    gcry_mpi_t prime;
+    gcry_mpi_t print;
+  } table[] = {
+   { 3,   "0x6" },
+   { 5,   "0x1E" },
+   { 7,   "0x7E" },
+   { 11,  "0x402" },
+   { 13,  "0x161A" },
+   { 17,  "0x1A316" },
+   { 19,  "0x30AF2" },
+   { 23,  "0x7FFFFE" },
+   { 29,  "0x1FFFFFFE" },
+   { 31,  "0x7FFFFFFE" },
+   { 37,  "0x4000402"  },
+   { 41,  "0x1FFFFFFFFFE" },
+   { 43,  "0x7FFFFFFFFFE" },
+   { 47,  "0x7FFFFFFFFFFE" },
+   { 53,  "0x12DD703303AED2" },
+   { 59,  "0x7FFFFFFFFFFFFFE" },
+   { 61,  "0x1434026619900B0A" },
+   { 67,  "0x7FFFFFFFFFFFFFFFE" },
+   { 71,  "0x1164729716B1D977E" },
+   { 73,  "0x147811A48004962078A" },
+   { 79,  "0xB4010404000640502"   },
+   { 83,  "0x7FFFFFFFFFFFFFFFFFFFE" },
+   { 89,  "0x1FFFFFFFFFFFFFFFFFFFFFE" },
+   { 97,  "0x1000000006000001800000002" },
+   { 101, "0x1FFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 103, "0x16380E9115BD964257768FE396" },
+   { 107, "0x27816EA9821633397BE6A897E1A" },
+   { 109, "0x1752639F4E85B003685CBE7192BA" },
+   { 113, "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 127, "0x6CA09850C2813205A04C81430A190536" },
+   { 131, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 137, "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 139, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 149, "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 151, "0x50C018BC00482458DAC35B1A2412003D18030A" },
+   { 157, "0x161FB414D76AF63826461899071BD5BACA0B7E1A" },
+   { 163, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
+   { 167, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" }
+  };
+  gpg_error_t err;
+  int i;
+  gcry_mpi_t rem;
+  unsigned int bitno;
+
+  /* Initialize on the first call. */
+  if (!table[0].prime)
+    {
+      /* We pass primes[i] to the call so that in case of a concurrent
+       * second thread the already allocated space is reused.  */
+      for (i = 0; i < DIM (table); i++)
+        {
+          table[i].prime = gcry_mpi_set_ui (table[i].prime, table[i].prime_ui);
+          if (gcry_mpi_scan (&table[i].print, GCRYMPI_FMT_HEX,
+                             table[i].print_hex, 0, NULL))
+            BUG ();
+        }
+    }
+
+  /* Check that it is not NULL or an opaque MPI.  */
+  if (!modulus || gcry_mpi_get_flag (modulus, GCRYMPI_FLAG_OPAQUE))
+    return my_error (GPG_ERR_BAD_MPI);
+
+  /* We divide the modulus of an RSA public key by a set of small
+   * PRIMEs and examine all the remainders.  If all the bits at the
+   * index given by the remainder are set in the corresponding PRINT
+   * masks the key is very likely vulnerable.  If any of the tested
+   * bits is zero, the key is not vulnerable.  */
+  rem = gcry_mpi_new (0);
+  for (i = 0; i < DIM (table); i++)
+    {
+      gcry_mpi_mod (rem, modulus, table[i].prime);
+      err = my_mpi_get_ui (&bitno, rem);
+      if (gpg_err_code (err) == GPG_ERR_ERANGE)
+        continue;
+      if (err)
+        goto leave;
+      if (!gcry_mpi_test_bit (table[i].print, bitno))
+        goto leave;  /* Not vulnerable.  */
+    }
+
+  /* Very likely vulnerable */
+  err = my_error (GPG_ERR_TRUE);
+
+ leave:
+  gcry_mpi_release (rem);
+  return err;
+}
diff --git a/common/pkscreening.h b/common/pkscreening.h
new file mode 100644 (file)
index 0000000..a647589
--- /dev/null
@@ -0,0 +1,26 @@
+/* pkscreening.c - Screen public keys for vulnerabilities
+ * Copyright (C) 2017 Werner Koch
+ *
+ * This file is part of GnuPG.
+ *
+ * This file 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 file 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 Lesser General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_PKSCREENING_H
+#define GNUPG_COMMON_PKSCREENING_H
+
+gpg_error_t screen_key_for_roca (gcry_mpi_t modulus);
+
+
+#endif /*GNUPG_COMMON_PKSCREENING_H*/
index e90010c..55a7ee9 100644 (file)
@@ -340,11 +340,10 @@ gnupg_usleep (unsigned int usecs)
       struct timespec req;
       struct timespec rem;
 
-      req.tv_sec = 0;
-      req.tv_nsec = usecs * 1000;
-
+      req.tv_sec  = usecs / 1000000;
+      req.tv_nsec = (usecs % 1000000) * 1000;
       while (nanosleep (&req, &rem) < 0 && errno == EINTR)
-        req = rem;
+          req = rem;
     }
 
 #else /*Standard Unix*/
index c6d19c6..f372281 100644 (file)
 /* Hash function used with libksba. */
 #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
 
+/* The length of the keygrip.  This is a SHA-1 hash of the key
+ * parameters as generated by gcry_pk_get_keygrip.  */
+#define KEYGRIP_LEN 20
+
+
 /* Get all the stuff from jnlib. */
 #include "../common/logging.h"
 #include "../common/argparse.h"
index 382ef1d..311979a 100644 (file)
@@ -27,8 +27,8 @@ min_automake_version="1.14"
 # another commit and push so that the git magic is able to work.
 m4_define([mym4_package],[gnupg])
 m4_define([mym4_major], [2])
-m4_define([mym4_minor], [2])
-m4_define([mym4_micro], [4])
+m4_define([mym4_minor], [3])
+m4_define([mym4_micro], [0])
 
 # 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
@@ -116,8 +116,8 @@ use_tls_library=no
 large_secmem=no
 show_tor_support=no
 
-
-GNUPG_BUILD_PROGRAM(gpg, yes)
+# gpg is a required part and can't be disabled anymore.
+build_gpg=yes
 GNUPG_BUILD_PROGRAM(gpgsm, yes)
 # The agent is a required part and can't be disabled anymore.
 build_agent=yes
@@ -244,6 +244,15 @@ fi
 AC_DEFINE_UNQUOTED(SECMEM_BUFFER_SIZE,$SECMEM_BUFFER_SIZE,
                    [Size of secure memory buffer])
 
+AC_MSG_CHECKING([calibrated passphrase-stretching (s2k) duration])
+AC_ARG_WITH(agent-s2k-calibration,
+              AC_HELP_STRING([--with-agent-s2k-calibration=MSEC],
+                             [calibrate passphrase stretching (s2k) to MSEC milliseconds]),
+              agent_s2k_calibration=$withval, agent_s2k_calibration=100)
+AC_MSG_RESULT($agent_s2k_calibration milliseconds)
+AC_DEFINE_UNQUOTED(AGENT_S2K_CALIBRATION, $agent_s2k_calibration,
+                   [Agent s2k calibration time (ms)])
+
 AC_MSG_CHECKING([whether to enable trust models])
 AC_ARG_ENABLE(trust-models,
               AC_HELP_STRING([--disable-trust-models],
@@ -548,9 +557,12 @@ AH_BOTTOM([
 # endif
 #endif
 
-/* Provide the es_ macro for estream.  */
+/* Enable the es_ macros from gpgrt.  */
 #define GPGRT_ENABLE_ES_MACROS 1
 
+/* Enable the log_ macros from gpgrt.  */
+#define GPGRT_ENABLE_LOG_MACROS 1
+
 /* Tell libgcrypt not to use its own libgpg-error implementation. */
 #define USE_LIBGPG_ERROR 1
 
@@ -602,9 +614,8 @@ AC_PROG_RANLIB
 AC_CHECK_TOOL(AR, ar, :)
 AC_PATH_PROG(PERL,"perl")
 AC_CHECK_TOOL(WINDRES, windres, :)
-AC_PATH_PROG(YAT2M, "yat2m")
+AC_PATH_PROG(YAT2M, "yat2m", "./yat2m" )
 AC_ARG_VAR(YAT2M, [tool to convert texi to man pages])
-AM_CONDITIONAL(HAVE_YAT2M, test -n "$ac_cv_path_YAT2M")
 AC_ISC_POSIX
 AC_SYS_LARGEFILE
 GNUPG_CHECK_USTAR
@@ -1600,7 +1611,7 @@ if test "$GCC" = yes; then
           AC_MSG_RESULT($_gcc_wopt)
         fi
         if test x"$_gcc_wopt" = xyes ; then
-          mycflags="$mycflags -W -Wno-sign-compare"
+          mycflags="$mycflags -W -Wno-sign-compare -Wno-format-zero-length"
           mycflags="$mycflags -Wno-missing-field-initializers"
         fi
 
@@ -1675,6 +1686,19 @@ AC_ARG_ENABLE(optimization,
                    fi])
 
 #
+# log_debug has certain requirements which might hamper portability.
+# Thus we use an option to enable it.
+#
+AC_MSG_CHECKING([whether to enable log_clock])
+AC_ARG_ENABLE(log_clock,
+              AC_HELP_STRING([--enable-log-clock],
+                             [enable log_clock timestamps]),
+              enable_log_clock=$enableval, enable_log_clock=no)
+AC_MSG_RESULT($enable_log_clock)
+if test "$enable_log_clock" = yes ; then
+  AC_DEFINE(ENABLE_LOG_CLOCK,1,[Defined to use log_clock timestamps])
+fi
+
 # Add -Werror to CFLAGS.  This hack can be used to avoid problems with
 # misbehaving autoconf tests in case the user supplied -Werror.
 #
index 6eeeb8d..8687c7b 100644 (file)
@@ -1346,7 +1346,7 @@ cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
         {
           log_error (_("WARNING: invalid cache record length for S/N "));
           log_printf ("0x");
-          log_printhex ("", sn, snlen);
+          log_printhex (sn, snlen, "");
         }
       else if (opt.verbose)
         {
index 17adae2..00caf06 100644 (file)
@@ -787,12 +787,12 @@ my_ntbtls_log_handler (void *opaque, int level, const char *fmt, va_list argv)
   (void)opaque;
 
   if (level == -1)
-    log_logv_with_prefix (GPGRT_LOG_INFO, "ntbtls: ", fmt, argv);
+    log_logv_prefix (GPGRT_LOGLVL_INFO, "ntbtls: ", fmt, argv);
   else
     {
       char prefix[10+20];
       snprintf (prefix, sizeof prefix, "ntbtls(%d): ", level);
-      log_logv_with_prefix (GPGRT_LOG_DEBUG, prefix, fmt, argv);
+      log_logv_prefix (GPGRT_LOGLVL_DEBUG, prefix, fmt, argv);
     }
 }
 #endif
@@ -1203,6 +1203,14 @@ main (int argc, char **argv)
           current_logfile = xstrdup (logfile);
         }
 
+      if (debug_wait)
+        {
+          log_debug ("waiting for debugger - my pid is %u .....\n",
+                     (unsigned int)getpid());
+          gnupg_sleep (debug_wait);
+          log_debug ("... okay\n");
+        }
+
 #ifndef HAVE_W32_SYSTEM
       if (strchr (socket_name, ':'))
         {
index 8e778df..cc7f5a5 100644 (file)
@@ -1053,7 +1053,7 @@ http_start_data (http_t hd)
   if (!hd->in_data)
     {
       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
-        log_debug_with_string ("\r\n", "http.c:request-header:");
+        log_debug_string ("\r\n", "http.c:request-header:");
       es_fputs ("\r\n", hd->fp_write);
       es_fflush (hd->fp_write);
       hd->in_data = 1;
@@ -1844,7 +1844,7 @@ send_request (http_t hd, const char *httphost, const char *auth,
         return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
 
       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
-        log_debug_with_string (request, "http.c:request:");
+        log_debug_string (request, "http.c:request:");
 
       cookie = xtrycalloc (1, sizeof *cookie);
       if (! cookie)
@@ -2159,7 +2159,7 @@ send_request (http_t hd, const char *httphost, const char *auth,
     }
 
   if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
-    log_debug_with_string (request, "http.c:request:");
+    log_debug_string (request, "http.c:request:");
 
   /* First setup estream so that we can write even the first line
      using estream.  This is also required for the sake of gnutls. */
@@ -2195,7 +2195,7 @@ send_request (http_t hd, const char *httphost, const char *auth,
       for (;headers; headers=headers->next)
         {
           if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
-            log_debug_with_string (headers->d, "http.c:request-header:");
+            log_debug_string (headers->d, "http.c:request-header:");
           if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
               || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
             {
@@ -2446,7 +2446,7 @@ parse_response (http_t hd)
        return GPG_ERR_EOF;
 
       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
-        log_debug_with_string (line, "http.c:response:\n");
+        log_debug_string (line, "http.c:response:\n");
     }
   while (!*line);
 
index 6291a9a..1270b83 100644 (file)
@@ -284,7 +284,7 @@ dump_string (const char *string)
       else
         {
           log_printf ( "[ ");
-          log_printhex (NULL, string, strlen (string));
+          log_printhex (string, strlen (string), NULL);
           log_printf ( " ]");
         }
     }
index e54e8a0..3c089b2 100644 (file)
@@ -222,12 +222,14 @@ described here.
 
 *** Field 18 - Compliance flags
 
-    Space separated list of asserted compliance modes for this key.
+    Space separated list of asserted compliance modes and
+    screening result for this key.
 
     Valid values are:
 
     - 8  :: The key is compliant with RFC4880bis
     - 23 :: The key is compliant with compliance mode "de-vs".
+    - 6001 :: Screening hit on the ROCA vulnerability.
 
 *** Field 19 - Last update
 
index bd16856..17c5826 100644 (file)
@@ -33,9 +33,9 @@ not be copied to the ChangeLog, separate it by a line consisting of
 two dashes at the begin of a line.
 
 The one-line summary usually starts with a keyword to identify the
-mainly affected subsystem.  If more than one keyword is required the
-are delimited by a comma (e.g. =scd,w32:=). Commonly found keywords
-are
+mainly affected subsystem (that is not the directory).  If more than
+one keyword is required they are delimited by a comma
+(e.g. =scd,w32:=). Commonly found keywords are
 
  - agent   :: The gpg-agent component
  - build   :: Changes to the build system
@@ -207,10 +207,6 @@ Note that such a comment will be removed if the git commit option
   - The predefined macro =__func__=:
     : log_debug ("%s: Problem with foo\n", __func__);
 
-  - Variable declaration inside a for():
-    : for (int i = 0; i < 5; ++)
-    :   bar (i);
-
   Although we usually make use of the =u16=, =u32=, and =u64= types,
   it is also possible to include =<stdint.h>= and use =int16_t=,
   =int32_t=, =int64_t=, =uint16_t=, =uint32_t=, and =uint64_t=.  But do
index aba84ba..21e3e45 100644 (file)
@@ -22,7 +22,7 @@ AM_CPPFLAGS =
 include $(top_srcdir)/am/cmacros.am
 
 examples = examples/README examples/scd-event examples/trustlist.txt   \
-          examples/vsnfd.prf examples/debug.prf                        \
+          examples/vsnfd.prf examples/debug.prf examples/qualified.txt \
           examples/systemd-user/README                                 \
           examples/systemd-user/dirmngr.service                        \
           examples/systemd-user/dirmngr.socket                         \
@@ -43,7 +43,7 @@ helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt              \
 
 profiles =
 
-EXTRA_DIST = samplekeys.asc mksamplekeys com-certs.pem qualified.txt \
+EXTRA_DIST = samplekeys.asc mksamplekeys com-certs.pem \
             gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png gnupg-logo-tr.png \
             gnupg-module-overview.png gnupg-module-overview.pdf \
              gnupg-card-architecture.png gnupg-card-architecture.pdf \
@@ -112,16 +112,8 @@ DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \
                  gnupg-module-overview.eps \
                 $(myman_pages) gnupg.7
 
-if HAVE_YAT2M
-YAT2M_CMD = $(YAT2M)
-YAT2M_DEP = $(YAT2M)
-else
-YAT2M_CMD = ./yat2m
-YAT2M_DEP = yat2m
-
 yat2m: yat2m.c
        $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c
-endif
 
 mkdefsinc: mkdefsinc.c Makefile ../config.h
        $(CC_FOR_BUILD) -I. -I.. -I$(srcdir) $(AM_CPPFLAGS) \
@@ -154,12 +146,12 @@ yat2m-stamp: $(myman_sources) defs.inc
        @touch yat2m-stamp.tmp
        incd="`test -f defsincdate || echo '$(srcdir)/'`defsincdate"; \
        for file in $(myman_sources) ; do \
-              $(YAT2M_CMD) $(YAT2M_OPTIONS) --store \
+              $(YAT2M) $(YAT2M_OPTIONS) --store \
                   --date "`cat $$incd 2>/dev/null`" \
                  `test -f '$$file' || echo '$(srcdir)/'`$$file ; done
        @mv -f yat2m-stamp.tmp $@
 
-yat2m-stamp: $(YAT2M_DEP)
+yat2m-stamp: $(YAT2M)
 
 $(myman_pages) gnupg.7 : yat2m-stamp defs.inc
        @if test -f $@; then :; else \
index 77ee807..4d6a5be 100644 (file)
@@ -9,3 +9,5 @@ trustlist.txt   A list of trustworthy root certificates
 gpgconf.conf    A sample configuration file for gpgconf.
 
 systemd-user    Sample files for a Linux-only init system.
+
+qualified.txt   Sample file for qualified.txt.
similarity index 98%
rename from doc/qualified.txt
rename to doc/examples/qualified.txt
index c0e4da5..eba11f2 100644 (file)
@@ -29,7 +29,7 @@
 #
 #                 Germany
 #
-# The information for Germany is available 
+# The information for Germany is available
 # at http://www.bundesnetzagentur.de
 #*******************************************
 
@@ -74,7 +74,7 @@ DB:45:3D:1B:B0:1A:F3:23:10:6B:DE:D0:09:61:57:AA:F4:25:E0:5B  de
 #Serial number: 02
 #       Issuer: /CN=9R-CA 1:PN/O=Regulierungsbehörde für
 #               Telekommunikation und Post/C=DE
-#      Subject: /CN=9R-CA 1:PN/O=Regulierungsbehörde für 
+#      Subject: /CN=9R-CA 1:PN/O=Regulierungsbehörde für
 #               Telekommunikation und Post/C=DE
 #     validity: 2004-11-25 14:59:11 through 2007-12-31 14:56:59
 #     key type: 1024 bit RSA
@@ -118,7 +118,7 @@ A0:8B:DF:3B:AA:EE:3F:9D:64:6C:47:81:23:21:D4:A6:18:81:67:1D  de
 #    key usage: certSign
 #     policies: 1.3.36.8.1.1:N:
 # chain length: unlimited
-# [checked: 2008-06-25] 
+# [checked: 2008-06-25]
 44:7E:D4:E3:9A:D7:92:E2:07:FA:53:1A:2E:F5:B8:02:5B:47:57:B0  de
 
 #           ID: 0x46A2CC8A
@@ -130,7 +130,7 @@ A0:8B:DF:3B:AA:EE:3F:9D:64:6C:47:81:23:21:D4:A6:18:81:67:1D  de
 #    key usage: certSign
 #     policies: 1.3.36.8.1.1:N:
 # chain length: unlimited
-# [checked: 2008-06-25] 
+# [checked: 2008-06-25]
 AC:A7:BE:45:1F:A6:BF:09:F2:D1:3F:08:7B:BC:EB:7F:46:A2:CC:8A  de
 
 
@@ -215,7 +215,7 @@ E0:BF:1B:91:91:6B:88:E4:F1:15:92:22:CE:37:23:96:B1:4A:2E:5C  de
 #     key type: 2048 bit RSA
 #    key usage: certSign crlSign
 # chain length: 1
-#[checked: 2007-12-13 via received ZIP file with qualified signature from 
+#[checked: 2007-12-13 via received ZIP file with qualified signature from
 #         /CN=Dr. Matthias Stehle/O=Deutscher Sparkassenverlag
 #         /C=DE/SerialNumber=DSV0000000008/SN=Stehle/GN=Matthias Georg]
 C9:2F:E6:50:DB:32:59:E0:CE:65:55:F3:8C:76:E0:B8:A8:FE:A3:CA  de
@@ -230,7 +230,7 @@ C9:2F:E6:50:DB:32:59:E0:CE:65:55:F3:8C:76:E0:B8:A8:FE:A3:CA  de
 #     key type: 2048 bit RSA
 #    key usage: certSign crlSign
 # chain length: 1
-#[checked: 2007-12-13 via received ZIP file with qualified signature from 
+#[checked: 2007-12-13 via received ZIP file with qualified signature from
 #         /CN=Dr. Matthias Stehle/O=Deutscher Sparkassenverlag
 #         /C=DE/SerialNumber=DSV0000000008/SN=Stehle/GN=Matthias Georg"]
 D5:C7:50:F2:FE:4E:EE:D7:C7:B1:E4:13:7B:FB:54:84:3A:7D:97:9B  de
index 5d79ce5..b187a54 100644 (file)
@@ -843,15 +843,9 @@ purposes.
 
 Note that even if a certificate is listed in this file, this does not
 mean that the certificate is trusted; in general the certificates listed
-in this file need to be listed also in @file{trustlist.txt}.
-
-This is a global file an installed in the data directory
-(e.g. @file{@value{DATADIR}/qualified.txt}).  GnuPG installs a suitable
-file with root certificates as used in Germany.  As new Root-CA
-certificates may be issued over time, these entries may need to be
-updated; new distributions of this software should come with an updated
-list but it is still the responsibility of the Administrator to check
-that this list is correct.
+in this file need to be listed also in @file{trustlist.txt}. This is a global
+file an installed in the sysconf directory (e.g.
+@file{@value{SYSCONFDIR}/qualified.txt}).
 
 Every time @command{gpgsm} uses a certificate for signing or verification
 this file will be consulted to check whether the certificate under
@@ -1073,7 +1067,7 @@ key. The algorithm must be capable of signing.  This is a required
 parameter.  The only supported value for @var{algo} is @samp{rsa}.
 
 @item Key-Length: @var{nbits}
-The requested length of a generated key in bits.  Defaults to 2048.
+The requested length of a generated key in bits.  Defaults to 3072.
 
 @item Key-Grip: @var{hexstring}
 This is optional and used to generate a CSR or certificate for an
index 55f1a91..30e28bd 100644 (file)
@@ -31,14 +31,14 @@ Let's continue:
 
 @cartouche
 @example
-  What keysize do you want? (2048)
-  Requested keysize is 2048 bits
+  What keysize do you want? (3072)
+  Requested keysize is 3072 bits
 @end example
 @end cartouche
 
-Hitting enter chooses the default RSA key size of 2048 bits.  Smaller
-keys are too weak on the modern Internet.  If you choose a larger
-(stronger) key, your server will need to do more work.
+Hitting enter chooses the default RSA key size of 3072 bits.  Keys
+smaller than 2048 bits are too weak on the modern Internet.  If you
+choose a larger (stronger) key, your server will need to do more work.
 
 @cartouche
 @example
@@ -124,7 +124,7 @@ request:
 @example
   These parameters are used:
       Key-Type: RSA
-      Key-Length: 2048
+      Key-Length: 3072
       Key-Usage: sign, encrypt
       Name-DN: CN=example.com
       Name-DNS: example.com
@@ -224,7 +224,7 @@ To see the content of your certificate, you may now enter:
             aka: (dns-name example.com)
             aka: (dns-name www.example.com)
        validity: 2015-07-01 16:20:51 through 2016-07-01 16:20:51
-       key type: 2048 bit RSA
+       key type: 3072 bit RSA
       key usage: digitalSignature keyEncipherment
   ext key usage: clientAuth (suggested), serverAuth (suggested), [...]
     fingerprint: 0F:9C:27:B2:DA:05:5F:CB:33:D8:19:E9:65:B9:4F:BD:B1:98:CC:57
index 029dbf0..55dfee6 100644 (file)
@@ -303,11 +303,11 @@ the submission address:
 The output of the last command looks similar to this:
 
 @example
-  sec   rsa2048 2016-08-30 [SC]
+  sec   rsa3072 2016-08-30 [SC]
         C0FCF8642D830C53246211400346653590B3795B
   uid           [ultimate] key-submission@@example.net
                 bxzcxpxk8h87z1k7bzk86xn5aj47intu@@example.net
-  ssb   rsa2048 2016-08-30 [E]
+  ssb   rsa3072 2016-08-30 [E]
 @end example
 
 Take the hash of the string "key-submission", which is
index 545b244..61d06c6 100644 (file)
@@ -195,7 +195,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
   err = get_assuan_server_version (ctx, mode, &serverversion);
   if (err)
     log_log (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED?
-             GPGRT_LOG_INFO : GPGRT_LOG_ERROR,
+             GPGRT_LOGLVL_INFO : GPGRT_LOGLVL_ERROR,
              _("error getting version from '%s': %s\n"),
              servername, gpg_strerror (err));
   else if (compare_version_strings (serverversion, myversion) < 0)
@@ -1474,7 +1474,7 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
   char *p;
   kbnode_t kbctx, node;
   int nkeys;
-  unsigned char grip[20];
+  unsigned char grip[KEYGRIP_LEN];
 
   err = start_agent (ctrl, 0);
   if (err)
@@ -1854,10 +1854,16 @@ agent_pksign (ctrl_t ctrl, const char *cache_nonce,
   snprintf (line, sizeof line, "PKSIGN%s%s",
             cache_nonce? " -- ":"",
             cache_nonce? cache_nonce:"");
+
+  if (DBG_CLOCK)
+    log_clock ("enter signing");
   err = assuan_transact (agent_ctx, line,
                          put_membuf_cb, &data,
                          default_inq_cb, &dfltparm,
                          NULL, NULL);
+  if (DBG_CLOCK)
+    log_clock ("leave signing");
+
   if (err)
     xfree (get_membuf (&data, NULL));
   else
index a396b7d..854b94f 100644 (file)
@@ -212,6 +212,7 @@ get_manufacturer (unsigned int no)
     case 0x000A: return "Dangerous Things";
 
     case 0x002A: return "Magrathea";
+    case 0x0042: return "GnuPG e.V.";
 
     case 0x1337: return "Warsaw Hackerspace";
     case 0x2342: return "warpzone"; /* hackerspace Muenster.  */
@@ -530,9 +531,9 @@ current_card_status (ctrl_t ctrl, estream_t fp,
 
       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
       print_name (fp, "Language prefs ...: ", info.disp_lang);
-      tty_fprintf (fp,    "Sex ..............: %s\n",
-                   info.disp_sex == 1? _("male"):
-                   info.disp_sex == 2? _("female") : _("unspecified"));
+      tty_fprintf (fp, "Salutation .......: %s\n",
+                   info.disp_sex == 1? _("Mr."):
+                   info.disp_sex == 2? _("Mrs.") : "");
       print_name (fp, "URL of public key : ", info.pubkey_url);
       print_name (fp, "Login data .......: ", info.login_data);
       if (info.private_do[0])
@@ -1087,7 +1088,7 @@ change_sex (void)
   int rc;
 
   data = cpr_get ("cardedit.change_sex",
-                  _("Sex ((M)ale, (F)emale or space): "));
+                  _("Salutation (M = Mr., F = Mrs., or space): "));
   if (!data)
     return -1;
   trim_spaces (data);
@@ -1108,7 +1109,7 @@ change_sex (void)
 
   rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
   if (rc)
-    log_error ("error setting sex: %s\n", gpg_strerror (rc));
+    log_error ("error setting salutation: %s\n", gpg_strerror (rc));
   xfree (data);
   write_sc_op_status (rc);
   return rc;
@@ -1121,7 +1122,8 @@ change_cafpr (int fprno)
   char *data;
   const char *s;
   int i, c, rc;
-  unsigned char fpr[20];
+  unsigned char fpr[MAX_FINGERPRINT_LEN];
+  int fprlen;
 
   data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
   if (!data)
@@ -1129,7 +1131,7 @@ change_cafpr (int fprno)
   trim_spaces (data);
   cpr_kill_prompt ();
 
-  for (i=0, s=data; i < 20 && *s; )
+  for (i=0, s=data; i < MAX_FINGERPRINT_LEN && *s; )
     {
       while (spacep(s))
         s++;
@@ -1143,8 +1145,9 @@ change_cafpr (int fprno)
       fpr[i++] = c;
       s += 2;
     }
+  fprlen = i;
   xfree (data);
-  if (i != 20 || *s)
+  if ((fprlen != 20 && fprlen != 32) || *s)
     {
       tty_printf (_("Error: invalid formatted fingerprint.\n"));
       return -1;
@@ -1152,7 +1155,7 @@ change_cafpr (int fprno)
 
   rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
                           fprno==2?"CA-FPR-2":
-                          fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
+                          fprno==3?"CA-FPR-3":"x", fpr, fprlen, NULL );
   if (rc)
     log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
   write_sc_op_status (rc);
@@ -1314,12 +1317,11 @@ show_keysize_warning (void)
     return;
   shown = 1;
   tty_printf
-    (_("Note: There is no guarantee that the card "
-       "supports the requested size.\n"
-       "      If the key generation does not succeed, "
-       "please check the\n"
-       "      documentation of your card to see what "
-       "sizes are allowed.\n"));
+    (_("Note: There is no guarantee that the card supports the requested\n"
+       "      key type or size.  If the key generation does not succeed,\n"
+       "      please check the documentation of your card to see which\n"
+       "      key types and sizes are supported.\n")
+     );
 }
 
 
@@ -1379,8 +1381,12 @@ ask_card_keyattr (int keyno, unsigned int nbits)
             }
           else
             {
+              char name[30];
+
+              snprintf (name, sizeof name, "rsa%u", req_nbits);
               tty_printf (_("The card will now be re-configured"
-                            " to generate a key of %u bits\n"), req_nbits);
+                            " to generate a key of type: %s\n"),
+                          name);
               show_keysize_warning ();
               return req_nbits;
             }
@@ -1885,7 +1891,8 @@ static struct
     { "fetch"   , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
     { "login"   , cmdLOGIN , 1, N_("change the login name")},
     { "lang"    , cmdLANG  , 1, N_("change the language preferences")},
-    { "sex"     , cmdSEX   , 1, N_("change card holder's sex")},
+    { "salutation",cmdSEX  , 1, N_("change card holder's salutation")},
+    { "sex"       ,cmdSEX  , 1, NULL },  /* Backward compatibility.  */
     { "cafpr"   , cmdCAFPR , 1, N_("change a CA fingerprint")},
     { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
     { "generate", cmdGENERATE, 1, N_("generate new keys")},
index 6c2a56b..6587cc4 100644 (file)
@@ -76,7 +76,7 @@ pk_ecdh_default_params (unsigned int qbits)
     }
   log_assert (i < DIM (kek_params_table));
   if (DBG_CRYPTO)
-    log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) );
+    log_printhex (kek_params, sizeof(kek_params), "ECDH KEK params are");
 
   return gcry_mpi_set_opaque (NULL, kek_params, 4 * 8);
 }
@@ -159,7 +159,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
       memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
 
     if (DBG_CRYPTO)
-      log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size );
+      log_printhex (secret_x, secret_x_size, "ECDH shared secret X is:");
   }
 
   /*** We have now the shared secret bytes in secret_x. ***/
@@ -179,7 +179,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
   kek_params_size = (nbits+7)/8;
 
   if (DBG_CRYPTO)
-    log_printhex ("ecdh KDF params:", kek_params, kek_params_size);
+    log_printhex (kek_params, kek_params_size, "ecdh KDF params:");
 
   /* Expect 4 bytes  03 01 hash_alg symm_alg.  */
   if (kek_params_size != 4 || kek_params[0] != 3 || kek_params[1] != 1)
@@ -236,7 +236,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
       }
 
     if(DBG_CRYPTO)
-      log_printhex ("ecdh KDF message params are:", message, message_size);
+      log_printhex (message, message_size, "ecdh KDF message params are:");
   }
 
   /* Derive a KEK (key wrapping key) using MESSAGE and SECRET_X. */
@@ -272,7 +272,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
     /* We could have allocated more, so clean the tail before returning.  */
     memset (secret_x+secret_x_size, 0, old_size - secret_x_size);
     if (DBG_CRYPTO)
-      log_printhex ("ecdh KEK is:", secret_x, secret_x_size );
+      log_printhex (secret_x, secret_x_size, "ecdh KEK is:");
   }
 
   /* And, finally, aeswrap with key secret_x.  */
@@ -338,7 +338,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
           }
 
         if (DBG_CRYPTO)
-          log_printhex ("ecdh encrypting  :", in, data_buf_size );
+          log_printhex (in, data_buf_size, "ecdh encrypting  :");
 
         err = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8,
                                    in, data_buf_size);
@@ -354,7 +354,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
         data_buf[0] = data_buf_size+8;
 
         if (DBG_CRYPTO)
-          log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] );
+          log_printhex (data_buf+1, data_buf[0], "ecdh encrypted to:");
 
         result = gcry_mpi_set_opaque (NULL, data_buf, 8 * (1+data_buf[0]));
         if (!result)
@@ -391,7 +391,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
         data_buf_size = data_buf[0];
 
         if (DBG_CRYPTO)
-          log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size);
+          log_printhex (data_buf+1, data_buf_size, "ecdh decrypting :");
 
         err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1,
                                    data_buf_size);
@@ -407,7 +407,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
         data_buf_size -= 8;
 
         if (DBG_CRYPTO)
-          log_printhex ("ecdh decrypted to :", in, data_buf_size);
+          log_printhex (in, data_buf_size, "ecdh decrypted to :");
 
         /* Padding is removed later.  */
         /* if (in[data_buf_size-1] > 8 ) */
index c68d6d5..263226a 100644 (file)
@@ -697,7 +697,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
 
   make_session_key (cfx.dek);
   if (DBG_CRYPTO)
-    log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
+    log_printhex (cfx.dek->key, cfx.dek->keylen, "DEK is: ");
 
   rc = write_pubkey_enc_from_list (ctrl, pk_list, cfx.dek, out);
   if (rc)
@@ -891,7 +891,7 @@ encrypt_filter (void *opaque, int control,
 
           make_session_key ( efx->cfx.dek );
           if (DBG_CRYPTO)
-            log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
+            log_printhex (efx->cfx.dek->key, efx->cfx.dek->keylen, "DEK is: ");
 
           rc = write_pubkey_enc_from_list (efx->ctrl,
                                            efx->pk_list, efx->cfx.dek, a);
index e31e023..dabd052 100644 (file)
@@ -144,7 +144,7 @@ static int lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
                   kbnode_t *ret_keyblock, kbnode_t *ret_found_key);
 static kbnode_t finish_lookup (kbnode_t keyblock,
                                unsigned int req_usage, int want_exact,
-                               unsigned int *r_flags);
+                               int want_secret, unsigned int *r_flags);
 static void print_status_key_considered (kbnode_t keyblock, unsigned int flags);
 
 
@@ -1743,7 +1743,7 @@ get_pubkey_fromfile (ctrl_t ctrl, PKT_public_key *pk, const char *fname)
       /* Warning: node flag bits 0 and 1 should be preserved by
        * merge_selfsigs.  FIXME: Check whether this still holds. */
       merge_selfsigs (ctrl, keyblock);
-      found_key = finish_lookup (keyblock, pk->req_usage, 0, &infoflags);
+      found_key = finish_lookup (keyblock, pk->req_usage, 0, 0, &infoflags);
       print_status_key_considered (keyblock, infoflags);
       if (found_key)
         pk_from_block (pk, keyblock, found_key);
@@ -3494,7 +3494,7 @@ merge_selfsigs (ctrl_t ctrl, kbnode_t keyblock)
  */
 static kbnode_t
 finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
-               unsigned int *r_flags)
+               int want_secret, unsigned int *r_flags)
 {
   kbnode_t k;
 
@@ -3636,6 +3636,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
              continue;
            }
 
+          if (want_secret && agent_probe_secret_key (NULL, pk))
+            {
+              if (DBG_LOOKUP)
+                log_debug ("\tno secret key\n");
+              continue;
+            }
+
          if (DBG_LOOKUP)
            log_debug ("\tsubkey might be fine\n");
          /* In case a key has a timestamp of 0 set, we make sure
@@ -3823,7 +3830,7 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
        * merge_selfsigs.  */
       merge_selfsigs (ctrl, keyblock);
       found_key = finish_lookup (keyblock, ctx->req_usage, ctx->exact,
-                                 &infoflags);
+                                 want_secret, &infoflags);
       print_status_key_considered (keyblock, infoflags);
       if (found_key)
        {
index 62d6131..61e39b8 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -197,6 +197,7 @@ enum cmd_and_opt_values
     oWithSubkeyFingerprint,
     oWithICAOSpelling,
     oWithKeygrip,
+    oWithKeyScreening,
     oWithSecret,
     oWithWKDHash,
     oWithColons,
@@ -785,6 +786,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
   ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
+  ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
   ARGPARSE_s_n (oWithKeyOrigin,   "with-key-origin", "@"),
@@ -2737,6 +2739,10 @@ main (int argc, char **argv)
             opt.with_keygrip = 1;
             break;
 
+         case oWithKeyScreening:
+            opt.with_key_screening = 1;
+            break;
+
          case oWithSecret:
             opt.with_secret = 1;
             break;
index 9b8b77c..03fe384 100644 (file)
--- a/g10/gpg.h
+++ b/g10/gpg.h
 #define MAX_EXTERN_MPI_BITS 16384
 
 /* The maximum length of a binary fingerprints.  This is used to
-   provide a static buffer and will be increased if we need to support
-   longer fingerprints.
-   Warning: At some places we still use 20 instead of this macro. */
-#define MAX_FINGERPRINT_LEN 20
+ * provide a static buffer and will be increased if we need to support
+ * longer fingerprints.  Warning: At some places we have some
+ * assumption on a 20 byte fingerprint.
+ * Watch out for FIXME(fingerprint) */
+#define MAX_FINGERPRINT_LEN 32
 
 /* The maximum length of a formatted fingerprint as returned by
  format_hexfingerprint().  */
-#define MAX_FORMATTED_FINGERPRINT_LEN 50
* format_hexfingerprint().  */
+#define MAX_FORMATTED_FINGERPRINT_LEN 59
 
 
 /*
index 2b42bfb..8c156d2 100644 (file)
@@ -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)
index 4acb2de..8d86253 100644 (file)
@@ -1142,7 +1142,7 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
           if (err)
             log_log ((gpg_err_code (err) == GPG_ERR_CANCELED
                       || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
-                     ? GPGRT_LOG_INFO : GPGRT_LOG_ERROR,
+                     ? GPGRT_LOGLVL_INFO : GPGRT_LOGLVL_ERROR,
                      _("key %s: error changing passphrase: %s\n"),
                        keystr_with_sub (keyid, subid),
                        gpg_strerror (err));
index b42afa8..912fa39 100644 (file)
 #include "../common/mbox-util.h"
 
 
-/* The default algorithms.  If you change them remember to change them
-   also in gpg.c:gpgconf_list.  You should also check that the value
+/* The default algorithms.  If you change them, you should ensure the value
    is inside the bounds enforced by ask_keysize and gen_xxx.  See also
    get_keysize_range which encodes the allowed ranges.  */
-#define DEFAULT_STD_KEY_PARAM  "rsa2048/cert,sign+rsa2048/encr"
+#define DEFAULT_STD_KEY_PARAM  "rsa3072/cert,sign+rsa3072/encr"
 #define FUTURE_STD_KEY_PARAM   "ed25519/cert,sign+cv25519/encr"
 
 /* When generating keys using the streamlined key generation dialog,
@@ -91,7 +90,7 @@ enum para_name {
   pHANDLE,
   pKEYSERVER,
   pKEYGRIP,
-  pSUBKEYGRIP,
+  pSUBKEYGRIP
 };
 
 struct para_data_s {
@@ -1641,7 +1640,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
 
   if (nbits < 1024)
     {
-      nbits = 2048;
+      nbits = 3072;
       log_info (_("keysize invalid; using %u bits\n"), nbits );
     }
   else if (nbits > maxsize)
@@ -2110,7 +2109,7 @@ get_keysize_range (int algo, unsigned int *min, unsigned int *max)
     default:
       *min = opt.compliance == CO_DE_VS ? 2048: 1024;
       *max = 4096;
-      def = 2048;
+      def = 3072;
       break;
     }
 
index ba35ec2..a9034ee 100644 (file)
@@ -73,7 +73,7 @@ pubkey_letter( int algo )
    is copied to the supplied buffer up a length of BUFSIZE-1.
    Examples for the output are:
 
-   "rsa2048"  - RSA with 2048 bit
+   "rsa3072"  - RSA with 3072 bit
    "elg1024"  - Elgamal with 1024 bit
    "ed25519"  - ECC using the curve Ed25519.
    "E_1.2.3.4"  - ECC using the unsupported curve with OID "1.2.3.4".
@@ -83,7 +83,7 @@ pubkey_letter( int algo )
    If the option --legacy-list-mode is active, the output use the
    legacy format:
 
-   "2048R" - RSA with 2048 bit
+   "3072R" - RSA with 3072 bit
    "1024g" - Elgamal with 1024 bit
    "256E"  - ECDSA using a curve with 256 bit
 
@@ -839,8 +839,22 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
               /* Half way through we add a second space.  */
               + 1);
     }
+  else if (hexlen == 64 || hexlen == 50)  /* v5 fingerprint */
+    {
+      /* The v5 fingerprint is commonly printed truncated to 25
+       * octets.  We accept the truncated as well as the full hex
+       * version here and format it like this:
+       * B2CCB6 838332 5D61BA C50F9F 5E CD21A8 0AC8C5 2565C8 C52565
+       */
+      hexlen = 50;
+      space = 8 * 6 + 2 + 8 + 1;
+    }
   else  /* Other fingerprint versions - print as is.  */
     {
+      /* We truncated here so that we do not need to provide a buffer
+       * of a length which is in reality never used.  */
+      if (hexlen > MAX_FORMATTED_FINGERPRINT_LEN - 1)
+        hexlen = MAX_FORMATTED_FINGERPRINT_LEN - 1;
       space = hexlen + 1;
     }
 
@@ -853,7 +867,7 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
     {
       for (i = 0, j = 0; i < 40; i ++)
         {
-          if (i && i % 4 == 0)
+          if (i && !(i % 4))
             buffer[j ++] = ' ';
           if (i == 40 / 2)
             buffer[j ++] = ' ';
@@ -863,9 +877,29 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
       buffer[j ++] = 0;
       log_assert (j == space);
     }
+  else if (hexlen == 50)  /* v5 fingerprint */
+    {
+      for (i=j=0; i < 24; i++)
+        {
+          if (i && !(i % 6))
+            buffer[j++] = ' ';
+          buffer[j++] = fingerprint[i];
+        }
+      buffer[j++] = ' ';
+      buffer[j++] = fingerprint[i++];
+      buffer[j++] = fingerprint[i++];
+      for (; i < 50; i++)
+        {
+          if (!((i-26) % 6))
+            buffer[j++] = ' ';
+          buffer[j++] = fingerprint[i];
+        }
+      buffer[j++] = 0;
+      log_assert (j == space);
+    }
   else
     {
-      strcpy (buffer, fingerprint);
+      mem2str (buffer, fingerprint, space);
     }
 
   return buffer;
@@ -948,7 +982,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
   else
     {
       if (DBG_PACKET)
-        log_printhex ("keygrip=", array, 20);
+        log_printhex (array, 20, "keygrip=");
       /* FIXME: Save the keygrip in PK.  */
     }
   gcry_sexp_release (s_pkey);
@@ -963,18 +997,18 @@ gpg_error_t
 hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
 {
   gpg_error_t err;
-  unsigned char grip[20];
+  unsigned char grip[KEYGRIP_LEN];
 
   *r_grip = NULL;
   err = keygrip_from_pk (pk, grip);
   if (!err)
     {
-      char * buf = xtrymalloc (20*2+1);
+      char * buf = xtrymalloc (KEYGRIP_LEN * 2 + 1);
       if (!buf)
         err = gpg_error_from_syserror ();
       else
         {
-          bin2hex (grip, 20, buf);
+          bin2hex (grip, KEYGRIP_LEN, buf);
           *r_grip = buf;
         }
     }
index 86d1c56..bcbad45 100644 (file)
@@ -45,6 +45,7 @@
 #include "../common/zb32.h"
 #include "tofu.h"
 #include "../common/compliance.h"
+#include "../common/pkscreening.h"
 
 
 static void list_all (ctrl_t, int, int);
@@ -696,6 +697,37 @@ print_key_data (PKT_public_key * pk)
     }
 }
 
+
+/* Various public key screenings.  (Right now just ROCA).  With
+ * COLON_MODE set the output is formatted for use in the compliance
+ * field of a colon listing.
+ */
+static void
+print_pk_screening (PKT_public_key *pk, int colon_mode)
+{
+  gpg_error_t err;
+
+  if (is_RSA (pk->pubkey_algo) && pubkey_get_npkey (pk->pubkey_algo))
+    {
+      err = screen_key_for_roca (pk->pkey[0]);
+      if (!err)
+        ;
+      else if (gpg_err_code (err) == GPG_ERR_TRUE)
+        {
+          if (colon_mode)
+            es_fprintf (es_stdout, colon_mode > 1? " %d":"%d", 6001);
+          else
+            es_fprintf (es_stdout,
+                        "      Screening: ROCA vulnerability detected\n");
+        }
+      else if (!colon_mode)
+        es_fprintf (es_stdout, "      Screening: [ROCA check failed: %s]\n",
+                    gpg_strerror (err));
+    }
+
+}
+
+
 static void
 print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
 {
@@ -922,6 +954,9 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
   if (opt.with_key_data)
     print_key_data (pk);
 
+  if (opt.with_key_screening)
+    print_pk_screening (pk, 0);
+
   if (opt.with_key_origin
       && (pk->keyorg || pk->keyupdate || pk->updateurl))
     {
@@ -1063,6 +1098,8 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
          if (opt.with_key_data)
            print_key_data (pk2);
+          if (opt.with_key_screening)
+            print_pk_screening (pk2, 0);
        }
       else if (opt.list_sigs
               && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
@@ -1227,6 +1264,9 @@ print_compliance_flags (PKT_public_key *pk,
                  gnupg_status_compliance_flag (CO_DE_VS));
       any++;
     }
+
+  if (opt.with_key_screening)
+    print_pk_screening (pk, 1+any);
 }
 
 
@@ -1906,6 +1946,9 @@ print_card_serialno (const char *serialno)
  * pub   dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
  *       80615870F5BAD690333686D0F2AD85AC1E42B367
  *
+ * pub   rsa2048 2017-12-31 [SC] [expires: 2028-12-31]
+ *       80615870F5BAD690333686D0F2AD85AC1E42B3671122334455
+ *
  * Some global options may result in a different output format.  If
  * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
  * depending on the value a flag character is shown:
index 6c15a2a..4a8f8c3 100644 (file)
@@ -31,7 +31,9 @@
    (i.e. uncompressed) rather than 1 (zip).  However, the real world
    issues of speed and size come into play here. */
 
-#if GPG_USE_AES128
+#if GPG_USE_AES256
+# define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_AES256
+#elif GPG_USE_AES128
 # define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_AES
 #elif GPG_USE_CAST5
 # define DEFAULT_CIPHER_ALGO     CIPHER_ALGO_CAST5
index 77c8f26..9016d27 100644 (file)
@@ -396,7 +396,7 @@ print_further_info (const char *format, ...)
 
   log_info (_("(further info: "));
   va_start (arg_ptr, format);
-  log_logv (GPGRT_LOG_CONT, format, arg_ptr);
+  log_logv (GPGRT_LOGLVL_CONT, format, arg_ptr);
   va_end (arg_ptr);
   log_printf (")\n");
 }
index 130bec8..61f7403 100644 (file)
@@ -82,6 +82,7 @@ struct
   int with_fingerprint; /* Option --with-fingerprint active.  */
   int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active.  */
   int with_keygrip;     /* Option --with-keygrip active.  */
+  int with_key_screening;/* Option --with-key-screening active.  */
   int with_tofu_info;   /* Option --with-tofu_info active.  */
   int with_secret;      /* Option --with-secret active.  */
   int with_wkd_hash;    /* Option --with-wkd-hash.  */
index d7ba953..0185097 100644 (file)
@@ -255,7 +255,7 @@ get_it (ctrl_t ctrl,
    * CSUM
    */
   if (DBG_CRYPTO)
-    log_printhex ("DEK frame:", frame, nframe);
+    log_printhex (frame, nframe, "DEK frame:");
   n = 0;
 
   if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
@@ -361,7 +361,7 @@ get_it (ctrl_t ctrl,
   if (DBG_CLOCK)
     log_clock ("decryption ready");
   if (DBG_CRYPTO)
-    log_printhex ("DEK is:", dek->key, dek->keylen);
+    log_printhex (dek->key, dek->keylen, "DEK is:");
 
   /* Check that the algo is in the preferences and whether it has
    * expired.  Also print a status line with the key's fingerprint.  */
index 23af12b..f8e366b 100644 (file)
@@ -233,7 +233,7 @@ check_signature2 (ctrl_t ctrl,
        unsigned char *p, *buffer;
         size_t n, nbytes;
         int i;
-        char hashbuf[20];
+        char hashbuf[20];  /* We use SHA-1 here.  */
 
         nbytes = 6;
        for (i=0; i < nsig; i++ )
@@ -510,7 +510,11 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
         return GPG_ERR_GENERAL;
 
     /* Verify the signature.  */
+    if (DBG_CLOCK && sig->sig_class <= 0x01)
+      log_clock ("enter pk_verify");
     rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey );
+    if (DBG_CLOCK && sig->sig_class <= 0x01)
+      log_clock ("leave pk_verify");
     gcry_mpi_release (result);
 
     if( !rc && sig->flags.unknown_critical )
index 5ea903f..37bf78b 100644 (file)
@@ -129,7 +129,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
     char *p;
     size_t n, fprlen;
     unsigned int otrust;
-    byte fpr[20];
+    byte fpr[MAX_FINGERPRINT_LEN];
     int any = 0;
     int rc;
 
@@ -171,7 +171,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
            continue;
        }
        fprlen = p - line;
-       if( fprlen != 32 && fprlen != 40 ) {
+       if( fprlen != 32 && fprlen != 40 && fprlen != 64) {
            log_error (_("error in '%s': %s\n"),
                        fname, _("invalid fingerprint") );
            continue;
@@ -183,10 +183,12 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
        }
        if( !otrust )
            continue; /* no otrust defined - no need to update or insert */
-       /* convert the ascii fingerprint to binary */
-       for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 )
-           fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
-       while (fprlen < 20)
+       /* Convert the ascii fingerprint to binary */
+       for(p=line, fprlen=0;
+            fprlen < MAX_FINGERPRINT_LEN && *p != ':';
+            p += 2 )
+          fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
+       while (fprlen < MAX_FINGERPRINT_LEN)
            fpr[fprlen++] = 0;
 
        rc = tdbio_search_trust_byfpr (fpr, &rec);
index 091d5b0..762b19b 100644 (file)
@@ -2083,13 +2083,16 @@ build_conflict_set (ctrl_t ctrl, tofu_dbs_t dbs,
    * policy to ask due to a conflict.  */
   for (iter = conflict_set; iter; iter = iter->next)
     {
+      /* Fixme: Why the check against N+1?  */
       int l = strlen (iter->d);
-      if (!(l == 2 * MAX_FINGERPRINT_LEN
-            || l == 2 * MAX_FINGERPRINT_LEN + 1))
+      if (!(l == 2 * 20
+            || l == 2 * 20 + 1
+            || l == 2 * 32
+            || l == 2 * 32 + 1))
         {
           log_error (_("TOFU db corruption detected.\n"));
-          print_further_info ("fingerprint '%s' is not %d characters long",
-                              iter->d, 2 * MAX_FINGERPRINT_LEN);
+          print_further_info ("fingerprint '%s' is %d characters long",
+                              iter->d, l);
         }
 
       if (l >= 1 && iter->d[l - 1] == '!')
@@ -2469,10 +2472,11 @@ get_policy (ctrl_t ctrl, tofu_dbs_t dbs, PKT_public_key *pk,
   /* See if the key is signed by an ultimately trusted key.  */
   {
     int fingerprint_raw_len = strlen (fingerprint) / 2;
-    char fingerprint_raw[20];
+    char fingerprint_raw[MAX_FINGERPRINT_LEN];
     int len = 0;
 
-    if (fingerprint_raw_len != sizeof fingerprint_raw
+    /* FIXME(fingerprint) */
+    if (fingerprint_raw_len != 20 /*sizeof fingerprint_raw */
         || ((len = hex2bin (fingerprint,
                             fingerprint_raw, fingerprint_raw_len))
             != strlen (fingerprint)))
@@ -3210,7 +3214,7 @@ show_statistics (tofu_dbs_t dbs,
             *p = ' ';
       }
 
-      log_string (GPGRT_LOG_INFO, msg);
+      log_string (GPGRT_LOGLVL_INFO, msg);
       xfree (msg);
 
       if (policy == TOFU_POLICY_AUTO)
@@ -3275,7 +3279,7 @@ show_warning (const char *fingerprint, strlist_t user_id_list)
     log_fatal ("format failed: %s\n",
                gpg_strerror (gpg_error_from_syserror()));
   xfree (tmpmsg);
-  log_string (GPGRT_LOG_INFO, text);
+  log_string (GPGRT_LOGLVL_INFO, text);
   xfree (text);
 
   es_free (set_policy_command);
index 8a50c3f..b160ba3 100644 (file)
@@ -366,7 +366,7 @@ create_inq_cb (void *opaque, const char *line)
           void *ciphertext;
           size_t ciphertextlen;
 
-          log_printhex ("plain", plaintext, plaintextlen);
+          log_printhex (plaintext, plaintextlen, "plain");
           err = g13_encrypt_keyblob (parm->ctrl,
                                      plaintext, plaintextlen,
                                      &ciphertext, &ciphertextlen);
index b10ebbc..6693826 100644 (file)
@@ -318,7 +318,7 @@ dump_tupledesc (tupledesc_t tuples)
               if (n < 100 && all_printable (value, n))
                 log_printf ("%.*s\n", (int)n, (const char*)value);
               else
-                log_printhex ("", value, n);
+                log_printhex (value, n, "");
               break;
 
             case KEYBLOB_TAG_CONT_NSEC:
@@ -327,11 +327,11 @@ dump_tupledesc (tupledesc_t tuples)
               if (!convert_uint (value, n, &uint))
                 log_printf ("%llu\n", uint);
               else
-                log_printhex ("", value, n);
+                log_printhex (value, n, "");
               break;
 
             default:
-              log_printhex ("", value, n);
+              log_printhex (value, n, "");
               break;
             }
         }
index 9b43584..e3814d3 100644 (file)
@@ -137,14 +137,14 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
   /* Map the log levels.  */
   switch (level)
     {
-    case GCRY_LOG_CONT: level = GPGRT_LOG_CONT; break;
-    case GCRY_LOG_INFO: level = GPGRT_LOG_INFO; break;
-    case GCRY_LOG_WARN: level = GPGRT_LOG_WARN; break;
-    case GCRY_LOG_ERROR:level = GPGRT_LOG_ERROR; break;
-    case GCRY_LOG_FATAL:level = GPGRT_LOG_FATAL; break;
-    case GCRY_LOG_BUG:  level = GPGRT_LOG_BUG; break;
-    case GCRY_LOG_DEBUG:level = GPGRT_LOG_DEBUG; break;
-    default:            level = GPGRT_LOG_ERROR; break;
+    case GCRY_LOG_CONT: level = GPGRT_LOGLVL_CONT; break;
+    case GCRY_LOG_INFO: level = GPGRT_LOGLVL_INFO; break;
+    case GCRY_LOG_WARN: level = GPGRT_LOGLVL_WARN; break;
+    case GCRY_LOG_ERROR:level = GPGRT_LOGLVL_ERROR; break;
+    case GCRY_LOG_FATAL:level = GPGRT_LOGLVL_FATAL; break;
+    case GCRY_LOG_BUG:  level = GPGRT_LOGLVL_BUG; break;
+    case GCRY_LOG_DEBUG:level = GPGRT_LOGLVL_DEBUG; break;
+    default:            level = GPGRT_LOGLVL_ERROR; break;
     }
   log_logv (level, fmt, arg_ptr);
 }
index c50afbd..60270ed 100644 (file)
@@ -470,7 +470,7 @@ dump_reader_status (int slot)
   if (reader_table[slot].atrlen)
     {
       log_info ("slot %d: ATR=", slot);
-      log_printhex ("", reader_table[slot].atr, reader_table[slot].atrlen);
+      log_printhex (reader_table[slot].atr, reader_table[slot].atrlen, "");
     }
 }
 
@@ -496,6 +496,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";
     }
 }
@@ -602,7 +603,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:
@@ -724,7 +725,7 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
     return err;
 
   if (DBG_CARD_IO)
-    log_printhex ("  PCSC_data:", apdu, apdulen);
+    log_printhex (apdu, apdulen, "  PCSC_data:");
 
   if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1))
       send_pci.protocol = PCSC_PROTOCOL_T1;
@@ -1420,7 +1421,7 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
     return err;
 
   if (DBG_CARD_IO)
-    log_printhex (" raw apdu:", apdu, apdulen);
+    log_printhex (apdu, apdulen, " raw apdu:");
 
   maxbuflen = *buflen;
   if (pininfo)
@@ -1689,7 +1690,7 @@ my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
 
   *buflen = 0;
   if (DBG_CARD_IO)
-    log_printhex ("  APDU_data:", apdu, apdulen);
+    log_printhex (apdu, apdulen, "  APDU_data:");
 
   if (apdulen < 4)
     {
@@ -2822,7 +2823,7 @@ send_le (int slot, int class, int ins, int p0, int p1,
       log_debug (" response: sw=%04X  datalen=%d\n",
                  sw, (unsigned int)resultlen);
       if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA))
-        log_printhex ("    dump: ", result, resultlen);
+        log_printhex (result, resultlen, "    dump: ");
     }
 
   if (sw == SW_SUCCESS || sw == SW_EOF_REACHED)
@@ -2895,7 +2896,7 @@ send_le (int slot, int class, int ins, int p0, int p1,
               log_debug ("     more: sw=%04X  datalen=%d\n",
                          sw, (unsigned int)resultlen);
               if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA))
-                log_printhex ("     dump: ", result, resultlen);
+                log_printhex (result, resultlen, "     dump: ");
             }
 
           if ((sw & 0xff00) == SW_MORE_DATA
@@ -2941,7 +2942,7 @@ send_le (int slot, int class, int ins, int p0, int p1,
   xfree (result_buffer);
 
   if (DBG_CARD_IO && retbuf && sw == SW_SUCCESS)
-    log_printhex ("      dump: ", *retbuf, *retbuflen);
+    log_printhex (*retbuf, *retbuflen, "      dump: ");
 
   return sw;
 }
@@ -3101,7 +3102,7 @@ apdu_send_direct (int slot, size_t extended_length,
       log_debug (" response: sw=%04X  datalen=%d\n",
                  sw, (unsigned int)resultlen);
       if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA))
-        log_printhex ("     dump: ", result, resultlen);
+        log_printhex (result, resultlen, "     dump: ");
     }
 
   if (handle_more && (sw & 0xff00) == SW_MORE_DATA)
@@ -3157,7 +3158,7 @@ apdu_send_direct (int slot, size_t extended_length,
               log_debug ("     more: sw=%04X  datalen=%d\n",
                          sw, (unsigned int)resultlen);
               if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA))
-                log_printhex ("     dump: ", result, resultlen);
+                log_printhex (result, resultlen, "     dump: ");
             }
 
           if ((sw & 0xff00) == SW_MORE_DATA
@@ -3226,7 +3227,7 @@ apdu_send_direct (int slot, size_t extended_length,
     }
 
   if (DBG_CARD_IO && retbuf)
-    log_printhex ("      dump: ", *retbuf, *retbuflen);
+    log_printhex (*retbuf, *retbuflen, "      dump: ");
 
   return 0;
 }
index 6751e8c..8a0d4bd 100644 (file)
@@ -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;
index 6fcec3e..689d880 100644 (file)
@@ -98,7 +98,7 @@ static struct {
   { 0x0065, 1,    0, 1, 0, 0, 0, 0, "Cardholder Related Data"},
   { 0x005B, 0, 0x65, 0, 0, 0, 0, 0, "Name" },
   { 0x5F2D, 0, 0x65, 0, 0, 0, 0, 0, "Language preferences" },
-  { 0x5F35, 0, 0x65, 0, 0, 0, 0, 0, "Sex" },
+  { 0x5F35, 0, 0x65, 0, 0, 0, 0, 0, "Salutation" },
   { 0x006E, 1,    0, 1, 0, 0, 0, 0, "Application Related Data" },
   { 0x004F, 0, 0x6E, 1, 0, 0, 0, 0, "AID" },
   { 0x0073, 1,    0, 1, 0, 0, 0, 0, "Discretionary Data Objects" },
@@ -558,7 +558,7 @@ dump_all_do (int slot)
           if (data_objects[i].binary)
             {
               log_info ("DO '%s': ", data_objects[i].desc);
-              log_printhex ("", buffer, buflen);
+              log_printhex (buffer, buflen, "");
             }
           else
             log_info ("DO '%s': '%.*s'\n",
@@ -588,7 +588,7 @@ dump_all_do (int slot)
                           if (valuelen > 200)
                             log_info ("[%u]\n", (unsigned int)valuelen);
                           else
-                            log_printhex ("", value, valuelen);
+                            log_printhex (value, valuelen, "");
                         }
                       else
                         log_info ("DO '%s': '%.*s'\n",
@@ -4973,7 +4973,7 @@ parse_algorithm_attribute (app_t app, int keyno)
       curve = ecc_curve (buffer + 1, oidlen);
 
       if (!curve)
-        log_printhex ("Curve with OID not supported: ", buffer+1, buflen-1);
+        log_printhex (buffer+1, buflen-1, "Curve with OID not supported: ");
       else
         {
           app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECC;
@@ -4991,7 +4991,7 @@ parse_algorithm_attribute (app_t app, int keyno)
         }
     }
   else if (opt.verbose)
-    log_printhex ("", buffer, buflen);
+    log_printhex (buffer, buflen, "");
 
   xfree (relptr);
 }
@@ -5033,7 +5033,7 @@ app_select_openpgp (app_t app)
       if (opt.verbose)
         {
           log_info ("AID: ");
-          log_printhex ("", buffer, buflen);
+          log_printhex (buffer, buflen, "");
         }
 
       app->card_version = buffer[6] << 8;
@@ -5066,7 +5066,7 @@ app_select_openpgp (app_t app)
           if (opt.verbose)
             {
               log_info ("Historical Bytes: ");
-              log_printhex ("", buffer, buflen);
+              log_printhex (buffer, buflen, "");
             }
           parse_historical (app->app_local, buffer, buflen);
           xfree (relptr);
index 0bb5f9e..1902924 100644 (file)
@@ -2274,7 +2274,7 @@ read_ef_tokeninfo (app_t app)
     }
   memcpy (app->app_local->serialno, p, objlen);
   app->app_local->serialnolen = objlen;
-  log_printhex ("Serialnumber from EF(TokenInfo) is:", p, objlen);
+  log_printhex (p, objlen, "Serialnumber from EF(TokenInfo) is:");
 
  leave:
   xfree (buffer);
@@ -2781,7 +2781,7 @@ micardo_mse (app_t app, unsigned short fid)
                      gpg_strerror (err));
           return err;
         }
-      log_printhex ("keyD record:", buffer, buflen);
+      log_printhex (buffer, buflen, "keyD record:");
       p = find_tlv (buffer, buflen, 0x83, &n);
       if (p && n == 4 && ((p[2]<<8)|p[3]) == fid)
         {
index 081b080..29208c2 100644 (file)
@@ -93,8 +93,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))
index a361aca..4e18caf 100644 (file)
@@ -119,7 +119,8 @@ do_list (int is_error, int listmode, estream_t fp, const char *format, ...)
     }
   else
     {
-      log_logv (is_error? GPGRT_LOG_ERROR: GPGRT_LOG_INFO, format, arg_ptr);
+      log_logv (is_error? GPGRT_LOGLVL_ERROR: GPGRT_LOGLVL_INFO,
+                format, arg_ptr);
       log_printf ("\n");
     }
   va_end (arg_ptr);
index 1102bcc..51f1a94 100644 (file)
@@ -374,7 +374,7 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
       return gpg_error (GPG_ERR_BUG);
     }
   if (DBG_CRYPTO)
-    log_printhex ("public key: ", p, n);
+    log_printhex (p, n, "public key: ");
 
   rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n);
   ksba_free (p);
index edee76f..9567c67 100644 (file)
@@ -167,7 +167,7 @@ gpgsm_dump_string (const char *string)
       else
         {
           log_printf ( "[ ");
-          log_printhex (NULL, string, strlen (string));
+          log_printhex (string, strlen (string), NULL);
           log_printf ( " ]");
         }
     }
index 9772a3b..4f8a1ac 100644 (file)
@@ -138,7 +138,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream)
   unsigned int nbits;
   int minbits = 1024;
   int maxbits = 4096;
-  int defbits = 2048;
+  int defbits = 3072;
   const char *keyusage;
   char *subject_name;
   membuf_t mb_email, mb_dns, mb_uri, mb_result;
index 4431870..1d610c1 100644 (file)
@@ -26,7 +26,7 @@
      $ cat >foo <<EOF
      %echo Generating a standard key
      Key-Type: RSA
-     Key-Length: 2048
+     Key-Length: 3072
      Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Ddorf,C=DE
      Name-Email: joe@foo.bar
      # Do a commit here, so that we can later print a "done"
@@ -468,7 +468,7 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para,
   /* Check the keylength.  NOTE: If you change this make sure that it
      macthes the gpgconflist item in gpgsm.c  */
   if (!get_parameter (para, pKEYLENGTH, 0))
-    nbits = 2048;
+    nbits = 3072;
   else
     nbits = get_parameter_uint (para, pKEYLENGTH);
   if ((nbits < 1024 || nbits > 4096) && !cardkeyid)
index 60ed14a..b0ab63f 100644 (file)
@@ -72,7 +72,7 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
     }
 
   if (DBG_CRYPTO)
-    log_printhex ("pkcs1 encoded session key:", seskey, seskeylen);
+    log_printhex (seskey, seskeylen, "pkcs1 encoded session key:");
 
   n=0;
   if (seskeylen == 24 || seskeylen == 16)
@@ -115,7 +115,7 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
     }
 
   if (DBG_CRYPTO)
-    log_printhex ("session key:", seskey+n, seskeylen-n);
+    log_printhex (seskey+n, seskeylen-n, "session key:");
 
   rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
   if (rc)
index fbcec58..4bf378a 100644 (file)
@@ -196,7 +196,7 @@ gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array)
       return NULL;
     }
   if (DBG_X509)
-    log_printhex ("keygrip=", array, 20);
+    log_printhex (array, 20, "keygrip=");
 
   return array;
 }
@@ -277,6 +277,70 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
 }
 
 
+/* If KEY is an RSA key, return its modulus.  For non-RSA keys or on
+ * error return NULL.  */
+gcry_mpi_t
+gpgsm_get_rsa_modulus (ksba_cert_t cert)
+{
+  gpg_error_t err;
+  gcry_sexp_t key;
+  gcry_sexp_t list = NULL;
+  gcry_sexp_t l2 = NULL;
+  char *name = NULL;
+  gcry_mpi_t modulus = NULL;
+
+  {
+    ksba_sexp_t ckey;
+    size_t n;
+
+    ckey = ksba_cert_get_public_key (cert);
+    if (!ckey)
+      return NULL;
+    n = gcry_sexp_canon_len (ckey, 0, NULL, NULL);
+    if (!n)
+      {
+        xfree (ckey);
+        return NULL;
+      }
+    err = gcry_sexp_sscan (&key, NULL, (char *)ckey, n);
+    xfree (ckey);
+    if (err)
+      return NULL;
+  }
+
+  list = gcry_sexp_find_token (key, "public-key", 0);
+  if (!list)
+    list = gcry_sexp_find_token (key, "private-key", 0);
+  if (!list)
+    list = gcry_sexp_find_token (key, "protected-private-key", 0);
+  if (!list)
+    list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
+
+  gcry_sexp_release (key);
+  if (!list)
+    return NULL;  /* No suitable key.  */
+
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  l2 = NULL;
+
+  name = gcry_sexp_nth_string (list, 0);
+  if (!name)
+    ;
+  else if (gcry_pk_map_name (name) == GCRY_PK_RSA)
+    {
+      l2 = gcry_sexp_find_token (list, "n", 1);
+      if (l2)
+        modulus = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+    }
+
+  gcry_free (name);
+  gcry_sexp_release (l2);
+  gcry_sexp_release (list);
+  return modulus;
+}
+
 
 \f
 /* For certain purposes we need a certificate id which has an upper
index b505be1..650b130 100644 (file)
@@ -155,6 +155,7 @@ enum cmd_and_opt_values {
   oWithMD5Fingerprint,
   oWithKeygrip,
   oWithSecret,
+  oWithKeyScreening,
   oAnswerYes,
   oAnswerNo,
   oKeyring,
@@ -391,6 +392,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
+  ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
@@ -1289,6 +1291,10 @@ main ( int argc, char **argv)
           opt.with_keygrip = 1;
           break;
 
+        case oWithKeyScreening:
+          opt.with_key_screening = 1;
+          break;
+
         case oOptions:
           /* config files may not be nested (silently ignore them) */
           if (!configfp)
@@ -1786,8 +1792,7 @@ main ( int argc, char **argv)
         /* The next one is an info only item and should match what
            proc_parameters actually implements.  */
         es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
-                   "RSA-2048");
-        es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
+                   "RSA-3072");
 
       }
       break;
index cd4fc99..3e2f95f 100644 (file)
@@ -85,6 +85,8 @@ struct
 
   int with_keygrip; /* Option --with-keygrip active.  */
 
+  int with_key_screening; /* Option  --with-key-screening active.  */
+
   int pinentry_mode;
 
   int armor;        /* force base64 armoring (see also ctrl.with_base64) */
@@ -258,6 +260,7 @@ unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert,
 unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array);
 char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert);
 int  gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits);
+gcry_mpi_t gpgsm_get_rsa_modulus (ksba_cert_t cert);
 char *gpgsm_get_certid (ksba_cert_t cert);
 
 
index 8796cd2..ca69382 100644 (file)
@@ -836,7 +836,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
       log_error ("can't calculate keygrip\n");
       goto leave;
     }
-  log_printhex ("keygrip=", grip, 20);
+  log_printhex (grip, 20, "keygrip=");
 
   /* Convert to canonical encoding using a function which pads it to a
      multiple of 64 bits.  We need this padding for AESWRAP.  */
index 9997da8..ea2a220 100644 (file)
@@ -37,6 +37,7 @@
 #include "../common/i18n.h"
 #include "../common/tlv.h"
 #include "../common/compliance.h"
+#include "../common/pkscreening.h"
 
 struct list_external_parm_s
 {
@@ -238,6 +239,38 @@ print_key_data (ksba_cert_t cert, estream_t fp)
 #endif
 }
 
+
+/* Various public key screenings.  (Right now just ROCA).  With
+ * COLON_MODE set the output is formatted for use in the compliance
+ * field of a colon listing.  */
+static void
+print_pk_screening (ksba_cert_t cert, int colon_mode, estream_t fp)
+{
+  gpg_error_t err;
+  gcry_mpi_t modulus;
+
+  modulus = gpgsm_get_rsa_modulus (cert);
+  if (modulus)
+    {
+      err = screen_key_for_roca (modulus);
+      if (!err)
+        ;
+      else if (gpg_err_code (err) == GPG_ERR_TRUE)
+        {
+          if (colon_mode)
+            es_fprintf (fp, colon_mode > 1? " %d":"%d", 6001);
+          else
+            es_fprintf (fp, "    screening: ROCA vulnerability detected\n");
+        }
+      else if (!colon_mode)
+        es_fprintf (fp, "    screening: [ROCA check failed: %s]\n",
+                    gpg_strerror (err));
+      gcry_mpi_release (modulus);
+    }
+
+}
+
+
 static void
 print_capabilities (ksba_cert_t cert, estream_t fp)
 {
@@ -348,10 +381,19 @@ email_kludge (const char *name)
 /* Print the compliance flags to field 18.  ALGO is the gcrypt algo
  * number.  NBITS is the length of the key in bits.  */
 static void
-print_compliance_flags (int algo, unsigned int nbits, estream_t fp)
+print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits,
+                        estream_t fp)
 {
+  int any = 0;
+
   if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
-    es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
+    {
+      es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
+      any++;
+    }
+
+  if (opt.with_key_screening)
+    print_pk_screening (cert, 1+any, fp);
 }
 
 
@@ -526,7 +568,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
   es_putc (':', fp);  /* End of field 15. */
   es_putc (':', fp);  /* End of field 16. */
   es_putc (':', fp);  /* End of field 17. */
-  print_compliance_flags (algo, nbits, fp);
+  print_compliance_flags (cert, algo, nbits, fp);
   es_putc (':', fp);  /* End of field 18. */
   es_putc ('\n', fp);
 
@@ -1253,6 +1295,9 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
         }
     }
 
+  if (opt.with_key_screening)
+    print_pk_screening (cert, 0, fp);
+
   if (have_secret)
     {
       char *cardsn;
index 564e779..6a7b473 100644 (file)
@@ -58,7 +58,7 @@ read_list (char *key, char *country, int *lnr)
 
   if (!listname)
     {
-      listname = make_filename (gnupg_datadir (), "qualified.txt", NULL);
+      listname = make_filename (gnupg_sysconfdir (), "qualified.txt", NULL);
       listfp = fopen (listname, "r");
       if (!listfp && errno != ENOENT)
         {
index 10b3f43..b7b9fa8 100644 (file)
@@ -512,10 +512,10 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
               if (DBG_X509)
                 {
                   if (msgdigest)
-                    log_printhex ("message:  ", msgdigest, msgdigestlen);
+                    log_printhex (msgdigest, msgdigestlen, "message:  ");
                   if (s)
-                    log_printhex ("computed: ",
-                                  s, gcry_md_get_algo_dlen (algo));
+                    log_printhex (s, gcry_md_get_algo_dlen (algo),
+                                  "computed: ");
                 }
               fpr = gpgsm_fpr_and_name_for_status (cert);
               gpgsm_status (ctrl, STATUS_BADSIG, fpr);
index f6014c9..e5be42b 100644 (file)
@@ -102,9 +102,6 @@ XTESTS = \
        issue2929.scm \
        issue2941.scm
 
-# Temporary removed tests:
-#      trust-pgp-4.scm
-
 
 # XXX: Currently, one cannot override automake's 'check' target.  As a
 # workaround, we avoid defining 'TESTS', thus automake will not emit
@@ -268,7 +265,7 @@ sample_msgs = samplemsgs/clearsig-1-key-1.asc \
 
 EXTRA_DIST = defs.scm trust-pgp/common.scm $(XTESTS) $(TEST_FILES) \
             mkdemodirs signdemokey $(priv_keys) $(sample_keys)   \
-            $(sample_msgs) ChangeLog-2011 run-tests.scm trust-pgp-4.scm \
+            $(sample_msgs) ChangeLog-2011 run-tests.scm \
             setup.scm shell.scm all-tests.scm signed-messages.scm
 
 CLEANFILES = prepared.stamp x y yy z out err  $(data_files) \
@@ -279,6 +276,12 @@ CLEANFILES = prepared.stamp x y yy z out err  $(data_files) \
             gnupg-test.stop random_seed gpg-agent.log tofu.db \
             passphrases sshcontrol S.gpg-agent.ssh report.xml
 
+if DISABLE_REGEX
+EXTRA_DIST += trust-pgp-4.scm
+else
+XTESTS += trust-pgp-4.scm
+endif
+
 clean-local:
        -rm -rf private-keys-v1.d openpgp-revocs.d tofu.d gpgtar.d
 
index d687fe4..e12b175 100644 (file)
@@ -48,7 +48,7 @@
  (define setup-extended-key-format (setup* "extended-key-format"))
 
  (define all-tests
-   (parse-makefile-expand (in-srcdir "tests" "openpgp" "Makefile.am")
+   (parse-makefile-expand "Makefile"
                          (lambda (filename port key) (parse-makefile port key))
                          "XTESTS"))
 
index a6347fe..9f780fe 100644 (file)
               "allow-preset-passphrase"
               "no-grab"
               "enable-ssh-support"
+               "s2k-count 65536"
               (if (flag "--extended-key-format" *args*)
                   "enable-extended-key-format" "#enable-extended-key-format")
               (string-append "pinentry-program " (tool 'pinentry))
index b74ee04..c799143 100644 (file)
@@ -87,7 +87,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
   va_list arg_ptr;
 
   va_start (arg_ptr, fmt);
-  log_logv (GPGRT_LOG_ERROR, fmt, arg_ptr);
+  log_logv (GPGRT_LOGLVL_ERROR, fmt, arg_ptr);
   va_end (arg_ptr);
 
   if (errnum)