diff options
82 files changed, 1074 insertions, 384 deletions
@@ -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 <[email protected]> Translations [be] + +Andrey Jivsov <[email protected]> Assigns past and future changes for ECC. + (g10/ecdh.c. other changes to support ECC) + +Ben Kibbey <[email protected]> Assigns past and future changes. + +Birger Langkjer <[email protected]> Translations [da] + +Maxim Britov <[email protected]> Translations [ru] + +Daniel Resare <[email protected]> Translations [sv] +Per Tunedal <[email protected]> Translations [sv] +Daniel Nylander <[email protected]> Translations [sv] + +Daiki Ueno <[email protected]> Assigns Past and Future Changes. + (changed:passphrase.c and related code) + +David Shaw <[email protected]> Assigns past and future changes. + (all in keyserver/, + a lot of changes in g10/ see the ChangeLog, + bug fixes here and there) + +Dokianakis Theofanis <[email protected]> Translations [el] + +Edmund GRIMLEY EVANS <[email protected]> Translations [eo] + +Florian Weimer <[email protected]> Assigns past and future changes + (changed:g10/parse-packet.c, include/iobuf.h, util/iobuf.c) + +g10 Code GmbH <[email protected]> Assigns past and future changes + (all work since 2001 as indicated by mail addresses in ChangeLogs) + +Gaël Quéri <[email protected]> Translations [fr] + (fixed a lot of typos) + +Gregory Steuck <[email protected]> Translations [ru] + +Nagy Ferenc László <[email protected]> Translations [hu] + +Ivo Timmermans <[email protected]> Translations [nl] + +Jacobo Tarri'o Barreiro <[email protected]> Translations [gl] + +Janusz Aleksander Urbanowicz <[email protected]> Translations [pl] +Jakub Bogusz <[email protected]> Translations [pl] + +Jedi Lin <[email protected]> Translations [zh-tw] + +Jouni Hiltunen <[email protected]> Translations [fi] +Tommi Vainikainen <[email protected]> Translations [fi] + +Laurentiu Buzdugan <[email protected]> Translations [ro] + +Magda Procha'zkova' <[email protected]> Translations [cs] + +Michael Roth <[email protected]> Assigns changes. + (wrote cipher/des.c., changes and bug fixes all over the place) + +Michal Majer <[email protected]> Translations [sk] + +Marco d'Itri <[email protected]> Translations [it] + +Marcus Brinkmann <[email protected]> + (gpgconf and fixes all over the place) + +Matthew Skala <[email protected]> Disclaimer + (wrote cipher/twofish.c) + +Moritz Schulte <[email protected]> + (ssh support gpg-agent) + +Niklas Hernaeus <[email protected]> Disclaimer + (weak key patches) + +Nilgun Belma Buguner <[email protected]> Translations [tr] + +Nils Ellmenreich <nils 'at' infosun.fmi.uni-passau.de> + Assigns past and future changes + (configure.in, cipher/rndlinux.c, FAQ) + +Paul Eggert <[email protected]> + (configuration macros for LFS) + +Pavel I. Shajdo <[email protected]> Translations [ru] + (man pages) + +Pedro Morais <[email protected]> Translations [pt_PT] + +Rémi Guyomarch <[email protected]> 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 <[email protected]> Assigns past and future changes. + (All patches to support RISC OS) + +Timo Schulz <[email protected]> Assigns past and future changes. + (util/w32reg.c, g10/passphrase.c, g10/hkp.c) + +Tedi Heriyanto <[email protected]> Translations [id] + +Thiago Jung Bauermann <[email protected]> Translations [pt_BR] +Rafael Caetano dos Santos <[email protected]> Translations [pt_BR] + +Toomas Soome <[email protected]> Translations [et] + +Urko Lusa <[email protected]> Translations [es_ES] + +Walter Koch <[email protected]> Translations [de] + +Werner Koch <[email protected]> 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 <[email protected]> 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 <[email protected]> +2014-09-19:4525694.FcpLvWDUFT@esus: + +Andreas Schwier <[email protected]> +2014-07-22:[email protected]: + +Christian Aistleitner <[email protected]> +2013-05-26:[email protected]: + +Damien Goutte-Gattat <[email protected]> +2015-01-17:[email protected]: + +Daniel Kahn Gillmor <[email protected]> +2014-09-24:[email protected]: + +Hans of Guardian <[email protected]> +2013-06-26:[email protected]: + +Ineiev <[email protected]> +2017-05-09:[email protected]: + +Jonas Borgström <[email protected]> +2013-08-29:[email protected]: + +Joshua Rogers <[email protected]> +2014-12-22:[email protected]: + +Kyle Butt <[email protected]> +2013-05-29:CAAODAYLbCtqOG6msLLL0UTdASKWT6u2ptxsgUQ1JpusBESBoNQ@mail.gmail.com: + +Stefan Tomanek <[email protected]> +2014-01-30:[email protected]: + +Tobias Mueller <[email protected]> +2016-11-23:[email protected]: + +Werner Koch <[email protected]> +2013-03-29:[email protected]: + +William L. Thomson Jr. <[email protected]> +2017-05-23:[email protected]: + +Yann E. MORIN <[email protected]> +2016-07-10:[email protected]: + +Arnaud Fontaine <arnaud.fontaine at ssi.gouv.fr> +2016-10-17:[email protected]: + +Phil Pennock <[email protected]> +Phil Pennock <[email protected]> +2017-01-19:[email protected]: + +Rainer Perske <[email protected]> +2017-10-24:permail-2017102014511105be2aed00002fc6-perske@message-id.uni-muenster.de: Other authors @@ -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) @@ -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 diff --git a/agent/agent.h b/agent/agent.h index c2d857959..687635dc7 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -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; diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index a0886814f..af4eb06f2 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -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); diff --git a/agent/call-scd.c b/agent/call-scd.c index cf61a3546..6ce0cddfb 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -89,7 +89,6 @@ struct inq_needpin_parm_s const char *getpin_cb_desc; assuan_context_t passthru; /* If not NULL, pass unknown inquiries up to the caller. */ - int any_inq_seen; /* The next fields are used by inq_writekey_parm. */ const unsigned char *keydata; @@ -727,7 +726,6 @@ inq_needpin (void *opaque, const char *line) size_t pinlen; int rc; - parm->any_inq_seen = 1; if ((s = has_leading_keyword (line, "NEEDPIN"))) { line = s; @@ -811,30 +809,6 @@ hash_algo_option (int algo) } -static gpg_error_t -cancel_inquire (ctrl_t ctrl, gpg_error_t rc) -{ - gpg_error_t oldrc = rc; - - /* The inquire callback was called and transact returned a - cancel error. We assume that the inquired process sent a - CANCEL. The passthrough code is not able to pass on the - CANCEL and thus scdaemon would stuck on this. As a - workaround we send a CANCEL now. */ - rc = assuan_write_line (ctrl->scd_local->ctx, "CAN"); - if (!rc) { - char *line; - size_t len; - - rc = assuan_read_line (ctrl->scd_local->ctx, &line, &len); - if (!rc) - rc = oldrc; - } - - return rc; -} - - /* Create a signature using the current card. MDALGO is either 0 or * gives the digest algorithm. DESC_TEXT is an additional parameter * passed to GETPIN_CB. */ @@ -875,7 +849,6 @@ agent_card_pksign (ctrl_t ctrl, inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; - inqparm.any_inq_seen = 0; inqparm.keydata = NULL; inqparm.keydatalen = 0; @@ -888,9 +861,6 @@ agent_card_pksign (ctrl_t ctrl, put_membuf_cb, &data, inq_needpin, &inqparm, NULL, NULL); - if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || - gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) - rc = cancel_inquire (ctrl, rc); if (rc) { @@ -974,7 +944,6 @@ agent_card_pkdecrypt (ctrl_t ctrl, inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; - inqparm.any_inq_seen = 0; inqparm.keydata = NULL; inqparm.keydatalen = 0; snprintf (line, DIM(line), "PKDECRYPT %s", keyid); @@ -982,9 +951,6 @@ agent_card_pkdecrypt (ctrl_t ctrl, put_membuf_cb, &data, inq_needpin, &inqparm, padding_info_cb, r_padding); - if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || - gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) - rc = cancel_inquire (ctrl, rc); if (rc) { @@ -1111,15 +1077,11 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, parms.getpin_cb_arg = getpin_cb_arg; parms.getpin_cb_desc= NULL; parms.passthru = 0; - parms.any_inq_seen = 0; parms.keydata = keydata; parms.keydatalen = keydatalen; rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL, inq_writekey_parms, &parms, NULL, NULL); - if (parms.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED || - gpg_err_code(rc) == GPG_ERR_ASS_CANCELED)) - rc = cancel_inquire (ctrl, rc); return unlock_scd (ctrl, rc); } @@ -1344,7 +1306,6 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline, inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.getpin_cb_desc = NULL; inqparm.passthru = assuan_context; - inqparm.any_inq_seen = 0; inqparm.keydata = NULL; inqparm.keydatalen = 0; @@ -1354,8 +1315,6 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline, pass_data_thru, assuan_context, inq_needpin, &inqparm, pass_status_thru, assuan_context); - if (inqparm.any_inq_seen && gpg_err_code(rc) == GPG_ERR_ASS_CANCELED) - rc = cancel_inquire (ctrl, rc); assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag); if (rc) diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 9d45a1864..866f43959 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -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+"); diff --git a/agent/command.c b/agent/command.c index 0916f886a..7c7e8a4bc 100644 --- a/agent/command.c +++ b/agent/command.c @@ -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) diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index ee1222113..c4d0334c6 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -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++) diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 88b35cd21..b85b490c1 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -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; diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 46697bae1..06a8e0b6f 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -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, diff --git a/agent/protect.c b/agent/protect.c index 7b5abf21b..16ae715e1 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -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) diff --git a/common/Makefile.am b/common/Makefile.am index fcbe7ea66..94318dae4 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -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 diff --git a/common/asshelp.c b/common/asshelp.c index f3a92f9e5..5209ea6cf 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -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"); diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 7237993a2..425f2b4d5 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -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); diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 2c44e2c75..fddcbb65c 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -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> diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c index ec9f01441..3d68a01d1 100644 --- a/common/exechelp-w32ce.c +++ b/common/exechelp-w32ce.c @@ -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> diff --git a/common/exechelp.h b/common/exechelp.h index 2b40ba098..9e1f56f70 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -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 diff --git a/common/logging.c b/common/logging.c index c4eaca411..88860e715 100644 --- a/common/logging.c +++ b/common/logging.c @@ -63,6 +63,10 @@ #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. */ diff --git a/common/logging.h b/common/logging.h index e1bf56b17..5a82be4a0 100644 --- a/common/logging.h +++ b/common/logging.h @@ -38,6 +38,35 @@ #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*/ diff --git a/common/miscellaneous.c b/common/miscellaneous.c index caeb66f81..7997a1a83 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -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 index 000000000..a3bfb474e --- /dev/null +++ b/common/pkscreening.c @@ -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 index 000000000..a64758924 --- /dev/null +++ b/common/pkscreening.h @@ -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*/ diff --git a/common/sysutils.c b/common/sysutils.c index e90010c44..55a7ee9ec 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -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*/ diff --git a/common/util.h b/common/util.h index c6d19c64b..f3722812d 100644 --- a/common/util.h +++ b/common/util.h @@ -59,6 +59,11 @@ /* 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" diff --git a/configure.ac b/configure.ac index 382ef1df5..311979ab8 100644 --- a/configure.ac +++ b/configure.ac @@ -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. # diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 6eeeb8dd3..8687c7bf4 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -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) { diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 17adae2f4..00caf0686 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -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, ':')) { diff --git a/dirmngr/http.c b/dirmngr/http.c index 8e778dfa2..cc7f5a553 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -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); diff --git a/dirmngr/misc.c b/dirmngr/misc.c index 6291a9a35..1270b834d 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -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 ( " ]"); } } diff --git a/doc/DETAILS b/doc/DETAILS index e54e8a0f7..3c089b278 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -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 diff --git a/doc/HACKING b/doc/HACKING index bd1685678..17c58269b 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -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 diff --git a/doc/Makefile.am b/doc/Makefile.am index aba84ba3c..21e3e4578 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -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 \ diff --git a/doc/examples/README b/doc/examples/README index 77ee80741..4d6a5be87 100644 --- a/doc/examples/README +++ b/doc/examples/README @@ -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. diff --git a/doc/qualified.txt b/doc/examples/qualified.txt index c0e4da582..eba11f244 100644 --- a/doc/qualified.txt +++ b/doc/examples/qualified.txt @@ -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 diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 5d79ce54e..b187a54d5 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -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 diff --git a/doc/howto-create-a-server-cert.texi b/doc/howto-create-a-server-cert.texi index 55f1a91a4..30e28bdd0 100644 --- a/doc/howto-create-a-server-cert.texi +++ b/doc/howto-create-a-server-cert.texi @@ -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 diff --git a/doc/wks.texi b/doc/wks.texi index 029dbf0c0..55dfee6d5 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -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 diff --git a/g10/call-agent.c b/g10/call-agent.c index 545b2448a..61d06c663 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -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 diff --git a/g10/card-util.c b/g10/card-util.c index a396b7df4..854b94f47 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -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")}, diff --git a/g10/ecdh.c b/g10/ecdh.c index 6c2a56b84..6587cc4b4 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -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 ) */ diff --git a/g10/encrypt.c b/g10/encrypt.c index c68d6d5d1..263226ad5 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -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); diff --git a/g10/getkey.c b/g10/getkey.c index e31e0232e..dabd052e0 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -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) { @@ -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; @@ -38,14 +38,15 @@ #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 /* diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index 2b42bfbf9..8c156d279 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -2746,7 +2746,7 @@ literal_name (const char *option, int argc, char *argv[], void *cookie) { struct litinfo *li = cookie; - if (argc <= 1) + if (argc <= 0) log_fatal ("Usage: %s NAME\n", option); if (strlen (argv[0]) > 255) diff --git a/g10/keyedit.c b/g10/keyedit.c index 4acb2de5f..8d8625371 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -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)); diff --git a/g10/keygen.c b/g10/keygen.c index b42afa858..912fa390c 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -46,11 +46,10 @@ #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; } diff --git a/g10/keyid.c b/g10/keyid.c index ba35ec21f..a9034ee46 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -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; } } diff --git a/g10/keylist.c b/g10/keylist.c index 86d1c564f..bcbad450a 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -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: diff --git a/g10/main.h b/g10/main.h index 6c15a2a8d..4a8f8c32a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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 diff --git a/g10/misc.c b/g10/misc.c index 77c8f269c..9016d2770 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -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"); } diff --git a/g10/options.h b/g10/options.h index 130bec84c..61f7403be 100644 --- a/g10/options.h +++ b/g10/options.h @@ -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. */ diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index d7ba95391..0185097a4 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -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. */ diff --git a/g10/sig-check.c b/g10/sig-check.c index 23af12b2e..f8e366b7e 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -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 ) diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 5ea903f45..37bf78b80 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -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); diff --git a/g10/tofu.c b/g10/tofu.c index 091d5b0d0..762b19b7a 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -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); diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index 8a50c3ff4..b160ba32d 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -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); diff --git a/g13/g13tuple.c b/g13/g13tuple.c index b10ebbc9a..6693826ad 100644 --- a/g13/g13tuple.c +++ b/g13/g13tuple.c @@ -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; } } diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 9b43584a6..e3814d316 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -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); } diff --git a/scd/apdu.c b/scd/apdu.c index c50afbde2..60270ede0 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -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; } diff --git a/scd/apdu.h b/scd/apdu.h index 6751e8c9b..8a0d4bda8 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -71,7 +71,8 @@ enum { SW_HOST_NO_READER = 0x1000c, SW_HOST_ABORTED = 0x1000d, SW_HOST_NO_PINPAD = 0x1000e, - SW_HOST_ALREADY_CONNECTED = 0x1000f + SW_HOST_ALREADY_CONNECTED = 0x1000f, + SW_HOST_CANCELLED = 0x10010 }; struct dev_list; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 6fcec3e4e..689d880d4 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -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); diff --git a/scd/app-p15.c b/scd/app-p15.c index 0bb5f9e51..190292433 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -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) { diff --git a/scd/iso7816.c b/scd/iso7816.c index 081b0808c..29208c254 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -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)) diff --git a/sm/certchain.c b/sm/certchain.c index a361acaf0..4e18caf55 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -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); diff --git a/sm/certcheck.c b/sm/certcheck.c index 1102bccad..51f1a9402 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -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); diff --git a/sm/certdump.c b/sm/certdump.c index edee76fa2..9567c67f5 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -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 ( " ]"); } } diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index 9772a3baf..4f8a1ac9d 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -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; diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 44318702a..1d610c1bb 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -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: [email protected] # 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) diff --git a/sm/decrypt.c b/sm/decrypt.c index 60ed14a64..b0ab63f00 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -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) diff --git a/sm/fingerprint.c b/sm/fingerprint.c index fbcec5883..4bf378a1c 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -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; +} + /* For certain purposes we need a certificate id which has an upper diff --git a/sm/gpgsm.c b/sm/gpgsm.c index b505be154..650b13030 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -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; diff --git a/sm/gpgsm.h b/sm/gpgsm.h index cd4fc995f..3e2f95fb3 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -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); diff --git a/sm/import.c b/sm/import.c index 8796cd206..ca693824a 100644 --- a/sm/import.c +++ b/sm/import.c @@ -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. */ diff --git a/sm/keylist.c b/sm/keylist.c index 9997da812..ea2a22093 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -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; diff --git a/sm/qualified.c b/sm/qualified.c index 564e77929..6a7b47306 100644 --- a/sm/qualified.c +++ b/sm/qualified.c @@ -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) { diff --git a/sm/verify.c b/sm/verify.c index 10b3f4378..b7b9fa8be 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -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); diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index f6014c9c5..e5be42b41 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -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 diff --git a/tests/openpgp/all-tests.scm b/tests/openpgp/all-tests.scm index d687fe49b..e12b175b9 100644 --- a/tests/openpgp/all-tests.scm +++ b/tests/openpgp/all-tests.scm @@ -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")) diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index a6347fe1f..9f780fe23 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -351,6 +351,7 @@ "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)) diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index b74ee04fd..c799143cd 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -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) |