Hello community, here is the log from the commit of package libTMCG for openSUSE:Factory checked in at 2018-02-10 17:58:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libTMCG (Old) and /work/SRC/openSUSE:Factory/.libTMCG.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libTMCG" Sat Feb 10 17:58:13 2018 rev:3 rq:574539 version:1.3.11 Changes: -------- --- /work/SRC/openSUSE:Factory/libTMCG/libTMCG.changes 2018-01-29 15:00:17.154593599 +0100 +++ /work/SRC/openSUSE:Factory/.libTMCG.new/libTMCG.changes 2018-02-10 17:58:14.435972793 +0100 @@ -1,0 +2,9 @@ +Thu Feb 8 21:12:35 UTC 2018 - kbabi...@suse.com + +- Update to 1.3.11: + * Improved libTMCG initialization (init_libTMCG()) + * Better handling of RFC4880 functionality + +- Switched sources to https instead of http + +------------------------------------------------------------------- Old: ---- libTMCG-1.3.10.tar.gz libTMCG-1.3.10.tar.gz.sig New: ---- libTMCG-1.3.11.tar.gz libTMCG-1.3.11.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libTMCG.spec ++++++ --- /var/tmp/diff_new_pack.ZmUgiY/_old 2018-02-10 17:58:15.611930223 +0100 +++ /var/tmp/diff_new_pack.ZmUgiY/_new 2018-02-10 17:58:15.615930078 +0100 @@ -18,17 +18,17 @@ # -%define sover 9 +%define sover 11 Name: libTMCG -Version: 1.3.10 +Version: 1.3.11 Release: 0 Summary: C++ library for creating secure and fair online card games License: GPL-2.0+ Group: Development/Libraries/C and C++ -Url: http://www.nongnu.org/libtmcg/ -Source: http://download.savannah.gnu.org/releases/libtmcg/%{name}-%{version}.tar.gz -Source2: http://download.savannah.gnu.org/releases/libtmcg/%{name}-%{version}.tar.gz.sig -Source3: http://savannah.nongnu.org/project/memberlist-gpgkeys.php?group=libtmcg&download=1#/%{name}.keyring +Url: https://www.nongnu.org/libtmcg/ +Source: https://download.savannah.gnu.org/releases/libtmcg/%{name}-%{version}.tar.gz +Source2: https://download.savannah.gnu.org/releases/libtmcg/%{name}-%{version}.tar.gz.sig +Source3: https://savannah.nongnu.org/project/memberlist-gpgkeys.php?group=libtmcg&download=1#/%{name}.keyring BuildRequires: gcc-c++ BuildRequires: gmp-devel >= 4.2 BuildRequires: libgcrypt-devel >= 1.6.0 ++++++ libTMCG-1.3.10.tar.gz -> libTMCG-1.3.11.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/ChangeLog new/libTMCG-1.3.11/ChangeLog --- old/libTMCG-1.3.10/ChangeLog 2018-01-14 09:38:23.000000000 +0100 +++ new/libTMCG-1.3.11/ChangeLog 2018-02-08 19:24:56.000000000 +0100 @@ -7,6 +7,14 @@ in the sources of this package and additionally can be obtained from Internet <https://www.gnu.org/licenses>. +* [2018-02-08] release 1.3.11 of LibTMCG +* [2018-01-26] init_libTMCG(): added libgcrypt self-test +* [2018-01-26] init_libTMCG(): check for already initialized libgcrypt +* [2018-01-23] RFC4880: introduced new enumeration type tmcg_armor_t +* [2018-01-22] RFC4880: added hash truncation for AsymmetricSignDSA() +* [2018-01-21] RFC4880: added KeyRevocationHashV3() +* [2018-01-16] RFC4880: increased buffer length for very large key sizes +* [2018-01-16] RFC4880: added OctetsCompareConstantTime() * [2018-01-14] release 1.3.10 of LibTMCG * [2018-01-12] RFC4880: added PacketSigPrepareCertificationSignature() * [2018-01-10] RFC4880: added RSA encoding for PacketPubEncode() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/NEWS new/libTMCG-1.3.11/NEWS --- old/libTMCG-1.3.10/NEWS 2018-01-14 09:37:50.000000000 +0100 +++ new/libTMCG-1.3.11/NEWS 2018-02-08 19:31:13.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (C) 2006, 2007, 2009, 2015-2017 Heiko Stamer <heikosta...@gmx.net> +Copyright (C) 2006, 2007, 2009, 2015-2018 Heiko Stamer <heikosta...@gmx.net> Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later @@ -7,6 +7,9 @@ included in the sources of this package and additionally can be obtained from Internet <https://www.gnu.org/licenses>. +1.3.11 Some small enhancements for the OpenPGP interfaces and the library + initialization have been implemented. Unfortunately, the changes + may require also an update of the application code to be effective. 1.3.10 With this release the RSA signature generation/verification for OpenPGP is introduced. Moreover, a function for preparing certification signatures has been added. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/README new/libTMCG-1.3.11/README --- old/libTMCG-1.3.10/README 2018-01-12 20:02:11.000000000 +0100 +++ new/libTMCG-1.3.11/README 2018-01-19 19:04:48.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (C) 2005, 2006, 2007, 2009, 2015, 2016, 2017 +Copyright (C) 2005, 2006, 2007, 2009, 2015, 2016, 2017, 2018 Heiko Stamer <heikosta...@gmx.net> Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 @@ -93,7 +93,11 @@ only, where $n$ denotes the total number of parties in the protocol. LibTMCG provides a well-known protocol due to Bracha in a slightly optimized variant by Cachin, Kursawe, Petzold, and Shoup. It works for $n >= 2$ - parties, however, t-resilience with $t > 0$ is achieved for $n > 3$ only. + parties, however, t-resilience with $t > 0$ is achieved for $n > 3$ only. + This protocol ensures simple reliable broadcast but not the more elaborated + Byzantine fault tolerant agreement (or terminating reliable broadcast), i.e., + the adversary can still influence the underlying point-to-point network such + that this broadcast protocol does not terminate for some parties. Please note that in most cases the application programmer must decide, where the use of a broadcast channel is neccesary and appropriate. Thus, without reliable broadcast you should take into account that not necessarily @@ -148,6 +152,7 @@ ++ GNU/Linux (Arch Linux) x86_64 gcc 7.2.0 (details omitted) ++ GNU/Linux (Trisquel Linux) x86_64 gcc 4.8.4 (details omitted) ++ OpenBSD 6.1 amd64 gcc 4.2.1 (details omitted) + ++ FreeBSD 11.1 amd64 gcc 6.4.0 (details omitted) Build & Install --------------- @@ -176,7 +181,7 @@ Copyright and License of this software -------------------------------------- (C) 2005, 2006, 2007, 2009, - 2015, 2016, 2017 Heiko Stamer <heikosta...@gmx.net> + 2015, 2016, 2017, 2018 Heiko Stamer <heikosta...@gmx.net> GNU General Public License version 2 Please have a look at file 'COPYING' and https://www.fsf.org/. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/THANKS new/libTMCG-1.3.11/THANKS --- old/libTMCG-1.3.10/THANKS 2017-09-27 20:46:26.000000000 +0200 +++ new/libTMCG-1.3.11/THANKS 2018-01-20 08:16:31.000000000 +0100 @@ -3,3 +3,4 @@ Jens Groth <j...@cs.ucla.edu> random Andreas Stieger +Karol Babioch <kbabi...@suse.de> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/TODO new/libTMCG-1.3.11/TODO --- old/libTMCG-1.3.10/TODO 2018-01-14 09:39:47.000000000 +0100 +++ new/libTMCG-1.3.11/TODO 2018-01-20 12:10:36.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (C) 2006, 2007, 2009, 2015-2017 Heiko Stamer <heikosta...@gmx.net> +Copyright (C) 2006, 2007, 2009, 2015-2018 Heiko Stamer <heikosta...@gmx.net> Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later @@ -7,6 +7,8 @@ in the sources of this package and additionally can be obtained from Internet <https://www.gnu.org/licenses>. +! add a constant-time function for modular multiplication mpz_smulm() + * add a generic group abstraction layer, e.g. for future use of ECC groups * add generic broadcast channel abstraction layer, e.g. AbstractBroadcastChannel * use secure memory allocation and erasing from libgcrypt, if requested by app diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/configure new/libTMCG-1.3.11/configure --- old/libTMCG-1.3.10/configure 2018-01-09 20:59:21.000000000 +0100 +++ new/libTMCG-1.3.11/configure 2018-01-23 21:09:15.000000000 +0100 @@ -1,7 +1,7 @@ #! /bin/sh -# From configure.ac 20180109. +# From configure.ac 20180123. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for LibTMCG 1.3.10. +# Generated by GNU Autoconf 2.69 for LibTMCG 1.3.11. # # Report bugs to <heikosta...@gmx.net>. # @@ -591,8 +591,8 @@ # Identity of this package. PACKAGE_NAME='LibTMCG' PACKAGE_TARNAME='libTMCG' -PACKAGE_VERSION='1.3.10' -PACKAGE_STRING='LibTMCG 1.3.10' +PACKAGE_VERSION='1.3.11' +PACKAGE_STRING='LibTMCG 1.3.11' PACKAGE_BUGREPORT='heikosta...@gmx.net' PACKAGE_URL='http://www.nongnu.org/libtmcg/' @@ -1350,7 +1350,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures LibTMCG 1.3.10 to adapt to many kinds of systems. +\`configure' configures LibTMCG 1.3.11 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1420,7 +1420,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of LibTMCG 1.3.10:";; + short | recursive ) echo "Configuration of LibTMCG 1.3.11:";; esac cat <<\_ACEOF @@ -1544,7 +1544,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -LibTMCG configure 1.3.10 +LibTMCG configure 1.3.11 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2197,7 +2197,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by LibTMCG $as_me 1.3.10, which was +It was created by LibTMCG $as_me 1.3.11, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2552,12 +2552,12 @@ # (Interfaces removed: CURRENT++, AGE=0, REVISION=0) # (Interfaces added: CURRENT++, AGE++, REVISION=0) # (No interfaces changed: REVISION++) -LIBTMCG_LT_CURRENT=10 -LIBTMCG_LT_AGE=1 +LIBTMCG_LT_CURRENT=11 +LIBTMCG_LT_AGE=0 LIBTMCG_LT_REVISION=0 # If API is changed in an incompatible way: increment the next counter. -LIBTMCG_CONFIG_API_VERSION=4 +LIBTMCG_CONFIG_API_VERSION=5 ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' @@ -3083,7 +3083,7 @@ # Define the identity of the package. PACKAGE='libTMCG' - VERSION='1.3.10' + VERSION='1.3.11' cat >>confdefs.h <<_ACEOF @@ -19218,7 +19218,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by LibTMCG $as_me 1.3.10, which was +This file was extended by LibTMCG $as_me 1.3.11, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19285,7 +19285,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -LibTMCG config.status 1.3.10 +LibTMCG config.status 1.3.11 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/configure.ac new/libTMCG-1.3.11/configure.ac --- old/libTMCG-1.3.10/configure.ac 2018-01-09 20:58:46.000000000 +0100 +++ new/libTMCG-1.3.11/configure.ac 2018-01-23 21:08:30.000000000 +0100 @@ -18,10 +18,10 @@ # # (Process this file with autoconf to produce a configure script.) -AC_REVISION([20180109]) +AC_REVISION([20180123]) AC_PREREQ(2.61) -AC_INIT([LibTMCG], [1.3.10], [heikosta...@gmx.net], [libTMCG], [http://www.nongnu.org/libtmcg/]) +AC_INIT([LibTMCG], [1.3.11], [heikosta...@gmx.net], [libTMCG], [http://www.nongnu.org/libtmcg/]) # The next two paragraphs are copies of behaviour from libgcrypt. @@ -29,12 +29,12 @@ # (Interfaces removed: CURRENT++, AGE=0, REVISION=0) # (Interfaces added: CURRENT++, AGE++, REVISION=0) # (No interfaces changed: REVISION++) -LIBTMCG_LT_CURRENT=10 -LIBTMCG_LT_AGE=1 +LIBTMCG_LT_CURRENT=11 +LIBTMCG_LT_AGE=0 LIBTMCG_LT_REVISION=0 # If API is changed in an incompatible way: increment the next counter. -LIBTMCG_CONFIG_API_VERSION=4 +LIBTMCG_CONFIG_API_VERSION=5 AC_LANG(C++) AC_CONFIG_SRCDIR([src/libTMCG.hh]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/doc/stamp-vti new/libTMCG-1.3.11/doc/stamp-vti --- old/libTMCG-1.3.10/doc/stamp-vti 2018-01-11 19:21:34.000000000 +0100 +++ new/libTMCG-1.3.11/doc/stamp-vti 2018-01-23 21:10:58.000000000 +0100 @@ -1,4 +1,4 @@ @set UPDATED 8 November 2017 @set UPDATED-MONTH November 2017 -@set EDITION 1.3.10 -@set VERSION 1.3.10 +@set EDITION 1.3.11 +@set VERSION 1.3.11 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/doc/version.texi new/libTMCG-1.3.11/doc/version.texi --- old/libTMCG-1.3.10/doc/version.texi 2018-01-11 19:21:34.000000000 +0100 +++ new/libTMCG-1.3.11/doc/version.texi 2018-01-23 21:10:58.000000000 +0100 @@ -1,4 +1,4 @@ @set UPDATED 8 November 2017 @set UPDATED-MONTH November 2017 -@set EDITION 1.3.10 -@set VERSION 1.3.10 +@set EDITION 1.3.11 +@set VERSION 1.3.11 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/src/CallasDonnerhackeFinneyShawThayerRFC4880.cc new/libTMCG-1.3.11/src/CallasDonnerhackeFinneyShawThayerRFC4880.cc --- old/libTMCG-1.3.10/src/CallasDonnerhackeFinneyShawThayerRFC4880.cc 2018-01-12 20:00:14.000000000 +0100 +++ new/libTMCG-1.3.11/src/CallasDonnerhackeFinneyShawThayerRFC4880.cc 2018-01-23 20:37:39.000000000 +0100 @@ -203,6 +203,17 @@ return true; } +bool CallasDonnerhackeFinneyShawThayerRFC4880::OctetsCompareConstantTime + (const tmcg_octets_t &in, const tmcg_octets_t &in2) +{ + size_t len = (in.size() < in2.size()) ? in.size() : in2.size(); + tmcg_byte_t res = 0; + + for (size_t i = 0; i < len; i++) + res |= in[i] ^ in2[i]; + return (res == 0) ? true : false; +} + bool CallasDonnerhackeFinneyShawThayerRFC4880::OctetsCompareZero (const tmcg_octets_t &in) { @@ -353,7 +364,7 @@ } void CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode - (const tmcg_byte_t type, const tmcg_octets_t &in, std::string &out) + (const tmcg_armor_t type, const tmcg_octets_t &in, std::string &out) { // Concatenating the following data creates ASCII Armor: // - An Armor Header Line, appropriate for the type of data @@ -383,18 +394,20 @@ // Line for the purposes of determining the content they delimit. switch (type) { - case 1: + case TMCG_OPENPGP_ARMOR_MESSAGE: out += "-----BEGIN PGP MESSAGE-----\r\n"; break; - case 2: + case TMCG_OPENPGP_ARMOR_SIGNATURE: out += "-----BEGIN PGP SIGNATURE-----\r\n"; break; - case 5: + case TMCG_OPENPGP_ARMOR_PRIVATE_KEY_BLOCK: out += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; break; - case 6: + case TMCG_OPENPGP_ARMOR_PUBLIC_KEY_BLOCK: out += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; break; + default: + break; } // The Armor Headers are pairs of strings that can give the user or @@ -426,25 +439,27 @@ // "END". switch (type) { - case 1: + case TMCG_OPENPGP_ARMOR_MESSAGE: out += "-----END PGP MESSAGE-----\r\n"; break; - case 2: + case TMCG_OPENPGP_ARMOR_SIGNATURE: out += "-----END PGP SIGNATURE-----\r\n"; break; - case 5: + case TMCG_OPENPGP_ARMOR_PRIVATE_KEY_BLOCK: out += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; break; - case 6: + case TMCG_OPENPGP_ARMOR_PUBLIC_KEY_BLOCK: out += "-----END PGP PUBLIC KEY BLOCK-----\r\n"; break; + default: + break; } } -tmcg_byte_t CallasDonnerhackeFinneyShawThayerRFC4880::ArmorDecode +tmcg_armor_t CallasDonnerhackeFinneyShawThayerRFC4880::ArmorDecode (const std::string &in, tmcg_octets_t &out) { - tmcg_byte_t type = 0; + tmcg_armor_t type = TMCG_OPENPGP_ARMOR_UNKNOWN; size_t spos = 0, rpos = 0, rlen = 4, cpos = 0, clen = 3, epos = 0; rpos = in.find("\r\n\r\n"); @@ -453,59 +468,59 @@ rpos = in.find("\n\n"); rlen = 2; } - cpos = in.find("\r\n="); // FIXME: does not work in all cases (use regex for detecting checksum start) + cpos = in.find("\r\n="); // FIXME: use regex for reliable detection of checksum start if (cpos == in.npos) { cpos = in.find("\n="); clen = 2; } if ((rpos == in.npos) || (cpos == in.npos)) - return 0; // no radix-64 start or checksum found in armor body + return TMCG_OPENPGP_ARMOR_UNKNOWN; // no radix-64 start or checksum found in armor body spos = in.find("-----BEGIN PGP MESSAGE-----"); epos = in.find("-----END PGP MESSAGE-----"); if ((spos != in.npos) && (epos != in.npos) && (epos > spos)) - type = 1; + type = TMCG_OPENPGP_ARMOR_MESSAGE; if (!type) { spos = in.find("-----BEGIN PGP SIGNATURE-----"); epos = in.find("-----END PGP SIGNATURE-----"); } if (!type && (spos != in.npos) && (epos != in.npos) && (epos > spos)) - type = 2; + type = TMCG_OPENPGP_ARMOR_SIGNATURE; if (!type) { spos = in.find("-----BEGIN PGP PRIVATE KEY BLOCK-----"); epos = in.find("-----END PGP PRIVATE KEY BLOCK-----"); } if (!type && (spos != in.npos) && (epos != in.npos) && (epos > spos)) - type = 5; + type = TMCG_OPENPGP_ARMOR_PRIVATE_KEY_BLOCK; if (!type) { spos = in.find("-----BEGIN PGP PUBLIC KEY BLOCK-----"); epos = in.find("-----END PGP PUBLIC KEY BLOCK-----"); } if (!type && (spos != in.npos) && (epos != in.npos) && (epos > spos)) - type = 6; + type = TMCG_OPENPGP_ARMOR_PUBLIC_KEY_BLOCK; if (!type) - return 0; // no armor header or trailer line found + return TMCG_OPENPGP_ARMOR_UNKNOWN; // no admissible armor header or trailer line found if (((spos + 26) < rpos) && ((rpos + rlen) < cpos) && ((cpos + clen + 4) < epos)) { if (in.find("-----", spos + 34) != epos) - return 0; // nested armor block detected + return TMCG_OPENPGP_ARMOR_UNKNOWN; // nested armor block detected tmcg_octets_t decoded_data; std::string chksum = ""; std::string data = in.substr(rpos + rlen, cpos - rpos - rlen); Radix64Decode(data, decoded_data); CRC24Encode(decoded_data, chksum); if (chksum != in.substr(cpos + (clen - 1), 5)) - return 0; // checksum error detected + return TMCG_OPENPGP_ARMOR_UNKNOWN; // checksum error detected out.insert(out.end(), decoded_data.begin(), decoded_data.end()); return type; } else { std::cerr << "ERROR: ArmorDecode() spos = " << spos << " rpos = " << rpos << " cpos = " << cpos << " epos = " << epos << std::endl; - return 0; + return TMCG_OPENPGP_ARMOR_UNKNOWN; } } @@ -3552,6 +3567,41 @@ left.push_back(hash[i]); } +void CallasDonnerhackeFinneyShawThayerRFC4880::KeyRevocationHashV3 + (const tmcg_octets_t &key, + const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, + tmcg_octets_t &hash, tmcg_octets_t &left) +{ + tmcg_octets_t hash_input; + + // When a signature is made over a key, the hash data starts with the + // octet 0x99, followed by a two-octet length of the key, and then body + // of the key packet. (Note that this is an old-style packet header for + // a key packet with two-octet length.) A subkey binding signature + // (type 0x18) or primary key binding signature (type 0x19) then hashes + // the subkey using the same format as the main key (also using 0x99 as + // the first octet). Key revocation signatures (types 0x20 and 0x28) + // hash only the key being revoked. + // RFC ERRATA: Primary key revocation signatures (type 0x20) hash only + // the key being revoked. Subkey revocation signature (type 0x28) hash + // first the primary key and then the subkey being revoked. + hash_input.push_back(0x99); + hash_input.push_back(key.size() >> 8); + hash_input.push_back(key.size()); + hash_input.insert(hash_input.end(), key.begin(), key.end()); + // Once the data body is hashed, then a trailer is hashed. A V3 + // signature hashes five octets of the packet body, starting from the + // signature type field. This data is the signature type, followed by + // the four-octet signature time. [...] + hash_input.insert(hash_input.end(), trailer.begin(), trailer.end()); + // After all this has been hashed in a single hash context, the + // resulting hash field is used in the signature algorithm and placed + // at the end of the Signature packet. + HashCompute(hashalgo, hash_input, hash); + for (size_t i = 0; i < 2; i++) + left.push_back(hash[i]); +} + void CallasDonnerhackeFinneyShawThayerRFC4880::KeyRevocationHash (const tmcg_octets_t &key, const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, @@ -3596,6 +3646,44 @@ left.push_back(hash[i]); } +void CallasDonnerhackeFinneyShawThayerRFC4880::KeyRevocationHashV3 + (const tmcg_octets_t &primary, const tmcg_octets_t &subkey, + const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, + tmcg_octets_t &hash, tmcg_octets_t &left) +{ + tmcg_octets_t hash_input; + + // When a signature is made over a key, the hash data starts with the + // octet 0x99, followed by a two-octet length of the key, and then body + // of the key packet. (Note that this is an old-style packet header for + // a key packet with two-octet length.) A subkey binding signature + // (type 0x18) or primary key binding signature (type 0x19) then hashes + // the subkey using the same format as the main key (also using 0x99 as + // the first octet). + // RFC ERRATA: Primary key revocation signatures (type 0x20) hash only + // the key being revoked. Subkey revocation signature (type 0x28) hash + // first the primary key and then the subkey being revoked. + hash_input.push_back(0x99); + hash_input.push_back(primary.size() >> 8); + hash_input.push_back(primary.size()); + hash_input.insert(hash_input.end(), primary.begin(), primary.end()); + hash_input.push_back(0x99); + hash_input.push_back(subkey.size() >> 8); + hash_input.push_back(subkey.size()); + hash_input.insert(hash_input.end(), subkey.begin(), subkey.end()); + // Once the data body is hashed, then a trailer is hashed. A V3 + // signature hashes five octets of the packet body, starting from the + // signature type field. This data is the signature type, followed by + // the four-octet signature time. [...] + hash_input.insert(hash_input.end(), trailer.begin(), trailer.end()); + // After all this has been hashed in a single hash context, the + // resulting hash field is used in the signature algorithm and placed + // at the end of the Signature packet. + HashCompute(hashalgo, hash_input, hash); + for (size_t i = 0; i < 2; i++) + left.push_back(hash[i]); +} + void CallasDonnerhackeFinneyShawThayerRFC4880::KeyRevocationHash (const tmcg_octets_t &primary, const tmcg_octets_t &subkey, const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, @@ -3921,7 +4009,7 @@ (const tmcg_octets_t &in, const gcry_sexp_t key, gcry_mpi_t &gk, gcry_mpi_t &myk) { - tmcg_byte_t buffer[1024]; + tmcg_byte_t buffer[2048]; gcry_sexp_t encryption, data; gcry_mpi_t v; gcry_error_t ret; @@ -3959,7 +4047,7 @@ (const gcry_mpi_t gk, const gcry_mpi_t myk, const gcry_sexp_t key, tmcg_octets_t &out) { - tmcg_byte_t buffer[1024]; + tmcg_byte_t buffer[2048]; gcry_sexp_t decryption, data; gcry_mpi_t v; gcry_error_t ret; @@ -3996,14 +4084,34 @@ (const tmcg_octets_t &in, const gcry_sexp_t key, gcry_mpi_t &r, gcry_mpi_t &s) { - tmcg_byte_t buffer[1024]; + tmcg_byte_t buffer[2048]; gcry_sexp_t sigdata, signature; - gcry_mpi_t h; + gcry_mpi_t q, h; + unsigned int qbits = 0; gcry_error_t ret; - size_t buflen = 0, erroff; + size_t buflen = 0, erroff, trunclen = 0; + // DSA signatures MUST use hashes that are equal in size to the number + // of bits of q, the group generated by the DSA key's generator value. + // If the output size of the chosen hash is larger than the number of + // bits of q, the hash result is truncated to fit by taking the number + // of leftmost bits equal to the number of bits of q. This (possibly + // truncated) hash function result is treated as a number and used + // directly in the DSA signature algorithm. + ret = gcry_sexp_extract_param(key, NULL, "q", &q, NULL); + if (ret) + return ret; + qbits = gcry_mpi_get_nbits(q); + gcry_mpi_release(q); + if (((in.size() * 8) < qbits) || (qbits < 160)) + return GPG_ERR_BAD_PUBKEY; + trunclen = in.size(); + while ((trunclen * 8) > qbits) + --trunclen; + if ((trunclen * 8) != qbits) + return GPG_ERR_BAD_PUBKEY; memset(buffer, 0, sizeof(buffer)); - for (size_t i = 0; ((i < in.size()) && (i < sizeof(buffer))); i++, buflen++) + for (size_t i = 0; ((i < in.size()) && (i < sizeof(buffer)) && (i < trunclen)); i++, buflen++) buffer[i] = in[i]; ret = gcry_mpi_scan(&h, GCRYMPI_FMT_USG, buffer, buflen, NULL); if (ret) @@ -4030,7 +4138,7 @@ (const tmcg_octets_t &in, const gcry_sexp_t key, const gcry_mpi_t r, const gcry_mpi_t s) { - tmcg_byte_t buffer[1024]; + tmcg_byte_t buffer[2048]; gcry_sexp_t sigdata, signature; gcry_mpi_t q, h; unsigned int qbits = 0; @@ -4049,11 +4157,13 @@ return ret; qbits = gcry_mpi_get_nbits(q); gcry_mpi_release(q); - if ((in.size() * 8) < qbits) + if (((in.size() * 8) < qbits) || (qbits < 160)) return GPG_ERR_BAD_PUBKEY; trunclen = in.size(); while ((trunclen * 8) > qbits) --trunclen; + if ((trunclen * 8) != qbits) + return GPG_ERR_BAD_PUBKEY; memset(buffer, 0, sizeof(buffer)); for (size_t i = 0; ((i < in.size()) && (i < sizeof(buffer)) && (i < trunclen)); i++, buflen++) buffer[i] = in[i]; @@ -4084,7 +4194,7 @@ const tmcg_byte_t hashalgo, gcry_mpi_t &s) { - tmcg_byte_t buffer[1024]; + tmcg_byte_t buffer[2048]; gcry_sexp_t sigdata, signature; gcry_mpi_t h; gcry_error_t ret; @@ -4122,7 +4232,7 @@ const tmcg_byte_t hashalgo, const gcry_mpi_t s) { - tmcg_byte_t buffer[1024]; + tmcg_byte_t buffer[2048]; gcry_sexp_t sigdata, signature; gcry_mpi_t h; gcry_error_t ret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/src/CallasDonnerhackeFinneyShawThayerRFC4880.hh new/libTMCG-1.3.11/src/CallasDonnerhackeFinneyShawThayerRFC4880.hh --- old/libTMCG-1.3.10/src/CallasDonnerhackeFinneyShawThayerRFC4880.hh 2018-01-12 19:48:17.000000000 +0100 +++ new/libTMCG-1.3.11/src/CallasDonnerhackeFinneyShawThayerRFC4880.hh 2018-01-23 20:35:46.000000000 +0100 @@ -46,6 +46,17 @@ typedef unsigned char tmcg_byte_t; typedef std::vector<tmcg_byte_t> tmcg_octets_t; + enum tmcg_armor_t + { + TMCG_OPENPGP_ARMOR_UNKNOWN = 0, + TMCG_OPENPGP_ARMOR_MESSAGE = 1, + TMCG_OPENPGP_ARMOR_SIGNATURE = 2, + TMCG_OPENPGP_ARMOR_MESSAGE_PART_X = 3, + TMCG_OPENPGP_ARMOR_MESSAGE_PART_X_Y = 4, + TMCG_OPENPGP_ARMOR_PRIVATE_KEY_BLOCK = 5, + TMCG_OPENPGP_ARMOR_PUBLIC_KEY_BLOCK = 6 + }; + // FIXME(C++11): move following definitions into class static const tmcg_byte_t tmcg_fRadix64[] = { 255, 255, 255, 255, 255, 255, 255, 255, @@ -201,6 +212,8 @@ (const tmcg_byte_t algo, std::string &out); static bool OctetsCompare (const tmcg_octets_t &in, const tmcg_octets_t &in2); + static bool OctetsCompareConstantTime + (const tmcg_octets_t &in, const tmcg_octets_t &in2); static bool OctetsCompareZero (const tmcg_octets_t &in); @@ -214,9 +227,9 @@ static void CRC24Encode (const tmcg_octets_t &in, std::string &out); static void ArmorEncode - (const tmcg_byte_t type, const tmcg_octets_t &in, + (const tmcg_armor_t type, const tmcg_octets_t &in, std::string &out); - static tmcg_byte_t ArmorDecode + static tmcg_armor_t ArmorDecode (const std::string &in, tmcg_octets_t &out); static void FingerprintCompute (const tmcg_octets_t &in, tmcg_octets_t &out); @@ -404,10 +417,18 @@ (const tmcg_octets_t &primary, const tmcg_octets_t &subkey, const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, tmcg_octets_t &hash, tmcg_octets_t &left); + static void KeyRevocationHashV3 + (const tmcg_octets_t &key, + const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, + tmcg_octets_t &hash, tmcg_octets_t &left); static void KeyRevocationHash (const tmcg_octets_t &key, const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, tmcg_octets_t &hash, tmcg_octets_t &left); + static void KeyRevocationHashV3 + (const tmcg_octets_t &primary, const tmcg_octets_t &subkey, + const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, + tmcg_octets_t &hash, tmcg_octets_t &left); static void KeyRevocationHash (const tmcg_octets_t &primary, const tmcg_octets_t &subkey, const tmcg_octets_t &trailer, const tmcg_byte_t hashalgo, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/src/libTMCG.cc new/libTMCG-1.3.11/src/libTMCG.cc --- old/libTMCG-1.3.10/src/libTMCG.cc 2017-09-01 12:54:34.000000000 +0200 +++ new/libTMCG-1.3.11/src/libTMCG.cc 2018-01-27 11:00:49.000000000 +0100 @@ -3,7 +3,7 @@ This file is part of LibTMCG. - Copyright (C) 2004, 2005, 2007, 2016, 2017 Heiko Stamer <heikosta...@gmx.net> + Copyright (C) 2004, 2005, 2007, 2016--2018 Heiko Stamer <heikosta...@gmx.net> LibTMCG is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,8 +49,20 @@ TMCG_LIBGCRYPT_VERSION << " needed" << std::endl; return false; } - gcry_control(GCRYCTL_DISABLE_SECMEM, 0); // disable secure memory - gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) + { + gcry_control(GCRYCTL_DISABLE_SECMEM, 0); // disable secure memory + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + } + // check libgcrypt + gcry_error_t ret = gcry_control(GCRYCTL_SELFTEST); + if (ret) + { + std::cerr << "init_libTMCG(): libgcrypt self-test " << + "failed (rc = " << gcry_err_code(ret) << ", str = " << + gcry_strerror(ret) << ")" << std::endl; + return false; + } if (gcry_md_test_algo(TMCG_GCRY_MD_ALGO)) // check for digest algorithm { std::cerr << "init_libTMCG(): libgcrypt algorithm " << diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/src/libTMCG.m4 new/libTMCG-1.3.11/src/libTMCG.m4 --- old/libTMCG-1.3.10/src/libTMCG.m4 2015-07-21 23:59:44.000000000 +0200 +++ new/libTMCG-1.3.11/src/libTMCG.m4 2018-01-20 22:49:17.000000000 +0100 @@ -1,6 +1,6 @@ -dnl Autoconf macros for libTMCG (source adapted from libgcrypt.m4) +dnl Autoconf macros for LibTMCG (source adapted from libgcrypt.m4) dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. -dnl 2005 Heiko Stamer <sta...@gaos.org> +dnl 2005, 2018 Heiko Stamer <heikosta...@gmx.net> dnl dnl This file is free software; as a special exception the author gives dnl unlimited permission to copy and/or distribute it, with or without @@ -18,12 +18,12 @@ dnl with the API version to also check the API compatibility. Example: dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed dnl version of libTMCG is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libTMCG +dnl this features allows to prevent build against newer versions of LibTMCG dnl with a changed API. dnl AC_DEFUN([AM_PATH_LIBTMCG], [ AC_ARG_WITH(libTMCG-prefix, - AC_HELP_STRING([--with-libTMCG-prefix=PFX], + AS_HELP_STRING([--with-libTMCG-prefix=<path>s], [prefix where libTMCG is installed (optional)]), libtmcg_config_prefix="$withval", libtmcg_config_prefix="") if test x$libtmcg_config_prefix != x ; then @@ -80,7 +80,7 @@ AC_MSG_RESULT(no) fi if test $ok = yes; then - # If we have a recent libTMCG, we should also check that the + # If we have a recent LibTMCG, we should also check that the # API is compatible if test "$req_libtmcg_api" -gt 0 ; then tmp=`$LIBTMCG_CONFIG --api-version 2>/dev/null || echo 0` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libTMCG-1.3.10/tests/t-rfc4880.cc new/libTMCG-1.3.11/tests/t-rfc4880.cc --- old/libTMCG-1.3.10/tests/t-rfc4880.cc 2018-01-09 21:50:33.000000000 +0100 +++ new/libTMCG-1.3.11/tests/t-rfc4880.cc 2018-01-23 20:46:30.000000000 +0100 @@ -36,9 +36,24 @@ { gcry_error_t ret; tmcg_octets_t in, out; - tmcg_byte_t b; + + // testing OctetsCompare(), OctetsCompareConstantTime(), and OctetsCompareZero() + std::cout << "OctetsCompareZero() "; + do + { + in.clear(), out.clear(); + for (size_t j = 0; j < 6; j++) + in.push_back(mpz_wrandom_ui() % 2); + for (size_t j = 0; j < 6; j++) + out.push_back(mpz_wrandom_ui() % 2); + assert((CallasDonnerhackeFinneyShawThayerRFC4880::OctetsCompare(in, out) == CallasDonnerhackeFinneyShawThayerRFC4880::OctetsCompareConstantTime(out, in))); + std::cout << "~"; + } + while (!CallasDonnerhackeFinneyShawThayerRFC4880::OctetsCompareZero(in)); + std::cout << std::endl; // testing Radix64Encode() and Radix64Decode() + in.clear(), out.clear(); for (size_t j = 0; j < 256; j++) { std::string radix; @@ -65,23 +80,26 @@ } // testing ArmorEncode() and ArmorDecode() - for (size_t j = 0; j < 10; j++) + std::vector<tmcg_armor_t> vat; + tmcg_armor_t at; + vat.push_back(TMCG_OPENPGP_ARMOR_MESSAGE); + vat.push_back(TMCG_OPENPGP_ARMOR_SIGNATURE); + vat.push_back(TMCG_OPENPGP_ARMOR_PRIVATE_KEY_BLOCK); + vat.push_back(TMCG_OPENPGP_ARMOR_PUBLIC_KEY_BLOCK); + for (std::vector<tmcg_armor_t>::iterator j = vat.begin(); j != vat.end(); ++j) { std::string u = "Max Mustermann <m...@gaos.org>", armor; - - if ((j != 1) && (j != 2) && (j != 5) && (j != 6)) - continue; // currently only this armor types are supported in.clear(), out.clear(); std::cout << "PackedUidEncode(\"" << u << "\", in)" << std::endl; CallasDonnerhackeFinneyShawThayerRFC4880::PacketUidEncode(u, in); - std::cout << "ArmorEncode(" << j << ", in, armor)" << std::endl; - CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode(j, in, armor); + std::cout << "ArmorEncode(" << *j << ", in, armor)" << std::endl; + CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode(*j, in, armor); std::cout << armor << std::endl; std::cout << "ArmorDecode(armor, out) = "; - b = CallasDonnerhackeFinneyShawThayerRFC4880::ArmorDecode(armor, out); - std::cout << (int)b << std::endl; - assert((int)b == j); + at = CallasDonnerhackeFinneyShawThayerRFC4880::ArmorDecode(armor, out); + std::cout << (int)at << std::endl; + assert(at == *j); assert(in.size() == out.size()); for (size_t i = 0; i < in.size(); i++) { @@ -122,7 +140,7 @@ subkeyid.push_back(0x00); CallasDonnerhackeFinneyShawThayerRFC4880::PacketPkeskEncode(subkeyid, gk, myk, out); CallasDonnerhackeFinneyShawThayerRFC4880::PacketSedEncode(enc, out); - CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode(1, out, armored_message); + CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode(TMCG_OPENPGP_ARMOR_MESSAGE, out, armored_message); std::cout << armored_message << std::endl; out.clear(), prefix.clear(), seskey.clear(); std::cout << "AsymmetricDecryptElgamal(...)" << std::endl; @@ -163,11 +181,19 @@ assert(!ret); CallasDonnerhackeFinneyShawThayerRFC4880::PacketSigPrepareDetachedSignature(0x00, 8, time(NULL), 60, subkeyid, trailer); CallasDonnerhackeFinneyShawThayerRFC4880::PacketSigEncode(trailer, left, r, s, sig); - CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode(2, sig, armored_signature); + CallasDonnerhackeFinneyShawThayerRFC4880::ArmorEncode(TMCG_OPENPGP_ARMOR_SIGNATURE, sig, armored_signature); std::cout << armored_signature << std::endl; std::cout << "AsymmetricVerifyDSA(...)" << std::endl; ret = CallasDonnerhackeFinneyShawThayerRFC4880::AsymmetricVerifyDSA(hash, dsakey, r, s); assert(!ret); + std::cout << "AsymmetricSignDSA(...) with truncated hash" << std::endl; + hash.clear(); + CallasDonnerhackeFinneyShawThayerRFC4880::HashCompute(10, lit, hash); // SHA512 + ret = CallasDonnerhackeFinneyShawThayerRFC4880::AsymmetricSignDSA(hash, dsakey, r, s); + assert(!ret); + std::cout << "AsymmetricVerifyDSA(...) with truncated hash" << std::endl; + ret = CallasDonnerhackeFinneyShawThayerRFC4880::AsymmetricVerifyDSA(hash, dsakey, r, s); + assert(!ret); gcry_sexp_release(dsaparms); gcry_sexp_release(dsakey); gcry_mpi_release(r); ++++++ libTMCG.keyring ++++++ --- /var/tmp/diff_new_pack.ZmUgiY/_old 2018-02-10 17:58:15.787923852 +0100 +++ /var/tmp/diff_new_pack.ZmUgiY/_new 2018-02-10 17:58:15.791923707 +0100 @@ -80,4 +80,3 @@ =I2tJ -----END PGP PUBLIC KEY BLOCK----- -