From cvs at cvs.gnupg.org Mon Feb 1 15:50:37 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 01 Feb 2016 15:50:37 +0100 Subject: [git] gnupg-doc - branch, master, updated. 17c0063e220c2f49c5abd42c01499ec2ec30a70d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 17c0063e220c2f49c5abd42c01499ec2ec30a70d (commit) via 303a9a935643a256f3eed579c3e47c43d7e53c24 (commit) from d08d7a5305049f1c91f6fede3eeeafe313329217 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 17c0063e220c2f49c5abd42c01499ec2ec30a70d Author: Werner Koch Date: Mon Feb 1 15:45:34 2016 +0100 web: Move some news to archive. diff --git a/web/index.org b/web/index.org index 816dd4d..168f03a 100644 --- a/web/index.org +++ b/web/index.org @@ -65,6 +65,11 @@ The latest release news:\\ # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** GnuPG 2.1.11 released (2016-01-26) + +A new version of the /modern/ branch of GnuPG has been released. +Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2016q1/000383.html][announcement mail]] for details. + ** GnuPG 1.4.20 released (2015-12-20) 18 years after the first GnuPG release version 1.4.20 has been @@ -128,75 +133,6 @@ Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q3/000371.h A new version of the /modern/ branch of GnuPG has been released. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q3/000370.html][announcement mail]] for details. -** GnuPG 2.1.5 released (2015-06-11) - -A new version of the /modern/ branch of GnuPG has been released. -Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000369.html][announcement mail]] for details. - - -** GPGME 1.5.5 released (2015-06-08) - -GPGME 1.5.5 is now available. This release fixes a crash due to -malformed user ids and a regression when gpgsm < 2.1 is used. See the -full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000368.html][{announcement}]] mail. - - -** GnuPG 2.0.28 released (2015-06-02) - -GnuPG 2.0.28 is now available. This release fixes a couple of bugs; -users of GnuPG 2.0.x should update to this version. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000367.html][{more}]] - -** GnuPG 2.1.4 released (2015-05-12) - -A new version of the /modern/ branch of GnuPG has been released. -Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000366.html][announcement mail]] for details. - -** GnuPG 2.1.3 released (2015-04-11) - -This is another release of the /modern/ branch of GnuPG. It fixes -a lot of bugs. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000365.html][announcement mail]]. - -** GnuPG 1.4.19 released (2015-02-27) :important: - -GnuPG 1.4.19 is now available. This release mitigates two new of side -channel attack methods as well as a couple of other bugs. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000363.html][{more}]] - -** Libgcrypt 1.6.3 released (2015-02-27) :important: - -Libgcrypt version 1.6.3 has been released to mitigate two new side -channel attack methods. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000364.html][{more}]] - -** GnuPG 2.0.27 released (2015-02-18) - -GnuPG 2.0.27 is now available. This release fixes a couple of bugs; -users of GnuPG 2.0.x should update to this version. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000362.html][{more}]] - -** GnuPG 2.1.2 released (2015-02-11) - -This is the third release of the /modern/ branch of GnuPG. It fixes -a lot of bugs. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000361.html][announcement mail]]. - -** GnuPG 2.1.1 released (2014-12-16) - -This is the second release of the /modern/ branch of GnuPG. It fixes -a lot of bugs and brings some new features. Read more about 2.1 at -the [[file:faq/whats-new-in-2.1.org][feature overview]] page and in the [[https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000360.html][announcement]] mail. - - -** Libksba 1.3.2 released (2014-11-25) :important: - -This is a security fix release and all users of Libksba should update -to this version. Note that *GnuPG 2.x* makes use of Libksba and thus -all user of GnuPG 2.x need to install this new version of Libksba and -restart the dirmngr process. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000359.html][announcement]]. - - -** GnuPG 2.1.0 with ECC support released (2014-11-06) - -This is the first release of the new /modern/ branch of GnuPG. It -features a lot of new things including support for ECC. Read more at -the [[file:faq/whats-new-in-2.1.org][feature overview]] page and in the [[https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000358.html][announcement]] mail. - * A big Thanks to all supporters diff --git a/web/news.org b/web/news.org index 6cfbd15..b1229c5 100644 --- a/web/news.org +++ b/web/news.org @@ -8,6 +8,73 @@ chronological order. News for the current year are found at the [[index][main page]]. +** GnuPG 2.1.5 released (2015-06-11) + +A new version of the /modern/ branch of GnuPG has been released. +Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000369.html][announcement mail]] for details. + +** GPGME 1.5.5 released (2015-06-08) + +GPGME 1.5.5 is now available. This release fixes a crash due to +malformed user ids and a regression when gpgsm < 2.1 is used. See the +full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000368.html][{announcement}]] mail. + +** GnuPG 2.0.28 released (2015-06-02) + +GnuPG 2.0.28 is now available. This release fixes a couple of bugs; +users of GnuPG 2.0.x should update to this version. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000367.html][{more}]] + +** GnuPG 2.1.4 released (2015-05-12) + +A new version of the /modern/ branch of GnuPG has been released. +Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000366.html][announcement mail]] for details. + +** GnuPG 2.1.3 released (2015-04-11) + +This is another release of the /modern/ branch of GnuPG. It fixes +a lot of bugs. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q2/000365.html][announcement mail]]. + +** GnuPG 1.4.19 released (2015-02-27) :important: + +GnuPG 1.4.19 is now available. This release mitigates two new of side +channel attack methods as well as a couple of other bugs. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000363.html][{more}]] + +** Libgcrypt 1.6.3 released (2015-02-27) :important: + +Libgcrypt version 1.6.3 has been released to mitigate two new side +channel attack methods. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000364.html][{more}]] + +** GnuPG 2.0.27 released (2015-02-18) + +GnuPG 2.0.27 is now available. This release fixes a couple of bugs; +users of GnuPG 2.0.x should update to this version. [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000362.html][{more}]] + +** GnuPG 2.1.2 released (2015-02-11) + +This is the third release of the /modern/ branch of GnuPG. It fixes +a lot of bugs. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2015q1/000361.html][announcement mail]]. + +** GnuPG 2.1.1 released (2014-12-16) + +This is the second release of the /modern/ branch of GnuPG. It fixes +a lot of bugs and brings some new features. Read more about 2.1 at +the [[file:faq/whats-new-in-2.1.org][feature overview]] page and in the [[https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000360.html][announcement]] mail. + + +** Libksba 1.3.2 released (2014-11-25) :important: + +This is a security fix release and all users of Libksba should update +to this version. Note that *GnuPG 2.x* makes use of Libksba and thus +all user of GnuPG 2.x need to install this new version of Libksba and +restart the dirmngr process. Read the full [[https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000359.html][announcement]]. + + +** GnuPG 2.1.0 with ECC support released (2014-11-06) + +This is the first release of the new /modern/ branch of GnuPG. It +features a lot of new things including support for ECC. Read more at +the [[file:faq/whats-new-in-2.1.org][feature overview]] page and in the [[https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000358.html][announcement]] mail. + ** A beta for GnuPG 2.1.0 released (2014-10-03) A beta release for the forthcoming GnuPG 2.1 version is now commit 303a9a935643a256f3eed579c3e47c43d7e53c24 Author: Werner Koch Date: Mon Feb 1 15:45:03 2016 +0100 web: Remove PGP5-GnUPG howto due to broken link -- GnuPG-bug-id: 2237 diff --git a/web/documentation/howtos.org b/web/documentation/howtos.org index 26b1723..d3e98b3 100644 --- a/web/documentation/howtos.org +++ b/web/documentation/howtos.org @@ -60,13 +60,6 @@ This smartcard howto is also available in the [[../download/cvs_access.org][source repository]]. -** PGP5-GnuPG HOWTO - - If you have problems exchanging messages with a PGP 5.x system, you - should have a look at this [[http://technocage.com/~caskey/gnupg/pgp2gnupg.html][PGP5-GnuPG HOWTO]] available in English - only. Note that PGP 5 is heavily out of date and should not be - used. - ** GnuPG Keysigning Party HOWTO Once you get familiar with GnuPG's mechanisms, you surely wouldn't ----------------------------------------------------------------------- Summary of changes: web/documentation/howtos.org | 7 ----- web/index.org | 74 +++----------------------------------------- web/news.org | 67 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 76 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 1 18:39:18 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 01 Feb 2016 18:39:18 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-6-g22caa5c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 22caa5c2d4b65289a0857c36bcded36b34baf4d2 (commit) from aa4a3aa3e7a0c7dc231b90b2958184c7138ccc93 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 22caa5c2d4b65289a0857c36bcded36b34baf4d2 Author: Werner Koch Date: Mon Feb 1 18:06:14 2016 +0100 Fix possible sign extension problem with newer compilers. * cipher/des.c (READ_64BIT_DATA): Cast to u32 before shifting by 24. * cipher/blowfish.c (do_encrypt_block): Ditto. (do_decrypt_block): Ditto. * cipher/camellia.c (CAMELLIA_RR8): Ditto. * cipher/cast5.c (do_encrypt_block): Ditto. (do_decrypt_block): Ditto. (do_cast_setkey): Ditto. * cipher/twofish.c (INPACK): Ditto. * util/iobuf.c (block_filter): Ditto. -- For cipher/des.c Reported-by: Balint Reczey See commit 57af33d9e7c9b20b413b96882e670e75a67a5e65 for details. Signed-off-by: Werner Koch diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 61cd2b7..e421099 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -278,7 +278,7 @@ static void burn_stack (int bytes) { char buf[64]; - + wipememory(buf,sizeof buf); bytes -= sizeof buf; if (bytes > 0) @@ -424,8 +424,8 @@ do_encrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf ) { u32 d1, d2; - d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + d1 = (u32)inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = (u32)inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; do_encrypt( bc, &d1, &d2 ); outbuf[0] = (d1 >> 24) & 0xff; outbuf[1] = (d1 >> 16) & 0xff; @@ -449,8 +449,8 @@ do_decrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf ) { u32 d1, d2; - d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + d1 = (u32)inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = (u32)inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; decrypt( bc, &d1, &d2 ); outbuf[0] = (d1 >> 24) & 0xff; outbuf[1] = (d1 >> 16) & 0xff; diff --git a/cipher/camellia.c b/cipher/camellia.c index 1a204e1..a03266e 100644 --- a/cipher/camellia.c +++ b/cipher/camellia.c @@ -18,7 +18,7 @@ */ /* - * Algorithm Specification + * Algorithm Specification * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ @@ -77,7 +77,7 @@ typedef unsigned char u8; #define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) /* rotation right shift 1byte */ -#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) +#define CAMELLIA_RR8(x) (((x) >> 8) + ((u32)(x) << 24)) /* rotation left shift 1bit */ #define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) /* rotation left shift 1byte */ @@ -936,7 +936,7 @@ void camellia_setup256(const unsigned char *key, u32 *subkey) CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw; dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw; - + return; } @@ -1048,14 +1048,14 @@ void camellia_encrypt128(const u32 *subkey, u32 *io) io[1] = io[3]; io[2] = t0; io[3] = t1; - + return; } void camellia_decrypt128(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ - + /* pre whitening but absorb kw2*/ io[0] ^= CamelliaSubkeyL(24); io[1] ^= CamelliaSubkeyR(24); @@ -1266,7 +1266,7 @@ void camellia_decrypt256(const u32 *subkey, u32 *io) /* pre whitening but absorb kw2*/ io[0] ^= CamelliaSubkeyL(32); io[1] ^= CamelliaSubkeyR(32); - + /* main iteration */ CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(31),CamelliaSubkeyR(31), @@ -1378,8 +1378,8 @@ void camellia_decrypt256(const u32 *subkey, u32 *io) * API for compatibility */ -void Camellia_Ekeygen(const int keyBitLength, - const unsigned char *rawKey, +void Camellia_Ekeygen(const int keyBitLength, + const unsigned char *rawKey, KEY_TABLE_TYPE keyTable) { switch(keyBitLength) { @@ -1398,9 +1398,9 @@ void Camellia_Ekeygen(const int keyBitLength, } -void Camellia_EncryptBlock(const int keyBitLength, - const unsigned char *plaintext, - const KEY_TABLE_TYPE keyTable, +void Camellia_EncryptBlock(const int keyBitLength, + const unsigned char *plaintext, + const KEY_TABLE_TYPE keyTable, unsigned char *ciphertext) { u32 tmp[4]; @@ -1429,9 +1429,9 @@ void Camellia_EncryptBlock(const int keyBitLength, PUTU32(ciphertext + 12, tmp[3]); } -void Camellia_DecryptBlock(const int keyBitLength, - const unsigned char *ciphertext, - const KEY_TABLE_TYPE keyTable, +void Camellia_DecryptBlock(const int keyBitLength, + const unsigned char *ciphertext, + const KEY_TABLE_TYPE keyTable, unsigned char *plaintext) { u32 tmp[4]; diff --git a/cipher/cast5.c b/cipher/cast5.c index ed8c738..8d46f1a 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -353,7 +353,7 @@ static void burn_stack (int bytes) { char buf[64]; - + wipememory(buf,sizeof buf); bytes -= sizeof buf; if (bytes > 0) @@ -375,8 +375,8 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf ) /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.) */ - l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + l = (u32)inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + r = (u32)inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows: * Li = Ri-1; @@ -433,8 +433,8 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf ) Km = c->Km; Kr = c->Kr; - l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + l = (u32)inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + r = (u32)inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); @@ -588,10 +588,10 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen ) if( keylen != 16 ) return G10ERR_WRONG_KEYLEN; - x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; - x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]; - x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]; - x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]; + x[0] = (u32)key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; + x[1] = (u32)key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]; + x[2] = (u32)key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]; + x[3] = (u32)key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]; key_schedule( x, z, k ); for(i=0; i < 16; i++ ) diff --git a/cipher/des.c b/cipher/des.c index 756c146..670ba65 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -429,15 +429,15 @@ static byte weak_keys[64][8] = /* * Macros to convert 8 bytes from/to 32bit words. */ -#define READ_64BIT_DATA(data, left, right) \ - left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ - right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; +#define READ_64BIT_DATA(data, left, right) \ + left = ((u32)data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ + right = ((u32)data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; -#define WRITE_64BIT_DATA(data, left, right) \ - data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ - data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ - data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ - data[6] = (right >> 8) &0xff; data[7] = right &0xff; +#define WRITE_64BIT_DATA(data, left, right) \ + data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ + data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ + data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ + data[6] = (right >> 8) &0xff; data[7] = right &0xff; /* * Handy macros for encryption and decryption of data @@ -452,7 +452,7 @@ static void burn_stack (int bytes) { char buf[64]; - + wipememory(buf,sizeof buf); bytes -= sizeof buf; if (bytes > 0) @@ -960,7 +960,7 @@ do_tripledes_setkey ( void *ctx, const byte *key, unsigned keylen ) burn_stack (64); return G10ERR_WEAK_KEY; } - burn_stack (64); + burn_stack (64); return 0; } diff --git a/cipher/twofish.c b/cipher/twofish.c index 2feccdf..2fe3791 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -549,7 +549,7 @@ static void burn_stack (int bytes) { char buf[64]; - + wipememory(buf,sizeof buf); bytes -= sizeof buf; if (bytes > 0) @@ -702,7 +702,7 @@ twofish_setkey (void *ctx, const byte *key, unsigned int keylen) burn_stack (23+6*sizeof(void*)); return rc; } - + /* Macros to compute the g() function in the encryption and decryption @@ -756,7 +756,7 @@ twofish_setkey (void *ctx, const byte *key, unsigned int keylen) #define INPACK(n, x, m) \ x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \ - ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m] + ^ (in[4 * (n) + 2] << 16) ^ ((u32)in[4 * (n) + 3] << 24) ^ ctx->w[m] #define OUTUNPACK(n, x, m) \ x ^= ctx->w[m]; \ diff --git a/util/iobuf.c b/util/iobuf.c index 539356e..c844292 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -738,7 +738,7 @@ block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len) } } else if( c == 255 ) { - a->size = iobuf_get(chain) << 24; + a->size = (size_t)iobuf_get(chain) << 24; a->size |= iobuf_get(chain) << 16; a->size |= iobuf_get(chain) << 8; if( (c = iobuf_get(chain)) == -1 ) { ----------------------------------------------------------------------- Summary of changes: cipher/blowfish.c | 10 +++++----- cipher/camellia.c | 28 ++++++++++++++-------------- cipher/cast5.c | 18 +++++++++--------- cipher/des.c | 20 ++++++++++---------- cipher/twofish.c | 6 +++--- util/iobuf.c | 2 +- 6 files changed, 42 insertions(+), 42 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 2 06:07:00 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 02 Feb 2016 06:07:00 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-308-ga2f9afc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via a2f9afcd7fcdafd5951498b07f34957f9766dce9 (commit) from 57b60bb1718b4f2c2500bb447ebd1d4562a5aa9b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a2f9afcd7fcdafd5951498b07f34957f9766dce9 Author: NIIBE Yutaka Date: Tue Feb 2 13:58:48 2016 +0900 ecc: Fix ECDH of Curve25519. * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Fix calc of NBITS and prefix detection. * cipher/ecc.c (ecc_generate): Use NBITS instead of CTX->NBITS. (ecc_encrypt_raw): Use NBITS from curve instead of from P. Fix rawmpilen calculation. (ecc_decrypt_raw): Likewise. Add debug output. -- This fixes the commit dd3d06e7. NBITS is defined 256 in ecc-curves.c, thus, ecc_get_nbits returns 256. But CTX->NBITS has 255 for Montgomery curve. diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 67e3b3d..33af6f7 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -322,7 +322,9 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) } else { - a = rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL); + unsigned int nbytes = (ctx->nbits+7)/8; + + a = rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL); if (!a) return gpg_err_code_from_syserror (); /* @@ -339,16 +341,17 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) * So, we need to check if it's really the prefix or not. * Only when it's the prefix, we remove it. */ - if (ctx->nbits/8 == rawmpilen - 1) - rawmpi++; - else if (rawmpilen < ctx->nbits/8) + if (rawmpilen > nbytes) + {/* Prefix 0x40 or 0x00 */ + rawmpi++; + rawmpilen = nbytes; + } + else if (rawmpilen < nbytes) {/* * It is possible for data created by older implementation * to have shorter length when it was parsed as MPI. */ - unsigned int new_rawmpilen = ctx->nbits/8; - - rawmpi = xtrymalloc (new_rawmpilen); + rawmpi = xtrymalloc (nbytes); if (!rawmpi) { gpg_err_code_t err = gpg_err_code_from_syserror (); @@ -356,8 +359,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) return err; } - memset (rawmpi, 0, new_rawmpilen - rawmpilen); - memcpy (rawmpi + new_rawmpilen - rawmpilen, a, rawmpilen); + memset (rawmpi, 0, nbytes - rawmpilen); + memcpy (rawmpi + nbytes - rawmpilen, a, rawmpilen); } } diff --git a/cipher/ecc.c b/cipher/ecc.c index 105650e..7d6ad94 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -606,8 +606,8 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) &encpk, &encpklen); else { - encpk = _gcry_mpi_get_buffer_extra (Qx, ctx->nbits/8, -1, - &encpklen, NULL); + encpk = _gcry_mpi_get_buffer_extra (Qx, nbits/8, + -1, &encpklen, NULL); if (encpk == NULL) rc = gpg_err_code_from_syserror (); else @@ -1231,6 +1231,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) static gcry_err_code_t ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) { + unsigned int nbits; gcry_err_code_t rc; struct pk_encoding_ctx ctx; gcry_sexp_t l1 = NULL; @@ -1246,7 +1247,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) memset (&pk, 0, sizeof pk); _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, - ecc_get_nbits (keyparms)); + (nbits = ecc_get_nbits (keyparms))); /* Look for flags. */ l1 = sexp_find_token (keyparms, "flags", 0); @@ -1371,13 +1372,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p); else { - rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, - &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { rawmpi[0] = 0x40; + rawmpilen++; mpi_s = mpi_new (0); mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8); } @@ -1392,13 +1393,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p); else { - rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, - &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { rawmpi[0] = 0x40; + rawmpilen++; mpi_e = mpi_new (0); mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8); } @@ -1447,6 +1448,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) static gcry_err_code_t ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) { + unsigned int nbits; gpg_err_code_t rc; struct pk_encoding_ctx ctx; gcry_sexp_t l1 = NULL; @@ -1465,7 +1467,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) point_init (&R); _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, - ecc_get_nbits (keyparms)); + (nbits = ecc_get_nbits (keyparms))); /* Look for flags. */ l1 = sexp_find_token (keyparms, "flags", 0); @@ -1565,6 +1567,9 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) if (rc) goto leave; + if (DBG_CIPHER) + log_printpnt ("ecc_decrypt kG", &kG, NULL); + /* R = dkG */ _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec); @@ -1588,7 +1593,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) unsigned char *rawmpi; unsigned int rawmpilen; - rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL); if (!rawmpi) { @@ -1598,6 +1603,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) else { rawmpi[0] = 0x40; + rawmpilen++; r = mpi_new (0); mpi_set_opaque (r, rawmpi, rawmpilen*8); } ----------------------------------------------------------------------- Summary of changes: cipher/ecc-misc.c | 21 ++++++++++++--------- cipher/ecc.c | 24 +++++++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 2 09:33:22 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 02 Feb 2016 09:33:22 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-309-g48ba5a5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 48ba5a50066611ecacea850ced13f5cb66097a81 (commit) from a2f9afcd7fcdafd5951498b07f34957f9766dce9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 48ba5a50066611ecacea850ced13f5cb66097a81 Author: NIIBE Yutaka Date: Tue Feb 2 17:24:10 2016 +0900 ecc: more fix of Curve25519. * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix removing of prefix. Clear the MSB, according to RFC7748. -- This change fixes two things. * Handle the case the prefix 0x40 comes at the end when scanned as standard MPI. * Implement MSB handling. In the page 7 of RFC7748, it says about decoding u-coordinate: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 33af6f7..e0dfec3 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -342,10 +342,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) * Only when it's the prefix, we remove it. */ if (rawmpilen > nbytes) - {/* Prefix 0x40 or 0x00 */ - rawmpi++; - rawmpilen = nbytes; - } + /* Prefix 0x40 or 0x00, which comes at the end (reverse) */ + rawmpilen = nbytes; else if (rawmpilen < nbytes) {/* * It is possible for data created by older implementation @@ -364,6 +362,7 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) } } + rawmpi[0] &= (1 << (ctx->nbits % 8)) - 1; _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0); xfree (a); mpi_set_ui (result->z, 1); ----------------------------------------------------------------------- Summary of changes: cipher/ecc-misc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 2 11:53:30 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 02 Feb 2016 11:53:30 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-8-g75311cf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 75311cfe18071b94c66121a9785b133b6df345a3 (commit) from 3d952a2fe5da9d84c20d3debdcc1e425b08781c6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 75311cfe18071b94c66121a9785b133b6df345a3 Author: Neal H. Walfield Date: Tue Feb 2 11:50:08 2016 +0100 doc: Note that rngd can also be used to quickly generate insecure keys. * doc/gpg-agent.texi (Agent Options): Add comment to the description of --debug-quick-random that rngd can also be used to quickly generate key. -- Signed-off-by: Neal H. Walfield diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index f4da9cf..5a387d4 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -243,9 +243,15 @@ debugger. This option inhibits the use of the very secure random quality level (Libgcrypt?s @code{GCRY_VERY_STRONG_RANDOM}) and degrades all request down to standard random quality. It is only used for testing and -shall not be used for any production quality keys. This option is +should not be used for any production quality keys. This option is only effective when given on the command line. +On GNU/Linux, another way to quickly generate insecure keys is to use + at command{rngd} to fill the kernel's entropy pool with lower quality +random data. @command{rngd} is typically provided by the + at command{rng-tools} package. It can be run as follows: @samp{sudo +rngd -f -r /dev/urandom}. + @item --debug-pinentry @opindex debug-pinentry This option enables extra debug information pertaining to the ----------------------------------------------------------------------- Summary of changes: doc/gpg-agent.texi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 2 13:17:25 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 02 Feb 2016 13:17:25 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-310-g6cb6df9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 6cb6df9dddac6ad246002b83c2ce0aaa0ecf30e5 (commit) from 48ba5a50066611ecacea850ced13f5cb66097a81 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6cb6df9dddac6ad246002b83c2ce0aaa0ecf30e5 Author: NIIBE Yutaka Date: Tue Feb 2 20:58:04 2016 +0900 ecc: Fix Curve25519 for data by older implementation. * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix code path for short length data. -- Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index e0dfec3..8f7b8c4 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -292,7 +292,6 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) { - unsigned char *a; unsigned char *rawmpi; unsigned int rawmpilen; @@ -312,8 +311,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) buf++; } - a = rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); - if (!a) + rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); + if (!rawmpi) return gpg_err_code_from_syserror (); p = rawmpi + rawmpilen; @@ -324,8 +323,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) { unsigned int nbytes = (ctx->nbits+7)/8; - a = rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL); - if (!a) + rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL); + if (!rawmpi) return gpg_err_code_from_syserror (); /* * It is not reliable to assume that 0x40 means the prefix. @@ -341,30 +340,29 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) * So, we need to check if it's really the prefix or not. * Only when it's the prefix, we remove it. */ - if (rawmpilen > nbytes) - /* Prefix 0x40 or 0x00, which comes at the end (reverse) */ - rawmpilen = nbytes; - else if (rawmpilen < nbytes) + if (pk->nlimbs * BYTES_PER_MPI_LIMB < nbytes) {/* * It is possible for data created by older implementation * to have shorter length when it was parsed as MPI. */ - rawmpi = xtrymalloc (nbytes); - if (!rawmpi) - { - gpg_err_code_t err = gpg_err_code_from_syserror (); - xfree (a); - return err; - } - - memset (rawmpi, 0, nbytes - rawmpilen); - memcpy (rawmpi + nbytes - rawmpilen, a, rawmpilen); + unsigned int len = pk->nlimbs * BYTES_PER_MPI_LIMB; + + memmove (rawmpi + nbytes - len, rawmpi, len); + memset (rawmpi, 0, nbytes - len); } + + /* + * When we have the prefix (0x40 or 0x00), it comes at the end, + * since it is taken by _gcry_mpi_get_buffer with little endian. + * Just setting RAWMPILEN to NBYTES is enough in this case. + * Othewise, RAWMPILEN is NBYTES already. + */ + rawmpilen = nbytes; } rawmpi[0] &= (1 << (ctx->nbits % 8)) - 1; _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0); - xfree (a); + xfree (rawmpi); mpi_set_ui (result->z, 1); return 0; ----------------------------------------------------------------------- Summary of changes: cipher/ecc-misc.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 3 04:28:16 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 03 Feb 2016 04:28:16 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-311-gb8b3361 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via b8b3361504950689ef1e779fb3357cecf8a9f739 (commit) from 6cb6df9dddac6ad246002b83c2ce0aaa0ecf30e5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b8b3361504950689ef1e779fb3357cecf8a9f739 Author: NIIBE Yutaka Date: Wed Feb 3 12:24:46 2016 +0900 tests: Add a test for Curve25519. * tests/Makefile.am (tests_bin): Add t-cv25519. * tests/t-cv25519.c: New. -- Signed-off-by: NIIBE Yutaka diff --git a/tests/Makefile.am b/tests/Makefile.am index a5c10dd..d462f30 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -22,7 +22,7 @@ tests_bin = \ version mpitests t-sexp t-convert \ t-mpi-bit t-mpi-point curves t-lock \ prime basic keygen pubkey hmac hashtest t-kdf keygrip \ - fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519 + fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519 t-cv25519 tests_bin_last = benchmark bench-slope diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c new file mode 100644 index 0000000..69aa005 --- /dev/null +++ b/tests/t-cv25519.c @@ -0,0 +1,568 @@ +/* t-cv25519.c - Check the cv25519 crypto + * Copyright (C) 2016 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "../src/gcrypt-int.h" + +#include "stopwatch.h" + +#define PGM "t-cv25519" +#define N_TESTS 6 + +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +#define xmalloc(a) gcry_xmalloc ((a)) +#define xcalloc(a,b) gcry_xcalloc ((a),(b)) +#define xstrdup(a) gcry_xstrdup ((a)) +#define xfree(a) gcry_free ((a)) +#define pass() do { ; } while (0) + +static int verbose; +static int debug; +static int error_count; + +static void +print_mpi (const char *text, gcry_mpi_t a) +{ + gcry_error_t err; + char *buf; + void *bufaddr = &buf; + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); + if (err) + fprintf (stderr, "%s: [error printing number: %s]\n", + text, gpg_strerror (err)); + else + { + fprintf (stderr, "%s: %s\n", text, buf); + gcry_free (buf); + } +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + if (*format && format[strlen(format)-1] != '\n') + putc ('\n', stderr); + exit (1); +} + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + /* if (wherestr) */ + /* fprintf (stderr, "%s: ", wherestr); */ + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + if (*format && format[strlen(format)-1] != '\n') + putc ('\n', stderr); + error_count++; + if (error_count >= 50) + die ("stopped after 50 errors."); +} + +static void +show (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose) + return; + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + if (*format && format[strlen(format)-1] != '\n') + putc ('\n', stderr); + va_end (arg_ptr); +} + + +static void +show_note (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose && getenv ("srcdir")) + fputs (" ", stderr); /* To align above "PASS: ". */ + else + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + if (*format && format[strlen(format)-1] != '\n') + putc ('\n', stderr); + va_end (arg_ptr); +} + + +/* Convert STRING consisting of hex characters into its binary + representation and return it as an allocated buffer. The valid + length of the buffer is returned at R_LENGTH. The string is + delimited by end of string. The function returns NULL on + error. */ +static void * +hex2buffer (const char *string, size_t *r_length) +{ + const char *s; + unsigned char *buffer; + size_t length; + + buffer = xmalloc (strlen(string)/2+1); + length = 0; + for (s=string; *s; s +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return NULL; /* Invalid hex digits. */ + ((unsigned char*)buffer)[length++] = xtoi_2 (s); + } + *r_length = length; + return buffer; +} + +static void +reverse_buffer (unsigned char *buffer, unsigned int length) +{ + unsigned int tmp, i; + + for (i=0; i < length/2; i++) + { + tmp = buffer[i]; + buffer[i] = buffer[length-1-i]; + buffer[length-1-i] = tmp; + } +} + + +/* + * Test X25519 functionality through higher layer crypto routines. + * + * Input: K (as hex string), U (as hex string), R (as hex string) + * + * where R is expected result of X25519 (K, U). + * + * It calls gcry_pk_decrypt with Curve25519 private key and let + * it compute X25519. + */ +static void +test_cv (int testno, const char *k_str, const char *u_str, + const char *result_str) +{ + gpg_error_t err; + void *buffer = NULL; + size_t buflen; + unsigned char *p; + gcry_sexp_t s_sk = NULL; + gcry_sexp_t s_data = NULL; + gcry_sexp_t s_result = NULL; + gcry_sexp_t s_tmp = NULL; + unsigned char *res = NULL; + size_t res_len; + + if (verbose > 1) + show ("Running test %d\n", testno); + + if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) + { + fail ("error building s-exp for test %d, %s: %s", + testno, "k", "invalid hex string"); + goto leave; + } + + /* + * Do what decodeScalar25519 does. + */ + p = (unsigned char *)buffer; + p[0] &= 248; + p[31] &= 127; + p[31] |= 64; + reverse_buffer (buffer, buflen); + + if ((err = gcry_sexp_build (&s_sk, NULL, + "(private-key" + " (ecc" + " (curve \"Curve25519\")" + " (flags djb-tweak)" + " (d %b)))", (int)buflen, buffer))) + { + fail ("error building s-exp for test %d, %s: %s", + testno, "sk", gpg_strerror (err)); + goto leave; + } + + xfree (buffer); + if (!(buffer = hex2buffer (u_str, &buflen))) + { + fail ("error building s-exp for test %d, %s: %s", + testno, "u", "invalid hex string"); + goto leave; + } + + /* + * The procedure of decodeUCoordinate will be done internally + * by _gcry_ecc_mont_decodepoint. So, we just put the little-endian + * binary to build S-exp. + * + * We could add the prefix 0x40, but libgcrypt also supports + * format with no prefix. So, it is OK not to put the prefix. + */ + if ((err = gcry_sexp_build (&s_data, NULL, + "(enc-val" + " (ecdh" + " (e %b)))", (int)buflen, buffer))) + { + fail ("error building s-exp for test %d, %s: %s", + testno, "data", gpg_strerror (err)); + goto leave; + } + + xfree (buffer); + buffer = NULL; + + if ((err = gcry_pk_decrypt (&s_result, s_data, s_sk))) + fail ("gcry_pk_decrypt failed for test %d: %s", testno, + gpg_strerror (err)); + + s_tmp = gcry_sexp_find_token (s_result, "value", 0); + if (!s_tmp || !(res = gcry_sexp_nth_buffer (s_tmp, 1, &res_len))) + fail ("gcry_pk_decrypt failed for test %d: %s", testno, "missing value"); + else + { + char *r, *r0; + int i; + + /* To skip the prefix 0x40, for-loop start with i=1 */ + r0 = r = xmalloc (2*(res_len)+1); + if (!r0) + { + fail ("memory allocation", testno); + goto leave; + } + + for (i=1; i < res_len; i++, r += 2) + snprintf (r, 3, "%02x", res[i]); + if (strcmp (result_str, r0)) + { + fail ("gcry_pk_decrypt failed for test %d: %s", + testno, "wrong value returned"); + show (" expected: '%s'", result_str); + show (" got: '%s'", r0); + } + xfree (r0); + } + + leave: + xfree (res); + gcry_sexp_release (s_tmp); + gcry_sexp_release (s_result); + gcry_sexp_release (s_data); + gcry_sexp_release (s_sk); + xfree (buffer); +} + +/* + * Test iterative X25519 computation through lower layer MPI routines. + * + * Input: K (as hex string), ITER, R (as hex string) + * + * where R is expected result of iterating X25519 by ITER times. + * + */ +static void +test_it (int testno, const char *k_str, int iter, const char *result_str) +{ + gcry_ctx_t ctx; + gpg_error_t err; + void *buffer = NULL; + size_t buflen; + gcry_mpi_t mpi_k = NULL; + gcry_mpi_t mpi_x = NULL; + gcry_mpi_point_t P = NULL; + gcry_mpi_point_t Q; + int i; + gcry_mpi_t mpi_kk = NULL; + + if (verbose > 1) + show ("Running test %d: iteration=%d\n", testno, iter); + + gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); + Q = gcry_mpi_point_new (0); + + if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) + { + fail ("error scanning MPI for test %d, %s: %s", + testno, "k", "invalid hex string"); + goto leave; + } + reverse_buffer (buffer, buflen); + if ((err = gcry_mpi_scan (&mpi_x, GCRYMPI_FMT_USG, buffer, buflen, NULL))) + { + fail ("error scanning MPI for test %d, %s: %s", + testno, "x", gpg_strerror (err)); + goto leave; + } + + xfree (buffer); + buffer = NULL; + + P = gcry_mpi_point_set (NULL, mpi_x, NULL, GCRYMPI_CONST_ONE); + + mpi_k = gcry_mpi_copy (mpi_x); + if (debug) + print_mpi ("k", mpi_k); + + for (i = 0; i < iter; i++) + { + /* + * Another variant of decodeScalar25519 thing. + */ + mpi_kk = gcry_mpi_set (mpi_kk, mpi_k); + gcry_mpi_set_bit (mpi_kk, 254); + gcry_mpi_clear_bit (mpi_kk, 255); + gcry_mpi_clear_bit (mpi_kk, 0); + gcry_mpi_clear_bit (mpi_kk, 1); + gcry_mpi_clear_bit (mpi_kk, 2); + + gcry_mpi_ec_mul (Q, mpi_kk, P, ctx); + + P = gcry_mpi_point_set (P, mpi_k, NULL, GCRYMPI_CONST_ONE); + gcry_mpi_ec_get_affine (mpi_k, NULL, Q, ctx); + + if (debug) + print_mpi ("k", mpi_k); + } + + { + unsigned char res[32]; + char *r, *r0; + + gcry_mpi_print (GCRYMPI_FMT_USG, res, 32, NULL, mpi_k); + reverse_buffer (res, 32); + + r0 = r = xmalloc (65); + if (!r0) + { + fail ("memory allocation", testno); + goto leave; + } + + for (i=0; i < 32; i++, r += 2) + snprintf (r, 3, "%02x", res[i]); + + if (strcmp (result_str, r0)) + { + fail ("curv25519 failed for test %d: %s", + testno, "wrong value returned"); + show (" expected: '%s'", result_str); + show (" got: '%s'", r0); + } + xfree (r0); + } + + leave: + gcry_mpi_release (mpi_kk); + gcry_mpi_release (mpi_k); + gcry_mpi_point_release (P); + gcry_mpi_release (mpi_x); + xfree (buffer); + gcry_mpi_point_release (Q); + gcry_ctx_release (ctx); +} + +/* + * X-coordinate of generator of the Curve25519. + */ +#define G_X "0900000000000000000000000000000000000000000000000000000000000000" + +/* + * Test Diffie-Hellman in RFC-7748. + * + * Note that it's not like the ECDH of OpenPGP, where we use + * ephemeral public key. + */ +static void +test_dh (int testno, const char *a_priv_str, const char *a_pub_str, + const char *b_priv_str, const char *b_pub_str, + const char *result_str) +{ + /* Test A for private key corresponds to public key. */ + test_cv (testno, a_priv_str, G_X, a_pub_str); + /* Test B for private key corresponds to public key. */ + test_cv (testno, b_priv_str, G_X, b_pub_str); + /* Test DH with A's private key and B's public key. */ + test_cv (testno, a_priv_str, b_pub_str, result_str); + /* Test DH with B's private key and A's public key. */ + test_cv (testno, b_priv_str, a_pub_str, result_str); +} + + +static void +check_cv25519 (void) +{ + int ntests; + + show ("Checking Curve25519.\n"); + + ntests = 0; + + /* + * Values are cited from RFC-7748: 5.2. Test Vectors. + * Following two tests are for the first type test. + */ + test_cv (1, + "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4", + "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c", + "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552"); + ntests++; + test_cv (2, + "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d", + "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493", + "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957"); + ntests++; + + /* + * Additional test. Value is from second type test. + */ + test_cv (3, + G_X, + G_X, + "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079"); + ntests++; + + /* + * Following two tests are for the second type test, + * with one iteration and 1,000 iterations. (1,000,000 iterations + * takes too long.) + */ + test_it (4, + G_X, + 1, + "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079"); + ntests++; + + test_it (5, + G_X, + 1000, + "684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51"); + ntests++; + + /* + * Last test is from: 6. Diffie-Hellman, 6.1. Curve25519 + */ + test_dh (6, + /* Alice's private key, a */ + "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", + /* Alice's public key, X25519(a, 9) */ + "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a", + /* Bob's private key, b */ + "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb", + /* Bob's public key, X25519(b, 9) */ + "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", + /* Their shared secret, K */ + "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"); + ntests++; + + if (ntests != N_TESTS) + fail ("did %d tests but expected %d", ntests, N_TESTS); + else if ((ntests % 256)) + show_note ("%d tests done\n", ntests); +} + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + fputs ("usage: " PGM " [options]\n" + "Options:\n" + " --verbose print timings etc.\n" + " --debug flyswatter\n", + stdout); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose += 2; + debug++; + argc--; argv++; + } + else if (!strncmp (*argv, "--", 2)) + die ("unknown option '%s'", *argv); + } + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + start_timer (); + check_cv25519 (); + stop_timer (); + + show ("All tests completed in %s. Errors: %d\n", + elapsed_time (1), error_count); + return !!error_count; +} ----------------------------------------------------------------------- Summary of changes: tests/Makefile.am | 2 +- tests/t-cv25519.c | 568 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 569 insertions(+), 1 deletion(-) create mode 100644 tests/t-cv25519.c hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 6 12:36:54 2016 From: cvs at cvs.gnupg.org (by Robert J. Hansen) Date: Sat, 06 Feb 2016 12:36:54 +0100 Subject: [git] gnupg-doc - branch, master, updated. ea11224852b7f39693b9ea5283eb97da7b345d51 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via ea11224852b7f39693b9ea5283eb97da7b345d51 (commit) from 17c0063e220c2f49c5abd42c01499ec2ec30a70d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ea11224852b7f39693b9ea5283eb97da7b345d51 Author: Robert J. Hansen Date: Sat Feb 6 06:36:43 2016 -0500 Typo fixes, mostly thanks to Ineiev of the FSF. diff --git a/web/faq/gnupg-faq.org b/web/faq/gnupg-faq.org index fe08967..f6e06bf 100644 --- a/web/faq/gnupg-faq.org +++ b/web/faq/gnupg-faq.org @@ -76,10 +76,18 @@ aren't, please feel free to email the FAQ maintainer (Rob Hansen, [[mailto:rjh at sixdemonbag.org?subject=The%20GnuPG%20FAQ][rjh at sixdemonbag.org]]) or bring your suggestion up on GnuPG-Users. +** Is this available in other languages? + :PROPERTIES: + :CUSTOM ID: translations + :END: + +Thanks to the Free Software Foundation, this FAQ is also available in +[[http:// + ** How do I get help? :PROPERTIES: :CUSTOM ID: gethelp - :END + :END: First, please don?t send emails directly to people in GnuPG. While we will try to help to people who send email directly to us, those emails quickly @@ -90,7 +98,7 @@ GnuPG community via the not individual people within GnuPG. -Second, tell us your operating environment. Be as specific as possible +Second, tell us your operating environment. Be as specific as possible. What operating system are you using? Which version of GnuPG are you using? Where did you get GnuPG from? If your problem is related to email, which email client are you using? Which version number? Is GnuPG supported natively, or @@ -140,7 +148,7 @@ Yes. :CUSTOM_ID: last_checked :END: -December 2015. +February 2016. * General questions @@ -651,7 +659,7 @@ although in a different way than the EFF. Many email clients offer strong GnuPG integration. The column ?Active? in the tables below indicate whether the software -os actively developed. +is actively developed. ** ? Microsoft Windows? :PROPERTIES: @@ -665,7 +673,7 @@ os actively developed. | Claws-Mail | yes (internal) | (3) | (1) With the Enigmail plugin, Thunderbird becomes one of the most - popular GnuPG-aware email clients. it?s under active development + popular GnuPG-aware email clients. It?s under active development and is compatible with the latest Thunderbird releases, with a friendly and welcoming user community. @@ -1080,7 +1088,7 @@ compressed. :END: -A revocation certificate is a [[#define_key][certificate]] that possesses the +A revocation certificate is a [[#define_certificate][certificate]] that possesses the information necessary to mark another certificate as unusable. This is called ?revoking? the certificate. @@ -1307,14 +1315,12 @@ keyserver pool.sks-keyservers.net keyserver-options import-clean-sigs import-clean-uids export-clean-sigs export-clean-uids # If I don't explicitly state which certificate to use, use this one. -default-key 23806BE5D6B98E10 +default-key 1DCBDC01B44427C7 # Always include signatures from these two certificates. -local-user 23806BE5D6B98E10 local-user 1DCBDC01B44427C7 # Always add these two certificates to my recipients list. -encrypt-to 23806BE5D6B98E10 encrypt-to 1DCBDC01B44427C7 # Turn "From" into "> From", in order to play nice with UNIX mailboxes. @@ -1340,8 +1346,8 @@ personal-compress-preferences BZIP2 ZIP ZLIB :END: -Many people have had excellent luck with =pool.sks-keyservers.net=. - +Many people have had excellent luck with =pool.sks-keyservers.net=. On OS X, +some people have needed to use =ipv4.pool.sks-keyservers.net= instead. ** What?s the difference between an ?option? and a ?command?? @@ -1400,7 +1406,7 @@ A variation is =-b= or =--detach-sign=, which produces a separate signature without including the file's content; this is useful for signing a software archive or other large file. The key to use for the signature can be specified with the =local-user= setting in your -gpg.conf file, or with the =-u=, =--local-user= options. +=gpg.conf= file, or with the =-u=, =--local-user= options. Encrypting a file's content is done with the =-e= or =--encrypt= commands. Recipients are specified with the =-r= or =--recipient= @@ -1422,7 +1428,7 @@ keys and the certificates of others. :END: In order to send an encrypted message or verify a signature, you must -obtain the certificate for the sender/signer's public key. +obtain the certificate for the recipient?s/signer?s public key. Occasionally you might obtain the certificate physically, by meeting the certificate holder face-to-face and exchanging the certificate on ----------------------------------------------------------------------- Summary of changes: web/faq/gnupg-faq.org | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 6 12:40:04 2016 From: cvs at cvs.gnupg.org (by Robert J. Hansen) Date: Sat, 06 Feb 2016 12:40:04 +0100 Subject: [git] gnupg-doc - branch, master, updated. 6d24f421b59488615fae999740f495281c4f741e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 6d24f421b59488615fae999740f495281c4f741e (commit) from ea11224852b7f39693b9ea5283eb97da7b345d51 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6d24f421b59488615fae999740f495281c4f741e Author: Robert J. Hansen Date: Sat Feb 6 06:39:55 2016 -0500 Bungled a URL for the Russian translation. Whoops. Fixed now. diff --git a/web/faq/gnupg-faq.org b/web/faq/gnupg-faq.org index f6e06bf..5b0535f 100644 --- a/web/faq/gnupg-faq.org +++ b/web/faq/gnupg-faq.org @@ -82,7 +82,7 @@ or bring your suggestion up on GnuPG-Users. :END: Thanks to the Free Software Foundation, this FAQ is also available in -[[http:// +[[https://www.gnu.org/server/standards/translations/ru/gnupg/gnupg-faq.ru.html][Russian]]. ** How do I get help? :PROPERTIES: ----------------------------------------------------------------------- Summary of changes: web/faq/gnupg-faq.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 8 01:37:05 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Mon, 08 Feb 2016 01:37:05 +0100 Subject: [git] GnuPG - branch, neal/encrypted-mailing-lists, updated. gnupg-2.1.11-13-ge2bde0a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, neal/encrypted-mailing-lists has been updated via e2bde0a1dcef0d96b767a935ab95aa2ee1eb98ac (commit) from fd7dc535f3104e521eb49d95d2bb180cd0e8a9af (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e2bde0a1dcef0d96b767a935ab95aa2ee1eb98ac Author: Neal H. Walfield Date: Mon Feb 8 01:36:57 2016 +0100 Add a small test and a bit of user documentation. diff --git a/mailing-list-test/README b/mailing-list-test/README new file mode 100644 index 0000000..1d2c366 --- /dev/null +++ b/mailing-list-test/README @@ -0,0 +1,70 @@ +After making sure a gpg2 with mailing list support is in your patch, +run test.sh as follows (when you run it, it will ask for two +passwords, use the password 'a'): + + # ./test.sh + *************** + Generating a user key (use a password of 'a'). + *************** + 'Some User ' + + *************** + Importing some public keys. + Running: gpg2 --batch --import keys.gpg + *************** + + *************** + Set the password to 'a' + *************** + + *************** + Creating mailing list. + Running: gpg2 --batch --quick-gen-mailing-list-key gnupg-devel + *************** + 'gnupg-devel ' + + ... + +To get more verbose output, run test.sh with the -v flag. To get even +more output, change the gpg2 invocations to include --debug=packet. + +A summary of the commands: + + --mailing-list-key-gen + --quick-gen-mailing-list-key 'Name ' + + Create a new mailing list key. + + --mailing-list-add-sub ML-KEYID SUB-KEYID... + --mailing-list-add-rm ML-KEYID SUB-KEYID... + + Add or remove one or more subscribers from the mailing list. + + --mailing-list-subs ML-KEYID + + List the subscribers (using their decryted keyids!) + + Compare: + + $ gpg2 -k 2A08A54D + pub rsa2048/2A08A54D 2016-02-08 [SC] + uid [ultimate] gnupg-devel (mailing list) + sub rsa2048/ED2D0863 2016-02-08 [E] + sub rsa2/7C03B9E1 2016-02-08 [E] + sub rsa2/83BCEFE4 2016-02-08 [E] + sub rsa2/04A1E753 2016-02-08 [E] + sub rsa2/535EB487 2016-02-08 [E] + + The above 2-bit RSA keys! These are the encrypted keys. Here are + the real subscribers: + + $ gpg2 --mailing-list-subs 2A08A54D + D1B030E3 + AA45C71F + 94244910 + 95A0BEEA + 4 subscribers. + +To encrypt to a mailing list, just do: gpg2 -r ML-KEYID -e and a gnupg +with encrypted mailing list support will automatically encrypt to the +list of current subscribers. diff --git a/mailing-list-test/keys.gpg b/mailing-list-test/keys.gpg new file mode 100644 index 0000000..12831dd --- /dev/null +++ b/mailing-list-test/keys.gpg @@ -0,0 +1,621 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +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 +=l1Ul +-----END PGP PUBLIC KEY BLOCK----- diff --git a/mailing-list-test/test.sh b/mailing-list-test/test.sh new file mode 100755 index 0000000..fbe1cdd --- /dev/null +++ b/mailing-list-test/test.sh @@ -0,0 +1,238 @@ +#! /bin/bash + +set -e +# set -x + +if ! test -e mailing-list +then + echo "Are you sure you are in the right directory?" + exit 1 +fi + +set +e +TEMP=$(getopt \ + --longoptions verbose \ + -o v \ + -n "${0##*/}" -- "$@") +EC=$? +set -e +if test $EC != 0 +then + echo "Try \`$0 --help' for more information." + exit 1 +fi +eval set -- "$TEMP" + +VERBOSE=0 +while true +do + case "$1" in + --verbose|-v) VERBOSE=1; shift;; + --) shift; break;; + *) echo 'Internal error!'; exit 1;; + esac +done + +banner() { + echo + echo "***************" + echo -e "$@" + echo "***************" +} + +GPG() { + # valgrind gpg2 "$@" + if test x"$VERBOSE" = x1 + then + gpg2 --no-permission-warning "$@" + else + gpg2 --no-permission-warning "$@" 2>/dev/null + fi +} + +GPGU() { + GNUPGHOME=`pwd`/user GPG "$@" +} + +SETPASSWD() { + keyids=$(gpg2 --no-permission-warning -K --with-keygrip --with-colons 2>/dev/null \ + | gawk -F: '/^grp/ { print $10; }') + if test x$KEYID != x + then + for keygrip in $keyids + do + /usr/lib/gnupg2/gpg-preset-passphrase \ + --preset -P a "$keygrip" + done + fi +} + +TEST() +{ + TEXT="$1" + shift + banner "$TEXT\n Running: gpg2 $@" + + if GPG "$@" + then + : + else + EC=$? + echo "FAIL! (exit code: $EC)" + exit $EC + fi +} + +XTEST() +{ + TEXT="$1" + shift + banner "$TEXT\n Running: gpg2 $@" + + if GPG "$@" + then + echo "UNEXPECTEDLY PASSED!" + exit 1 + fi +} + +# Be sure to clean up. +cleanup() { + rm -f "mailing-list/subs-expected.$KEYID" "mailing-list/subs-have.$KEYID" +} +trap cleanup EXIT + +CHECKLIST() { + for x in $@ + do + echo $x + done | sort > "mailing-list/subs-expected.$KEYID" + + if ! cmp "mailing-list/subs-have.$KEYID" \ + "mailing-list/subs-expected.$KEYID" + then + echo "Current subscriber list does not match expected subscriber list!" + diff -u "mailing-list/subs-expected.$KEYID" \ + "mailing-list/subs-have.$KEYID" + exit 1 + fi +} + +CHECKSUBS() { + GPG --mailing-list-subs $KEYID | grep -v subscribers \ + | sort > "mailing-list/subs-have.$KEYID" + + CHECKLIST "$@" +} + +export GNUPGHOME=`pwd`/mailing-list +unset KEYID + +# Kill any running agent. +gpgconf --kill gpg-agent + +# Rebuild the directory. +rm -rf mailing-list +mkdir mailing-list + +cat >$GNUPGHOME/gpg-agent.conf <$GNUPGHOME/gpg.conf <' + +UKEYID=$(GPGU -K --with-colons | gawk -F: '/^sec/ { print $5 }') +if test "x$UKEYID" = x +then + echo "Failed to figure out the keyid of the user's primary key." + exit 1 +fi +# We need the short keyid. +UEKEYID=$(GPGU -K --with-colons | gawk -F: '/^ssb/ { print $5 }' \ + | sed 's/^.\{8\}//') +if test "x$UKEYID" = x +then + echo "Failed to figure out the keyid of the user's encryption key." + exit 1 +fi + + +# CFEFE77F (encryption subkey: 2B6E7103) +# A9316686 (95A0BEEA) +# E29FC3CC (117E1AFB) +# 5C1A4468 (94244910) +# F462B6B1 (AA45C71F) +TEST "Importing some public keys." --batch --import keys.gpg +GPGU --batch --export $UKEYID | GPG --batch --import + +banner "Set the password to 'a'" +TEST "Creating mailing list." \ + --batch --quick-gen-mailing-list-key "gnupg-devel " + +KEYID=$(GPG -K --with-colons | gawk -F: '/^sec/ { print $5 }') +if test "x$KEYID" = x +then + echo "Failed to figure out the keyid of the ML's primary key." + exit 1 +fi +SETPASSWD + +TEST "Adding a subscriber." --mailing-list-add-sub $KEYID CFEFE77F +CHECKSUBS 2B6E7103 + +XTEST "Adding the same subscriber." --mailing-list-add-sub $KEYID CFEFE77F + +TEST "Adding two subscribers." --mailing-list-add-sub $KEYID A9316686 E29FC3CC +CHECKSUBS 117E1AFB 2B6E7103 95A0BEEA + +TEST "Removing a subscriber." --mailing-list-rm-sub $KEYID 117E1AFB +# We need to wait a second, otherwise the key may not yet be +# recognized as expired. +sleep 1 +CHECKSUBS 2B6E7103 95A0BEEA + +TEST "Adding a subscriber." --mailing-list-add-sub $KEYID 5C1A4468 +GPG --mailing-list-subs $KEYID | grep -v subscribers | sort > subs +CHECKSUBS 2B6E7103 94244910 95A0BEEA + +TEST "Removing a subscriber." --mailing-list-rm-sub $KEYID 2B6E7103 +sleep 1 +CHECKSUBS 94244910 95A0BEEA + +TEST "Adding a subscriber." --mailing-list-add-sub $KEYID F462B6B1 +CHECKSUBS AA45C71F 94244910 95A0BEEA + +TEST "Adding a subscriber." --mailing-list-add-sub $KEYID $UKEYID +CHECKSUBS AA45C71F 94244910 95A0BEEA $UEKEYID + +GPG --batch --export $KEYID | GPGU --batch --import + +GNUPGHOME=`pwd`/user SETPASSWD + +banner "Using subscriber's key to list subscribers" +GPGU --try-secret-key $UKEYID --mailing-list-subs $KEYID \ + | grep -v subscribers | sort > mailing-list/subs-have.$KEYID +CHECKLIST AA45C71F 94244910 95A0BEEA $UEKEYID + +banner "Using subscriber's key to send a message" +# Note: --list-packets uses long keyids. +echo | GPGU --trust-model=always --try-secret-key $UKEYID -r $KEYID -e \ + | GPGU --list-packets \ + | gawk '/pubkey enc packet/ { print $9 }' \ + | sed 's/^.\{8\}//' \ + | sort > mailing-list/subs-have.$KEYID +CHECKLIST AA45C71F 94244910 95A0BEEA $UEKEYID + +echo "All tests passed!" + +exit 0 ----------------------------------------------------------------------- Summary of changes: mailing-list-test/README | 70 +++++ mailing-list-test/keys.gpg | 621 +++++++++++++++++++++++++++++++++++++++++++++ mailing-list-test/test.sh | 238 +++++++++++++++++ 3 files changed, 929 insertions(+) create mode 100644 mailing-list-test/README create mode 100644 mailing-list-test/keys.gpg create mode 100755 mailing-list-test/test.sh hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 8 19:16:52 2016 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Mon, 08 Feb 2016 19:16:52 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-312-g8353884 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 8353884bc65c820d5bcacaf1ac23cdee72091a09 (commit) from b8b3361504950689ef1e779fb3357cecf8a9f739 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8353884bc65c820d5bcacaf1ac23cdee72091a09 Author: Jussi Kivilinna Date: Mon Feb 8 20:13:38 2016 +0200 Add ARM assembly implementation of SHA-512 * cipher/Makefile.am: Add 'sha512-arm.S'. * cipher/sha512-arm.S: New. * cipher/sha512.c (USE_ARM_ASM): New. (_gcry_sha512_transform_arm): New. (transform) [USE_ARM_ASM]: Use ARM assembly implementation instead of generic. * configure.ac: Add 'sha512-arm.lo'. -- Benchmark on Cortex-A8 (armv6, 1008 Mhz): Before: | nanosecs/byte mebibytes/sec cycles/byte SHA512 | 112.0 ns/B 8.52 MiB/s 112.9 c/B After (3.3x faster): | nanosecs/byte mebibytes/sec cycles/byte SHA512 | 34.01 ns/B 28.04 MiB/s 34.28 c/B Signed-off-by: Jussi Kivilinna diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 88c8fbf..65d7afb 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -89,7 +89,7 @@ sha1.c sha1-ssse3-amd64.S sha1-avx-amd64.S sha1-avx-bmi2-amd64.S \ sha1-armv7-neon.S \ sha256.c sha256-ssse3-amd64.S sha256-avx-amd64.S sha256-avx2-bmi2-amd64.S \ sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S sha512-avx2-bmi2-amd64.S \ - sha512-armv7-neon.S \ + sha512-armv7-neon.S sha512-arm.S \ keccak.c keccak_permute_32.h keccak_permute_64.h keccak-armv7-neon.S \ stribog.c \ tiger.c \ diff --git a/cipher/sha512-arm.S b/cipher/sha512-arm.S new file mode 100644 index 0000000..28f156e --- /dev/null +++ b/cipher/sha512-arm.S @@ -0,0 +1,465 @@ +/* sha512-arm.S - ARM assembly implementation of SHA-512 transform + * + * Copyright (C) 2016 Jussi Kivilinna + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ +#include + +#if defined(__ARMEL__) +#ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS + +.text + +.syntax unified +.arm + +/* structure of SHA512_CONTEXT */ +#define hd_a 0 +#define hd_b ((hd_a) + 8) +#define hd_c ((hd_b) + 8) +#define hd_d ((hd_c) + 8) +#define hd_e ((hd_d) + 8) +#define hd_f ((hd_e) + 8) +#define hd_g ((hd_f) + 8) +#define hd_h ((hd_g) + 8) + +/* register macros */ +#define RK %r2 + +#define RElo %r0 +#define REhi %r1 + +#define RT1lo %r3 +#define RT1hi %r4 +#define RT2lo %r5 +#define RT2hi %r6 +#define RWlo %r7 +#define RWhi %r8 +#define RT3lo %r9 +#define RT3hi %r10 +#define RT4lo %r11 +#define RT4hi %ip + +#define RRND %lr + +/* variable offsets in stack */ +#define ctx (0) +#define data ((ctx) + 4) +#define nblks ((data) + 4) +#define _a ((nblks) + 4) +#define _b ((_a) + 8) +#define _c ((_b) + 8) +#define _d ((_c) + 8) +#define _e ((_d) + 8) +#define _f ((_e) + 8) +#define _g ((_f) + 8) +#define _h ((_g) + 8) + +#define w(i) ((_h) + 8 + ((i) % 16) * 8) + +#define STACK_MAX (w(15) + 8) + +/* helper macros */ +#define ldr_unaligned_be(rout, rsrc, offs, rtmp) \ + ldrb rout, [rsrc, #((offs) + 3)]; \ + ldrb rtmp, [rsrc, #((offs) + 2)]; \ + orr rout, rout, rtmp, lsl #8; \ + ldrb rtmp, [rsrc, #((offs) + 1)]; \ + orr rout, rout, rtmp, lsl #16; \ + ldrb rtmp, [rsrc, #((offs) + 0)]; \ + orr rout, rout, rtmp, lsl #24; + +#ifdef __ARMEL__ + /* bswap on little-endian */ +#ifdef HAVE_ARM_ARCH_V6 + #define be_to_host(reg, rtmp) \ + rev reg, reg; +#else + #define be_to_host(reg, rtmp) \ + eor rtmp, reg, reg, ror #16; \ + mov rtmp, rtmp, lsr #8; \ + bic rtmp, rtmp, #65280; \ + eor reg, rtmp, reg, ror #8; +#endif +#else + /* nop on big-endian */ + #define be_to_host(reg, rtmp) /*_*/ +#endif + +#define host_to_host(x, y) /*_*/ + +#define read_u64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, convert, rtmp) \ + ldr lo0, [rin, #((offs) + 0 * 8 + 4)]; \ + ldr hi0, [rin, #((offs) + 0 * 8 + 0)]; \ + ldr lo1, [rin, #((offs) + 1 * 8 + 4)]; \ + ldr hi1, [rin, #((offs) + 1 * 8 + 0)]; \ + ldr lo2, [rin, #((offs) + 2 * 8 + 4)]; \ + convert(lo0, rtmp); \ + ldr hi2, [rin, #((offs) + 2 * 8 + 0)]; \ + convert(hi0, rtmp); \ + ldr lo3, [rin, #((offs) + 3 * 8 + 4)]; \ + convert(lo1, rtmp); \ + ldr hi3, [rin, #((offs) + 3 * 8 + 0)]; \ + convert(hi1, rtmp); \ + convert(lo2, rtmp); \ + convert(hi2, rtmp); \ + convert(lo3, rtmp); \ + convert(hi3, rtmp); + +#define read_be64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, rtmp0) \ + read_u64_aligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, be_to_host, rtmp0) + +/* need to handle unaligned reads by byte reads */ +#define read_be64_unaligned_4(rin, offs, lo0, hi0, lo1, hi1, lo2, hi2, lo3, hi3, rtmp0) \ + ldr_unaligned_be(lo0, rin, (offs) + 0 * 8 + 4, rtmp0); \ + ldr_unaligned_be(hi0, rin, (offs) + 0 * 8 + 0, rtmp0); \ + ldr_unaligned_be(lo1, rin, (offs) + 1 * 8 + 4, rtmp0); \ + ldr_unaligned_be(hi1, rin, (offs) + 1 * 8 + 0, rtmp0); \ + ldr_unaligned_be(lo2, rin, (offs) + 2 * 8 + 4, rtmp0); \ + ldr_unaligned_be(hi2, rin, (offs) + 2 * 8 + 0, rtmp0); \ + ldr_unaligned_be(lo3, rin, (offs) + 3 * 8 + 4, rtmp0); \ + ldr_unaligned_be(hi3, rin, (offs) + 3 * 8 + 0, rtmp0); + +/*********************************************************************** + * ARM assembly implementation of sha512 transform + ***********************************************************************/ + +/* Round function */ + +#define R(_a,_b,_c,_d,_e,_f,_g,_h,W,wi) \ + /* Message expansion, t1 = _h + w[i] */ \ + W(_a,_h,wi); \ + \ + /* w = Sum1(_e) */ \ + mov RWlo, RElo, lsr#14; \ + ldm RK!, {RT2lo-RT2hi}; \ + mov RWhi, REhi, lsr#14; \ + eor RWlo, RWlo, RElo, lsr#18; \ + eor RWhi, RWhi, REhi, lsr#18; \ + ldr RT3lo, [%sp, #(_f)]; \ + adds RT1lo, RT2lo; /* t1 += K */ \ + ldr RT3hi, [%sp, #(_f) + 4]; \ + adc RT1hi, RT2hi; \ + ldr RT4lo, [%sp, #(_g)]; \ + eor RWlo, RWlo, RElo, lsl#23; \ + ldr RT4hi, [%sp, #(_g) + 4]; \ + eor RWhi, RWhi, REhi, lsl#23; \ + eor RWlo, RWlo, REhi, lsl#18; \ + eor RWhi, RWhi, RElo, lsl#18; \ + eor RWlo, RWlo, REhi, lsl#14; \ + eor RWhi, RWhi, RElo, lsl#14; \ + eor RWlo, RWlo, REhi, lsr#9; \ + eor RWhi, RWhi, RElo, lsr#9; \ + \ + /* Cho(_e,_f,_g) => (_e & _f) ^ (~_e & _g) */ \ + adds RT1lo, RWlo; /* t1 += Sum1(_e) */ \ + and RT3lo, RT3lo, RElo; \ + adc RT1hi, RWhi; \ + and RT3hi, RT3hi, REhi; \ + bic RT4lo, RT4lo, RElo; \ + bic RT4hi, RT4hi, REhi; \ + eor RT3lo, RT3lo, RT4lo; \ + eor RT3hi, RT3hi, RT4hi; \ + \ + /* Load D */ \ + /* t1 += Cho(_e,_f,_g) */ \ + ldr RElo, [%sp, #(_d)]; \ + adds RT1lo, RT3lo; \ + ldr REhi, [%sp, #(_d) + 4]; \ + adc RT1hi, RT3hi; \ + \ + /* Load A */ \ + ldr RT3lo, [%sp, #(_a)]; \ + \ + /* _d += t1 */ \ + adds RElo, RT1lo; \ + ldr RT3hi, [%sp, #(_a) + 4]; \ + adc REhi, RT1hi; \ + \ + /* Store D */ \ + str RElo, [%sp, #(_d)]; \ + \ + /* t2 = Sum0(_a) */ \ + mov RT2lo, RT3lo, lsr#28; \ + str REhi, [%sp, #(_d) + 4]; \ + mov RT2hi, RT3hi, lsr#28; \ + ldr RWlo, [%sp, #(_b)]; \ + eor RT2lo, RT2lo, RT3lo, lsl#30; \ + ldr RWhi, [%sp, #(_b) + 4]; \ + eor RT2hi, RT2hi, RT3hi, lsl#30; \ + eor RT2lo, RT2lo, RT3lo, lsl#25; \ + eor RT2hi, RT2hi, RT3hi, lsl#25; \ + eor RT2lo, RT2lo, RT3hi, lsl#4; \ + eor RT2hi, RT2hi, RT3lo, lsl#4; \ + eor RT2lo, RT2lo, RT3hi, lsr#2; \ + eor RT2hi, RT2hi, RT3lo, lsr#2; \ + eor RT2lo, RT2lo, RT3hi, lsr#7; \ + eor RT2hi, RT2hi, RT3lo, lsr#7; \ + \ + /* t2 += t1 */ \ + adds RT2lo, RT1lo; \ + ldr RT1lo, [%sp, #(_c)]; \ + adc RT2hi, RT1hi; \ + \ + /* Maj(_a,_b,_c) => ((_a & _b) ^ (_c & (_a ^ _b))) */ \ + ldr RT1hi, [%sp, #(_c) + 4]; \ + and RT4lo, RWlo, RT3lo; \ + and RT4hi, RWhi, RT3hi; \ + eor RWlo, RWlo, RT3lo; \ + eor RWhi, RWhi, RT3hi; \ + and RWlo, RWlo, RT1lo; \ + and RWhi, RWhi, RT1hi; \ + eor RWlo, RWlo, RT4lo; \ + eor RWhi, RWhi, RT4hi; \ + +/* Message expansion */ + +#define W_0_63(_a,_h,i) \ + ldr RT3lo, [%sp, #(w(i-2))]; \ + adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ \ + ldr RT3hi, [%sp, #(w(i-2)) + 4]; \ + adc RT2hi, RWhi; \ + /* nw = S1(w[i-2]) */ \ + ldr RT1lo, [%sp, #(_h)]; /* Load H */ \ + mov RWlo, RT3lo, lsr#19; \ + str RT2lo, [%sp, #(_a)]; \ + eor RWlo, RWlo, RT3lo, lsl#3; \ + ldr RT1hi, [%sp, #(_h) + 4]; \ + mov RWhi, RT3hi, lsr#19; \ + ldr RT2lo, [%sp, #(w(i-7))]; \ + eor RWhi, RWhi, RT3hi, lsl#3; \ + str RT2hi, [%sp, #(_a) + 4]; \ + eor RWlo, RWlo, RT3lo, lsr#6; \ + ldr RT2hi, [%sp, #(w(i-7)) + 4]; \ + eor RWhi, RWhi, RT3hi, lsr#6; \ + eor RWlo, RWlo, RT3hi, lsl#13; \ + eor RWhi, RWhi, RT3lo, lsl#13; \ + eor RWlo, RWlo, RT3hi, lsr#29; \ + eor RWhi, RWhi, RT3lo, lsr#29; \ + ldr RT3lo, [%sp, #(w(i-15))]; \ + eor RWlo, RWlo, RT3hi, lsl#26; \ + ldr RT3hi, [%sp, #(w(i-15)) + 4]; \ + \ + adds RT2lo, RWlo; /* nw += w[i-7] */ \ + ldr RWlo, [%sp, #(w(i-16))]; \ + adc RT2hi, RWhi; \ + mov RT4lo, RT3lo, lsr#1; /* S0(w[i-15]) */ \ + ldr RWhi, [%sp, #(w(i-16)) + 4]; \ + mov RT4hi, RT3hi, lsr#1; \ + adds RT2lo, RWlo; /* nw += w[i-16] */ \ + eor RT4lo, RT4lo, RT3lo, lsr#8; \ + eor RT4hi, RT4hi, RT3hi, lsr#8; \ + eor RT4lo, RT4lo, RT3lo, lsr#7; \ + eor RT4hi, RT4hi, RT3hi, lsr#7; \ + eor RT4lo, RT4lo, RT3hi, lsl#31; \ + eor RT4hi, RT4hi, RT3lo, lsl#31; \ + eor RT4lo, RT4lo, RT3hi, lsl#24; \ + eor RT4hi, RT4hi, RT3lo, lsl#24; \ + eor RT4lo, RT4lo, RT3hi, lsl#25; \ + adc RT2hi, RWhi; \ + \ + /* nw += S0(w[i-15]) */ \ + adds RT2lo, RT4lo; \ + adc RT2hi, RT4hi; \ + \ + /* w[0] = nw */ \ + str RT2lo, [%sp, #(w(i))]; \ + adds RT1lo, RWlo; \ + str RT2hi, [%sp, #(w(i)) + 4]; \ + adc RT1hi, RWhi; + +#define W_64_79(_a,_h,i) \ + adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ \ + ldr RWlo, [%sp, #(w(i-16))]; \ + adc RT2hi, RWhi; \ + ldr RWhi, [%sp, #(w(i-16)) + 4]; \ + ldr RT1lo, [%sp, #(_h)]; /* Load H */ \ + ldr RT1hi, [%sp, #(_h) + 4]; \ + str RT2lo, [%sp, #(_a)]; \ + str RT2hi, [%sp, #(_a) + 4]; \ + adds RT1lo, RWlo; \ + adc RT1hi, RWhi; + +.align 3 +.globl _gcry_sha512_transform_arm +.type _gcry_sha512_transform_arm,%function; + +_gcry_sha512_transform_arm: + /* Input: + * %r0: SHA512_CONTEXT + * %r1: data + * %r2: u64 k[] constants + * %r3: nblks + */ + push {%r4-%r11, %ip, %lr}; + sub %sp, %sp, #STACK_MAX; + movs RWlo, %r3; + str %r0, [%sp, #(ctx)]; + + beq .Ldone; + +.Loop_blocks: + str RWlo, [%sp, #nblks]; + + /* Load context to stack */ + add RWhi, %sp, #(_a); + ldm %r0!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + ldm %r0, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + stm RWhi, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + /* Load input to w[16] */ +#ifndef __ARM_FEATURE_UNALIGNED + /* test if data is unaligned */ + tst %r1, #3; + beq 1f; + + /* unaligned load */ + add RWhi, %sp, #(w(0)); + read_be64_unaligned_4(%r1, 0 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + read_be64_unaligned_4(%r1, 4 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + read_be64_unaligned_4(%r1, 8 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + read_be64_unaligned_4(%r1, 12 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + b 2f; +#endif +1: + /* aligned load */ + add RWhi, %sp, #(w(0)); + read_be64_aligned_4(%r1, 0 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + read_be64_aligned_4(%r1, 4 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + read_be64_aligned_4(%r1, 8 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); + stm RWhi!, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + + read_be64_aligned_4(%r1, 12 * 8, RT1lo, RT1hi, RT2lo, RT2hi, RT3lo, RT3hi, RT4lo, RT4hi, RWlo); +2: + add %r1, #(16 * 8); + stm RWhi, {RT1lo,RT1hi,RT2lo,RT2hi,RT3lo,RT3hi,RT4lo,RT4hi} + str %r1, [%sp, #(data)]; + + /* preload E & A */ + ldr RElo, [%sp, #(_e)]; + ldr REhi, [%sp, #(_e) + 4]; + mov RWlo, #0; + ldr RT2lo, [%sp, #(_a)]; + mov RRND, #(80-16); + ldr RT2hi, [%sp, #(_a) + 4]; + mov RWhi, #0; + +.Loop_rounds: + R(_a, _b, _c, _d, _e, _f, _g, _h, W_0_63, 16); + R(_h, _a, _b, _c, _d, _e, _f, _g, W_0_63, 17); + R(_g, _h, _a, _b, _c, _d, _e, _f, W_0_63, 18); + R(_f, _g, _h, _a, _b, _c, _d, _e, W_0_63, 19); + R(_e, _f, _g, _h, _a, _b, _c, _d, W_0_63, 20); + R(_d, _e, _f, _g, _h, _a, _b, _c, W_0_63, 21); + R(_c, _d, _e, _f, _g, _h, _a, _b, W_0_63, 22); + R(_b, _c, _d, _e, _f, _g, _h, _a, W_0_63, 23); + R(_a, _b, _c, _d, _e, _f, _g, _h, W_0_63, 24); + R(_h, _a, _b, _c, _d, _e, _f, _g, W_0_63, 25); + R(_g, _h, _a, _b, _c, _d, _e, _f, W_0_63, 26); + R(_f, _g, _h, _a, _b, _c, _d, _e, W_0_63, 27); + R(_e, _f, _g, _h, _a, _b, _c, _d, W_0_63, 28); + R(_d, _e, _f, _g, _h, _a, _b, _c, W_0_63, 29); + R(_c, _d, _e, _f, _g, _h, _a, _b, W_0_63, 30); + R(_b, _c, _d, _e, _f, _g, _h, _a, W_0_63, 31); + + subs RRND, #16; + bne .Loop_rounds; + + R(_a, _b, _c, _d, _e, _f, _g, _h, W_64_79, 16); + R(_h, _a, _b, _c, _d, _e, _f, _g, W_64_79, 17); + R(_g, _h, _a, _b, _c, _d, _e, _f, W_64_79, 18); + R(_f, _g, _h, _a, _b, _c, _d, _e, W_64_79, 19); + R(_e, _f, _g, _h, _a, _b, _c, _d, W_64_79, 20); + R(_d, _e, _f, _g, _h, _a, _b, _c, W_64_79, 21); + R(_c, _d, _e, _f, _g, _h, _a, _b, W_64_79, 22); + R(_b, _c, _d, _e, _f, _g, _h, _a, W_64_79, 23); + R(_a, _b, _c, _d, _e, _f, _g, _h, W_64_79, 24); + R(_h, _a, _b, _c, _d, _e, _f, _g, W_64_79, 25); + R(_g, _h, _a, _b, _c, _d, _e, _f, W_64_79, 26); + R(_f, _g, _h, _a, _b, _c, _d, _e, W_64_79, 27); + R(_e, _f, _g, _h, _a, _b, _c, _d, W_64_79, 28); + R(_d, _e, _f, _g, _h, _a, _b, _c, W_64_79, 29); + R(_c, _d, _e, _f, _g, _h, _a, _b, W_64_79, 30); + R(_b, _c, _d, _e, _f, _g, _h, _a, W_64_79, 31); + + ldr %r0, [%sp, #(ctx)]; + adds RT2lo, RWlo; /* _h = t2 + Maj(_a,_b,_c) */ + ldr %r1, [%sp, #(data)]; + adc RT2hi, RWhi; + + ldm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi} + adds RT1lo, RT2lo; + ldr RT2lo, [%sp, #(_b + 0)]; + adc RT1hi, RT2hi; + ldr RT2hi, [%sp, #(_b + 4)]; + adds RWlo, RT2lo; + ldr RT2lo, [%sp, #(_c + 0)]; + adc RWhi, RT2hi; + ldr RT2hi, [%sp, #(_c + 4)]; + adds RT3lo, RT2lo; + ldr RT2lo, [%sp, #(_d + 0)]; + adc RT3hi, RT2hi; + ldr RT2hi, [%sp, #(_d + 4)]; + adds RT4lo, RT2lo; + ldr RT2lo, [%sp, #(_e + 0)]; + adc RT4hi, RT2hi; + stm %r0!, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi} + + ldr RT2hi, [%sp, #(_e + 4)]; + ldm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi} + adds RT1lo, RT2lo; + ldr RT2lo, [%sp, #(_f + 0)]; + adc RT1hi, RT2hi; + ldr RT2hi, [%sp, #(_f + 4)]; + adds RWlo, RT2lo; + ldr RT2lo, [%sp, #(_g + 0)]; + adc RWhi, RT2hi; + ldr RT2hi, [%sp, #(_g + 4)]; + adds RT3lo, RT2lo; + ldr RT2lo, [%sp, #(_h + 0)]; + adc RT3hi, RT2hi; + ldr RT2hi, [%sp, #(_h + 4)]; + adds RT4lo, RT2lo; + adc RT4hi, RT2hi; + stm %r0, {RT1lo,RT1hi,RWlo,RWhi,RT3lo,RT3hi,RT4lo,RT4hi} + sub %r0, %r0, #(4 * 8); + ldr RWlo, [%sp, #nblks]; + + sub RK, #(80 * 8); + subs RWlo, #1; + bne .Loop_blocks; + +.Ldone: + mov %r0, #STACK_MAX; +__out: + add %sp, %sp, #STACK_MAX; + pop {%r4-%r11, %ip, %pc}; +.size _gcry_sha512_transform_arm,.-_gcry_sha512_transform_arm; + +#endif +#endif diff --git a/cipher/sha512.c b/cipher/sha512.c index 1196db9..5b25965 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -66,6 +66,13 @@ #endif /*ENABLE_NEON_SUPPORT*/ +/* USE_ARM_ASM indicates whether to enable ARM assembly code. */ +#undef USE_ARM_ASM +#if defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) +# define USE_ARM_ASM 1 +#endif + + /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */ #undef USE_SSSE3 #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \ @@ -204,36 +211,6 @@ sha384_init (void *context, unsigned int flags) } -static inline u64 -ROTR (u64 x, u64 n) -{ - return ((x >> n) | (x << (64 - n))); -} - -static inline u64 -Ch (u64 x, u64 y, u64 z) -{ - return ((x & y) ^ ( ~x & z)); -} - -static inline u64 -Maj (u64 x, u64 y, u64 z) -{ - return ((x & y) ^ (x & z) ^ (y & z)); -} - -static inline u64 -Sum0 (u64 x) -{ - return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39)); -} - -static inline u64 -Sum1 (u64 x) -{ - return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41)); -} - static const u64 k[] = { U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd), @@ -278,6 +255,38 @@ static const u64 k[] = U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817) }; +#ifndef USE_ARM_ASM + +static inline u64 +ROTR (u64 x, u64 n) +{ + return ((x >> n) | (x << (64 - n))); +} + +static inline u64 +Ch (u64 x, u64 y, u64 z) +{ + return ((x & y) ^ ( ~x & z)); +} + +static inline u64 +Maj (u64 x, u64 y, u64 z) +{ + return ((x & y) ^ (x & z) ^ (y & z)); +} + +static inline u64 +Sum0 (u64 x) +{ + return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39)); +} + +static inline u64 +Sum1 (u64 x) +{ + return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41)); +} + /**************** * Transform the message W which consists of 16 64-bit-words */ @@ -304,7 +313,6 @@ transform_blk (SHA512_STATE *hd, const unsigned char *data) #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) - for (t = 0; t < 80 - 16; ) { u64 t1, t2; @@ -545,7 +553,7 @@ transform_blk (SHA512_STATE *hd, const unsigned char *data) return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) + 3 * sizeof(void*); } - +#endif /*!USE_ARM_ASM*/ /* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional * stack to store XMM6-XMM15 needed on Win64. */ @@ -568,6 +576,12 @@ void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd, const u64 k[], size_t num_blks); #endif +#ifdef USE_ARM_ASM +unsigned int _gcry_sha512_transform_arm (SHA512_STATE *hd, + const unsigned char *data, + const u64 k[], size_t num_blks); +#endif + #ifdef USE_SSSE3 unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data, void *state, @@ -622,6 +636,9 @@ transform (void *context, const unsigned char *data, size_t nblks) } #endif +#ifdef USE_ARM_ASM + burn = _gcry_sha512_transform_arm (&ctx->state, data, k, nblks); +#else do { burn = transform_blk (&ctx->state, data) + 3 * sizeof(void*); @@ -636,6 +653,7 @@ transform (void *context, const unsigned char *data, size_t nblks) */ burn += ASM_EXTRA_STACK; #endif +#endif return burn; } diff --git a/configure.ac b/configure.ac index ed37ab5..8b50360 100644 --- a/configure.ac +++ b/configure.ac @@ -2086,6 +2086,10 @@ if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo" GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo" ;; + arm*-*-*) + # Build with the assembly implementation + GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-arm.lo" + ;; esac if test x"$neonsupport" = xyes ; then ----------------------------------------------------------------------- Summary of changes: cipher/Makefile.am | 2 +- cipher/sha512-arm.S | 465 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cipher/sha512.c | 82 +++++---- configure.ac | 4 + 4 files changed, 520 insertions(+), 33 deletions(-) create mode 100644 cipher/sha512-arm.S hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 8 19:45:08 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Mon, 08 Feb 2016 19:45:08 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.21-7-g4b37d3a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 4b37d3ae19242f24e323da1a9462ad48b4bc8493 (commit) via c58e487cbdd392c5ed80eef1abb2177970d19c4a (commit) via 4135d1bb49777d41fcd556a7f1157b28b4d6a633 (commit) from b3bb6e2cc31208a198e74b42ca495c08ebb00fc4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4b37d3ae19242f24e323da1a9462ad48b4bc8493 Author: Daniel Kahn Gillmor Date: Mon Feb 8 11:06:38 2016 -0500 w32: Confirm the 639-1 code for Venda is "ve" -- https://www.loc.gov/standards/iso639-2/php/code_changes.php says that ve is indeed the 2-character code for Venda: >> This alpha-2 ISO 639-1 code was approved in 1999 and included in >> ISO 639-1: 2002. It was mistakenly missing in earlier versions of >> the tables on the ISO639-2 web site. As of January 2003, it has >> been included. diff --git a/src/w32-gettext.c b/src/w32-gettext.c index 734b9c1..8168e30 100644 --- a/src/w32-gettext.c +++ b/src/w32-gettext.c @@ -1039,11 +1039,7 @@ my_nl_locale_name (const char *categoryname) } return "uz"; case LANG_VENDA: - /* FIXME: It's not clear whether Venda has the ISO 639-2 two-letter code - "ve" or not. - http://www.loc.gov/standards/iso639-2/englangn.html has it, but - http://lcweb.loc.gov/standards/iso639-2/codechanges.html doesn't, */ - return "ven_ZA"; /* or "ve_ZA"? */ + return "ve_ZA"; case LANG_VIETNAMESE: return "vi_VN"; case LANG_WELSH: return "cy_GB"; case LANG_XHOSA: return "xh_ZA"; commit c58e487cbdd392c5ed80eef1abb2177970d19c4a Author: Daniel Kahn Gillmor Date: Mon Feb 8 11:06:37 2016 -0500 Convert http links to https where possible in the source. -- * use https for bug reporting * in comments and docs, use https to refer to: - www.gnu.org - creativecommons.org - translationproject.org - mail.gnome.org - www.perl.org - www.ctan.org - www.cl.cam.ac.uk - www.ntg.nl - cygwin.com - www.ethnologue.com diff --git a/ABOUT-NLS b/ABOUT-NLS index b1de1b6..3b879cb 100644 --- a/ABOUT-NLS +++ b/ABOUT-NLS @@ -111,7 +111,7 @@ people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, -`http://translationproject.org/', in the "Teams" area. +`https://translationproject.org/', in the "Teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. @@ -1259,7 +1259,7 @@ distribution. If June 2010 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at -`http://translationproject.org/extra/matrix.html'. +`https://translationproject.org/extra/matrix.html'. 1.5 Using `gettext' in new packages =================================== diff --git a/Makefile.am b/Makefile.am index e5f3f56..4f9f094 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public -# License along with this program; if not, see . +# License along with this program; if not, see . ACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = --enable-doc diff --git a/autogen.sh b/autogen.sh index 24da40c..91f35a6 100755 --- a/autogen.sh +++ b/autogen.sh @@ -347,7 +347,7 @@ if [ -d .git ]; then [ -z "${SILENT}" ] && cat <. +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/build-aux/config.guess b/build-aux/config.guess index dbfb978..7adf147 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -15,7 +15,7 @@ timestamp='2015-01-01' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/build-aux/config.sub b/build-aux/config.sub index 6d2e94c..0b2d816 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -15,7 +15,7 @@ timestamp='2015-01-01' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/build-aux/depcomp b/build-aux/depcomp index 4ebd5b3..f0a474c 100755 --- a/build-aux/depcomp +++ b/build-aux/depcomp @@ -16,7 +16,7 @@ scriptversion=2013-05-30.07; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh index f8c3614..c3bcdc0 100644 --- a/build-aux/ltmain.sh +++ b/build-aux/ltmain.sh @@ -24,7 +24,7 @@ # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# can be downloaded from https://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -75,8 +75,8 @@ # autoconf: $autoconf_version # # Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . +# GNU libtool home page: . +# General help using GNU software: . PROGRAM=libtool PACKAGE=libtool diff --git a/build-aux/mdate-sh b/build-aux/mdate-sh index b3719cf..39f48bb 100755 --- a/build-aux/mdate-sh +++ b/build-aux/mdate-sh @@ -17,7 +17,7 @@ scriptversion=2010-08-21.06; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/build-aux/missing b/build-aux/missing index db98974..295de3f 100755 --- a/build-aux/missing +++ b/build-aux/missing @@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ else exit $st fi -perl_URL=http://www.perl.org/ +perl_URL=https://www.perl.org/ flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +gnu_software_URL=https://www.gnu.org/software program_details () { diff --git a/build-aux/texinfo.tex b/build-aux/texinfo.tex index a181898..b1f0d2e 100644 --- a/build-aux/texinfo.tex +++ b/build-aux/texinfo.tex @@ -21,7 +21,7 @@ % % You should have received a copy of the GNU General Public License % along with this texinfo.tex file; see the file COPYING. If not, -% see . +% see . % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without @@ -29,9 +29,9 @@ % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: -% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or +% https://www.gnu.org/software/texinfo/ (the Texinfo home page), or % ftp://tug.org/tex/texinfo.tex -% (and all CTAN mirrors, see http://www.ctan.org). +% (and all CTAN mirrors, see https://www.ctan.org). % The texinfo.tex in any given distribution could well be out % of date, so if that's what you're using, please check. % @@ -55,7 +55,7 @@ % extent. You can get the existing language-specific files from the % full Texinfo distribution. % -% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. +% The GNU Texinfo home page is https://www.gnu.org/software/texinfo. \message{Loading texinfo [version \texinfoversion]:} @@ -1209,7 +1209,7 @@ where each line of input produces a line of output.} % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. -% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html +% https://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html % (and related messages, the final outcome is that it is up to the TeX % user to double the backslashes and otherwise make the string valid, so % that's what we do). @@ -2560,7 +2560,7 @@ end % We use the free feym* fonts from the eurosym package by Henrik % Theiling, which support regular, slanted, bold and bold slanted (and % "outlined" (blackboard board, sort of) versions, which we don't need). -% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% It is available from https://www.ctan.org/tex-archive/fonts/eurosym. % % Although only regular is the truly official Euro symbol, we ignore % that. The Euro is designed to be slightly taller than the regular diff --git a/configure.ac b/configure.ac index aec3685..19ae9c8 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # (Process this file with autoconf to produce a configure script.) # The following lines are used by ./autogen.sh. @@ -44,7 +44,7 @@ m4_define([mym4_betastring], m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes])) m4_define([mym4_full_version],[mym4_version[]mym4_betastring]) -AC_INIT([libgpg-error],[mym4_full_version],[http://bugs.gnupg.org]) +AC_INIT([libgpg-error],[mym4_full_version],[https://bugs.gnupg.org]) # LT Version numbers, remember to change them just *before* a release. # (Code changed: REVISION++) # (Interfaces added/removed/changed: CURRENT++, REVISION=0) diff --git a/doc/Makefile.am b/doc/Makefile.am index 8949f81..ddb7e48 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -14,7 +14,7 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public -# License along with this program; if not, see . +# License along with this program; if not, see . EXTRA_DIST = HACKING errorref.txt \ diff --git a/doc/ldap2gpgerr.c b/doc/ldap2gpgerr.c index 515bf40..f6fd3cf 100644 --- a/doc/ldap2gpgerr.c +++ b/doc/ldap2gpgerr.c @@ -8,7 +8,7 @@ * * You should have received a copy of the CC0 Public Domain Dedication * along with this software. If not, see - * . + * . */ /* diff --git a/doc/yat2m.c b/doc/yat2m.c index f780952..5039cc2 100644 --- a/doc/yat2m.c +++ b/doc/yat2m.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see . + * along with this program; if not, see . */ /* diff --git a/m4/ac_prog_cc_for_build.m4 b/m4/ac_prog_cc_for_build.m4 index 42c91ce..32329c7 100644 --- a/m4/ac_prog_cc_for_build.m4 +++ b/m4/ac_prog_cc_for_build.m4 @@ -1,5 +1,5 @@ dnl Available from the GNU Autoconf Macro Archive at: -dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_prog_cc_for_build.html +dnl https://www.gnu.org/software/ac-archive/htmldoc/ac_prog_cc_for_build.html dnl dnl All content of this archive is free software; dnl you can redistribute it and/or modify it under the terms of the GNU diff --git a/m4/libtool.m4 b/m4/libtool.m4 index 1d62b05..0cd84af 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -34,7 +34,7 @@ m4_define([_LT_COPYING], [dnl # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# can be downloaded from https://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) diff --git a/m4/threadlib.m4 b/m4/threadlib.m4 index b015365..32c2ea5 100644 --- a/m4/threadlib.m4 +++ b/m4/threadlib.m4 @@ -67,7 +67,7 @@ changequote(,)dnl dnl child process gets an endless segmentation fault inside execvp(). dnl Disable multithreading by default on Cygwin 1.5.x, because it has dnl bugs that lead to endless loops or crashes. See - dnl . + dnl . osf*) gl_use_threads=no ;; cygwin*) case `uname -r` in diff --git a/po/en at boldquot.header b/po/en at boldquot.header index fedb6a0..506ca9e 100644 --- a/po/en at boldquot.header +++ b/po/en at boldquot.header @@ -2,7 +2,7 @@ # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). diff --git a/po/en at quot.header b/po/en at quot.header index a9647fc..6522f0c 100644 --- a/po/en at quot.header +++ b/po/en at quot.header @@ -2,7 +2,7 @@ # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). diff --git a/src/Makefile.am b/src/Makefile.am index 8aca7df..b7cb023 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,7 +14,7 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public -# License along with this program; if not, see . +# License along with this program; if not, see . # We distribute the generated sources err-sources.h and err-codes.h, # because they are needed to build the po directory, and they don't diff --git a/src/estream-printf.c b/src/estream-printf.c index 39a813f..091ff7d 100644 --- a/src/estream-printf.c +++ b/src/estream-printf.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libestream; if not, see . + * License along with Libestream; if not, see . * * ALTERNATIVELY, Libestream may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/src/estream-printf.h b/src/estream-printf.h index e82d8fb..ae303a7 100644 --- a/src/estream-printf.h +++ b/src/estream-printf.h @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libestream; if not, see . + * License along with Libestream; if not, see . * * ALTERNATIVELY, Libestream may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/src/estream.c b/src/estream.c index 3a89868..abce0bf 100644 --- a/src/estream.c +++ b/src/estream.c @@ -15,7 +15,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libestream; if not, see . + * License along with Libestream; if not, see . * * ALTERNATIVELY, Libestream may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/src/estream.h b/src/estream.h index cfb7eec..91f2bc0 100644 --- a/src/estream.h +++ b/src/estream.h @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #ifndef ESTREAM_H diff --git a/src/gen-posix-lock-obj.c b/src/gen-posix-lock-obj.c index 595d379..22de456 100644 --- a/src/gen-posix-lock-obj.c +++ b/src/gen-posix-lock-obj.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/src/gen-w32-lock-obj.c b/src/gen-w32-lock-obj.c index 9e49d1e..f8da67f 100644 --- a/src/gen-w32-lock-obj.c +++ b/src/gen-w32-lock-obj.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 16de809..f8b9ebc 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -14,7 +14,7 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . * * Note: This file should be updated manually and the ordinals shall * never be changed. Also check gpg-error.vers and visibility.h. diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in index 28581e0..b32b4c4 100644 --- a/src/gpg-error.h.in +++ b/src/gpg-error.h.in @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . * * @configure_input@ */ diff --git a/src/gpg-error.vers b/src/gpg-error.vers index 067bb29..cdff0e3 100644 --- a/src/gpg-error.vers +++ b/src/gpg-error.vers @@ -14,7 +14,7 @@ # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public -# License along with this program; if not, see . +# License along with this program; if not, see . # # NOTE: When adding new functions, please make sure to add them to # visibility.h and gpg-error.def.in as well. diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index 0f7b29b..d69fe2c 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #ifndef _GPGRT_GPGRT_INT_H diff --git a/src/init.c b/src/init.c index 7abb6ff..8de54b6 100644 --- a/src/init.c +++ b/src/init.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/src/init.h b/src/init.h index 0a31fd7..90a716a 100644 --- a/src/init.h +++ b/src/init.h @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #ifndef INIT_H diff --git a/src/lock.h b/src/lock.h index b60f2c2..a830b36 100644 --- a/src/lock.h +++ b/src/lock.h @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #ifndef LOCK_H diff --git a/src/mkw32errmap.c b/src/mkw32errmap.c index 68d0f05..508a513 100644 --- a/src/mkw32errmap.c +++ b/src/mkw32errmap.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #ifdef RESOLVE_MACROS diff --git a/src/posix-lock-obj.h b/src/posix-lock-obj.h index 872e55a..08e0bac 100644 --- a/src/posix-lock-obj.h +++ b/src/posix-lock-obj.h @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #ifndef POSIX_LOCK_OBJ_H diff --git a/src/posix-lock.c b/src/posix-lock.c index d8f5465..2e0ae92 100644 --- a/src/posix-lock.c +++ b/src/posix-lock.c @@ -15,7 +15,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . Parts of the code, in particular use_pthreads_p, are based on code from gettext, written by Bruno Haible , 2005. diff --git a/src/posix-thread.c b/src/posix-thread.c index bef0386..270dc91 100644 --- a/src/posix-thread.c +++ b/src/posix-thread.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/src/thread.h b/src/thread.h index 0b2cf04..c650a99 100644 --- a/src/thread.h +++ b/src/thread.h @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #ifndef THREAD_H diff --git a/src/version.c b/src/version.c index 216fee4..d0c408d 100644 --- a/src/version.c +++ b/src/version.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/src/visibility.c b/src/visibility.c index 4750685..e3ac8a7 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #include diff --git a/src/visibility.h b/src/visibility.h index ec3a124..1de6c62 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #ifndef _GPGRT_VISIBILITY_H diff --git a/src/w32-gettext.c b/src/w32-gettext.c index 146de53..734b9c1 100644 --- a/src/w32-gettext.c +++ b/src/w32-gettext.c @@ -15,7 +15,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H @@ -681,7 +681,7 @@ my_nl_locale_name (const char *categoryname) /* Dispatch on language. See also http://www.unicode.org/unicode/onlinedat/languages.html . - For details about languages, see http://www.ethnologue.com/ . */ + For details about languages, see https://www.ethnologue.com/ . */ switch (primary) { case LANG_AFRIKAANS: return "af_ZA"; diff --git a/src/w32-lock-obj.h b/src/w32-lock-obj.h index ef53546..8ed3084 100644 --- a/src/w32-lock-obj.h +++ b/src/w32-lock-obj.h @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #ifndef W32_LOCK_OBJ_H diff --git a/src/w32-lock.c b/src/w32-lock.c index 8c086f9..d1decc9 100644 --- a/src/w32-lock.c +++ b/src/w32-lock.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/src/w32-thread.c b/src/w32-thread.c index 53d26b4..6860075 100644 --- a/src/w32-thread.c +++ b/src/w32-thread.c @@ -14,7 +14,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, see . + License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/tests/t-common.h b/tests/t-common.h index c6dcd12..e11bca9 100644 --- a/tests/t-common.h +++ b/tests/t-common.h @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #include diff --git a/tests/t-lock.c b/tests/t-lock.c index 1ccf815..38c9cec 100644 --- a/tests/t-lock.c +++ b/tests/t-lock.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #if HAVE_CONFIG_H diff --git a/tests/t-poll.c b/tests/t-poll.c index 57cdb75..56b29c8 100644 --- a/tests/t-poll.c +++ b/tests/t-poll.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ /* FIXME: We need much better tests that this very basic one. */ diff --git a/tests/t-printf.c b/tests/t-printf.c index 069bdc6..7fba012 100644 --- a/tests/t-printf.c +++ b/tests/t-printf.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ /* Note that these tests check against glibc behaviour. On non glibc diff --git a/tests/t-version.c b/tests/t-version.c index ce8f41b..4606dbc 100644 --- a/tests/t-version.c +++ b/tests/t-version.c @@ -14,7 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . + * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H commit 4135d1bb49777d41fcd556a7f1157b28b4d6a633 Author: Werner Koch Date: Wed Jan 27 10:12:25 2016 +0100 Add syscfg alias for x86_64-pc-linux-gnuhardened1 -- diff --git a/src/mkheader.c b/src/mkheader.c index 875a0f5..0d3d6ba 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -81,6 +81,7 @@ canon_host_triplet (const char *triplet) {"i586-pc-gnu"}, {"i486-pc-kfreebsd-gnu", "i686-pc-kfreebsd-gnu"}, {"i586-pc-kfreebsd-gnu"}, + {"x86_64-pc-linux-gnuhardened1", "x86_64-pc-linux-gnu" }, { NULL } }; ----------------------------------------------------------------------- Summary of changes: ABOUT-NLS | 4 ++-- Makefile.am | 2 +- autogen.sh | 2 +- build-aux/compile | 2 +- build-aux/config.guess | 2 +- build-aux/config.sub | 2 +- build-aux/depcomp | 2 +- build-aux/ltmain.sh | 6 +++--- build-aux/mdate-sh | 2 +- build-aux/missing | 6 +++--- build-aux/texinfo.tex | 12 ++++++------ configure.ac | 4 ++-- doc/Makefile.am | 2 +- doc/ldap2gpgerr.c | 2 +- doc/yat2m.c | 2 +- m4/ac_prog_cc_for_build.m4 | 2 +- m4/libtool.m4 | 2 +- m4/threadlib.m4 | 2 +- po/en at boldquot.header | 2 +- po/en at quot.header | 2 +- src/Makefile.am | 2 +- src/estream-printf.c | 2 +- src/estream-printf.h | 2 +- src/estream.c | 2 +- src/estream.h | 2 +- src/gen-posix-lock-obj.c | 2 +- src/gen-w32-lock-obj.c | 2 +- src/gpg-error.def.in | 2 +- src/gpg-error.h.in | 2 +- src/gpg-error.vers | 2 +- src/gpgrt-int.h | 2 +- src/init.c | 2 +- src/init.h | 2 +- src/lock.h | 2 +- src/mkheader.c | 1 + src/mkw32errmap.c | 2 +- src/posix-lock-obj.h | 2 +- src/posix-lock.c | 2 +- src/posix-thread.c | 2 +- src/thread.h | 2 +- src/version.c | 2 +- src/visibility.c | 2 +- src/visibility.h | 2 +- src/w32-gettext.c | 10 +++------- src/w32-lock-obj.h | 2 +- src/w32-lock.c | 2 +- src/w32-thread.c | 2 +- tests/t-common.h | 2 +- tests/t-lock.c | 2 +- tests/t-poll.c | 2 +- tests/t-printf.c | 2 +- tests/t-version.c | 2 +- 52 files changed, 65 insertions(+), 68 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 8 19:49:49 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 08 Feb 2016 19:49:49 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.21-8-g1e6c5a7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 1e6c5a70b3b51f81d2fc1289129f6c3e1920ebcc (commit) from 4b37d3ae19242f24e323da1a9462ad48b4bc8493 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1e6c5a70b3b51f81d2fc1289129f6c3e1920ebcc Author: Werner Koch Date: Mon Feb 8 19:44:06 2016 +0100 build: Create an SWDB file during "make distcheck" * Makefile.am (distcheck-hook): New. -- The SWDB file is used to update the swdb.mac file from the gnupg-doc repo which is the source for https://gnupg.org/swdb.lst https://gnupg.org/swdb.lst.sig Signed-off-by: Werner Koch diff --git a/Makefile.am b/Makefile.am index 4f9f094..baeba14 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,20 @@ dist-hook: gen-ChangeLog $(top_srcdir)/libgpg-error.spec.in > $(distdir)/libgpg-error.spec @set -e; echo "$(VERSION)" > $(distdir)/VERSION +distcheck-hook: + set -e; ( \ + pref="#+macro: $$(echo $(PACKAGE_NAME)|tr '-' '_')_" ;\ + reldate="$$(date -u +%Y-%m-%d)" ;\ + echo "$${pref}ver $(PACKAGE_VERSION)" ;\ + echo "$${pref}date $${reldate}" ;\ + list='$(DIST_ARCHIVES)'; for i in $$list; do \ + case "$$i" in *.tar.bz2) \ + echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ + echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ + echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ + esac;\ + done ) | tee $(distdir).swdb + gen_start_date = 2011-12-01T00:00:00 .PHONY: gen-ChangeLog ----------------------------------------------------------------------- Summary of changes: Makefile.am | 14 ++++++++++++++ 1 file changed, 14 insertions(+) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 9 10:11:21 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 09 Feb 2016 10:11:21 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.4-7-gde7db12 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-6-BRANCH has been updated via de7db12fa04016e12dffb2b678632f45eba15ec4 (commit) via 070f0c4e14298c53785ea8caa8db71e30d134a1d (commit) via 28eb424e4427b320ec1c9c4ce56af25d495230bd (commit) from df3cfdb32c332b57822d54040fc911bcb0594acb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit de7db12fa04016e12dffb2b678632f45eba15ec4 Author: NIIBE Yutaka Date: Wed Nov 25 12:46:19 2015 +0900 ecc: Constant-time multiplication for Weierstrass curve. * mpi/ec.c (_gcry_mpi_ec_mul_point): Use simple left-to-right binary method for Weierstrass curve when SCALAR is secure. -- Signed-off-by: NIIBE Yutaka CVE-id: CVE-2015-7511 Thanks to Daniel Genkin, Lev Pachmanov, Itamar Pipman, and Eran Tromer. http://www.cs.tau.ac.IL/~tromer/ecdh/ This could be an effective contermeasure to some chosen cipher text attacks. (backport from master commit 88e1358962e902ff1cbec8d53ba3eee46407851a) diff --git a/mpi/ec.c b/mpi/ec.c index ccaed29..cb4113c 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1106,16 +1106,27 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, unsigned int i, loops; mpi_point_struct p1, p2, p1inv; - if (ctx->model == MPI_EC_TWISTEDEDWARDS) + if (ctx->model == MPI_EC_TWISTEDEDWARDS + || (ctx->model == MPI_EC_WEIERSTRASS + && mpi_is_secure (scalar))) { /* Simple left to right binary method. GECC Algorithm 3.27 */ unsigned int nbits; int j; nbits = mpi_get_nbits (scalar); - mpi_set_ui (result->x, 0); - mpi_set_ui (result->y, 1); - mpi_set_ui (result->z, 1); + if (ctx->model == MPI_EC_WEIERSTRASS) + { + mpi_set_ui (result->x, 1); + mpi_set_ui (result->y, 1); + mpi_set_ui (result->z, 0); + } + else + { + mpi_set_ui (result->x, 0); + mpi_set_ui (result->y, 1); + mpi_set_ui (result->z, 1); + } if (mpi_is_secure (scalar)) { commit 070f0c4e14298c53785ea8caa8db71e30d134a1d Author: NIIBE Yutaka Date: Thu Nov 26 11:37:47 2015 +0900 ecc: minor improvement of point multiplication. * mpi/ec.c (_gcry_mpi_ec_mul_point): Move ec_subm out of the loop. -- (backport from master commit 3658afd09c3b03b4398aaa5748387220c93b1a94) diff --git a/mpi/ec.c b/mpi/ec.c index 168076f..ccaed29 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1205,6 +1205,10 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, point_init (&p2); point_init (&p1inv); + /* Invert point: y = p - y mod p */ + point_set (&p1inv, &p1); + ec_subm (p1inv.y, ctx->p, p1inv.y, ctx); + for (i=loops-2; i > 0; i--) { _gcry_mpi_ec_dup_point (result, result, ctx); @@ -1216,9 +1220,6 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1) { point_set (&p2, result); - /* Invert point: y = p - y mod p */ - point_set (&p1inv, &p1); - ec_subm (p1inv.y, ctx->p, p1inv.y, ctx); _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx); } } commit 28eb424e4427b320ec1c9c4ce56af25d495230bd Author: NIIBE Yutaka Date: Wed Nov 25 08:41:41 2015 +0900 ecc: input validation on ECDH. * cipher/ecc.c (ecc_decrypt_raw): Validate the point. diff --git a/cipher/ecc.c b/cipher/ecc.c index 9dd2482..9b05d46 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1382,6 +1382,12 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0, sk.E.p, sk.E.a, sk.E.b); + if (!_gcry_mpi_ec_curve_point (&kG, ec)) + { + point_free (&kG); + return GPG_ERR_INV_DATA; + } + /* R = dkG */ _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec); ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 6 ++++++ mpi/ec.c | 26 +++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 9 10:26:00 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 09 Feb 2016 10:26:00 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-313-g23b7290 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 23b72901f8a5ba9a78485b235c7a917fbc8faae0 (commit) from 8353884bc65c820d5bcacaf1ac23cdee72091a09 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 23b72901f8a5ba9a78485b235c7a917fbc8faae0 Author: NIIBE Yutaka Date: Wed Nov 25 08:41:41 2015 +0900 ecc: input validation on ECDH. * cipher/ecc.c (ecc_decrypt_raw): Validate the point. -- Signed-off-by: NIIBE Yutaka (forward port from LIBGCRYPT-1-6-BRANCH commit 28eb424e4427b320ec1c9c4ce56af25d495230bd) diff --git a/cipher/ecc.c b/cipher/ecc.c index 7d6ad94..b861925 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1570,6 +1570,12 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) if (DBG_CIPHER) log_printpnt ("ecc_decrypt kG", &kG, NULL); + if (!_gcry_mpi_ec_curve_point (&kG, ec)) + { + point_free (&kG); + return GPG_ERR_INV_DATA; + } + /* R = dkG */ _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec); ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 9 10:58:45 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 09 Feb 2016 10:58:45 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-314-g4a19b19 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 4a19b195697e0b6534d28de9401ae3e9d86adb42 (commit) from 23b72901f8a5ba9a78485b235c7a917fbc8faae0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4a19b195697e0b6534d28de9401ae3e9d86adb42 Author: NIIBE Yutaka Date: Tue Feb 9 18:50:47 2016 +0900 doc: about commit 23b72901f8a5ba9a78485b235c7a917fbc8faae0 -- Signed-off-by: NIIBE Yutaka Together with 88e1358962e902ff1cbec8d53ba3eee46407851a, it could be an effective contermeasure to some chosen cipher text attacks. CVE-id: CVE-2015-7511 Thanks to Daniel Genkin, Lev Pachmanov, Itamar Pipman, and Eran Tromer. http://www.cs.tau.ac.IL/~tromer/ecdh/ ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 9 11:41:08 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 09 Feb 2016 11:41:08 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.4-9-g9294955 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-6-BRANCH has been updated via 929495541b6b737585a1ba620adbd2789b2cf65f (commit) via 92b33b9e3f016c83646f2e9360a403c853d48551 (commit) from de7db12fa04016e12dffb2b678632f45eba15ec4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 929495541b6b737585a1ba620adbd2789b2cf65f Author: Werner Koch Date: Tue Feb 9 11:36:03 2016 +0100 Post release updates -- diff --git a/NEWS b/NEWS index 492344a..22ce582 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.6.6 (unreleased) [C20/A0/R_] +------------------------------------------------ + + Noteworthy changes in version 1.6.5 (2016-02-09) [C20/A0/R5] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index e271769..b58fd6b 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.14" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [6]) -m4_define(mym4_version_micro, [5]) +m4_define(mym4_version_micro, [6]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit 92b33b9e3f016c83646f2e9360a403c853d48551 Author: Werner Koch Date: Tue Feb 9 11:00:15 2016 +0100 Release 1.6.5. * configure.ac: Set LT version to C20/A0/R5. Signed-off-by: Werner Koch diff --git a/AUTHORS b/AUTHORS index 823b0d6..a8f62ce 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,7 +17,7 @@ year that would otherwise be listed individually. List of Copyright holders ========================= - Copyright (C) 1989,1991-2015 Free Software Foundation, Inc. + Copyright (C) 1989,1991-2016 Free Software Foundation, Inc. Copyright (C) 1994 X Consortium Copyright (C) 1996 L. Peter Deutsch Copyright (C) 1997 Werner Koch @@ -26,7 +26,7 @@ List of Copyright holders Copyright (C) 1996-2006 Peter Gutmann, Matt Thomlinson and Blake Coverett Copyright (C) 2003 Nikos Mavroyanopoulos Copyright (C) 2006-2007 NTT (Nippon Telegraph and Telephone Corporation) - Copyright (C) 2012-2015 g10 Code GmbH + Copyright (C) 2012-2016 g10 Code GmbH Copyright (C) 2012 Simon Josefsson, Niels M??ller Copyright (c) 2012 Intel Corporation Copyright (C) 2013 Christian Grothoff diff --git a/NEWS b/NEWS index 25689ba..492344a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,12 @@ -Noteworthy changes in version 1.6.5 (unreleased) [C20/A0/R_] +Noteworthy changes in version 1.6.5 (2016-02-09) [C20/A0/R5] ------------------------------------------------ + * Mitigate side-channel attack on ECDH with Weierstrass curves + [CVE-2015-7511]. See http://www.cs.tau.ac.IL/~tromer/ecdh/ for + details. + + * Fix build problem on Solaris. + Noteworthy changes in version 1.6.4 (2015-09-08) [C20/A0/R4] ------------------------------------------------ @@ -887,7 +893,7 @@ Noteworthy changes in version 1.1.3 (2001-05-31) Copyright 2001, 2002, 2003, 2004, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. -Copyright 2013 g10 Code GmbH +Copyright 2013-2016 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/README b/README index 53894e0..18fb0f2 100644 --- a/README +++ b/README @@ -2,8 +2,8 @@ ------------------------------------ Version 1.6 - Copyright (C) 1989,1991-2015 Free Software Foundation, Inc. - Copyright (C) 2012-2015 g10 Code GmbH + Copyright (C) 1989,1991-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2016 g10 Code GmbH Copyright (C) 2013-2015 Jussi Kivilinna Libgcrypt is free software. See the file AUTHORS for full copying diff --git a/compat/compat.c b/compat/compat.c index 2389961..0922cda 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -30,8 +30,8 @@ _gcry_compat_identification (void) static const char blurb[] = "\n\n" "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n" - "Copyright (C) 2000-2015 Free Software Foundation, Inc.\n" - "Copyright (C) 2012-2015 g10 Code GmbH\n" + "Copyright (C) 2000-2016 Free Software Foundation, Inc.\n" + "Copyright (C) 2012-2016 g10 Code GmbH\n" "Copyright (C) 2013-2015 Jussi Kivilinna\n" "(See the source code for a complete list)\n" "\n" diff --git a/configure.ac b/configure.ac index eb1ba34..e271769 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=20 LIBGCRYPT_LT_AGE=0 -LIBGCRYPT_LT_REVISION=4 +LIBGCRYPT_LT_REVISION=5 # If the API is changed in an incompatible way: increment the next counter. diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index 3199521..1adb4e9 100644 --- a/src/versioninfo.rc.in +++ b/src/versioninfo.rc.in @@ -39,7 +39,7 @@ BEGIN VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0" VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT at .@LIBGCRYPT_LT_AGE at .@LIBGCRYPT_LT_REVISION at .@BUILD_REVISION@\0" VALUE "InternalName", "libgcrypt\0" - VALUE "LegalCopyright", "Copyright ? 2012 Free Software Foundation, Inc.\0" + VALUE "LegalCopyright", "Copyright ? 2016 Free Software Foundation, Inc.\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libgcrypt.dll\0" VALUE "PrivateBuild", "\0" ----------------------------------------------------------------------- Summary of changes: AUTHORS | 4 ++-- NEWS | 14 ++++++++++++-- README | 4 ++-- compat/compat.c | 4 ++-- configure.ac | 4 ++-- src/versioninfo.rc.in | 2 +- 6 files changed, 21 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 9 12:27:03 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 09 Feb 2016 12:27:03 +0100 Subject: [git] gnupg-doc - branch, master, updated. a0ef42da45e53c0f3001ae2016da47d9d51eaa87 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via a0ef42da45e53c0f3001ae2016da47d9d51eaa87 (commit) via 4f37049552640bd422a9cd8c9a39478928f6c229 (commit) from 6d24f421b59488615fae999740f495281c4f741e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a0ef42da45e53c0f3001ae2016da47d9d51eaa87 Author: Werner Koch Date: Tue Feb 9 12:21:31 2016 +0100 faq: Fix syntax error and change donation URL. - Fix syntax error for the gethelp CUSTOM_ID. - Change donation from the former g10 Code to the GnuPG page. diff --git a/web/faq/gnupg-faq.org b/web/faq/gnupg-faq.org index 5b0535f..984d41f 100644 --- a/web/faq/gnupg-faq.org +++ b/web/faq/gnupg-faq.org @@ -86,7 +86,7 @@ Thanks to the Free Software Foundation, this FAQ is also available in ** How do I get help? :PROPERTIES: - :CUSTOM ID: gethelp + :CUSTOM_ID: gethelp :END: First, please don?t send emails directly to people in GnuPG. While we will @@ -366,7 +366,7 @@ you may share the software and/or your modifications with others. :CUSTOM_ID: donate :END: -The best way is to visit the [[http://g10code.com/gnupg-donation.html][g10 Code donation page]]. +The best way is to visit the [[https://gnupg.org/donate/][donation page]]. ** How can I help with GnuPG development? commit 4f37049552640bd422a9cd8c9a39478928f6c229 Author: Werner Koch Date: Tue Feb 9 12:11:17 2016 +0100 swdb: Release libgcrypt 1.6.5 and updated 2.1.11 windows installer diff --git a/web/swdb.mac b/web/swdb.mac index edc291e..4295c1c 100644 --- a/web/swdb.mac +++ b/web/swdb.mac @@ -26,11 +26,11 @@ #+macro: gnupg21_sha1 4af2032a60ff22e322b1c5b270d6d2228f59a3a3 #+macro: gnupg21_sha2 b7b0fb2c8c5d47d7ec916d4a1097c0ddcb94a12bb1c0ac424ad86b1ee316b61a # -#+macro: gnupg21_w32_ver 2.1.11_20160126 -#+macro: gnupg21_w32_date 2016-01-26 +#+macro: gnupg21_w32_ver 2.1.11_20160209 +#+macro: gnupg21_w32_date 2016-02-09 #+macro: gnupg21_w32_size 2630k -#+macro: gnupg21_w32_sha1 ed237ba7bf8fd4fd3f2688ddd46b949dd15ebdd6 -#+macro: gnupg21_w32_sha2 4567227bd0885354b17f18639d13820bca81e5202b2388e7a6efa096864d66d4 +#+macro: gnupg21_w32_sha1 89bd31652d370ba69ac27b42b4d474d7edd9e0ea +#+macro: gnupg21_w32_sha2 1e92b39ef4f4cdf3b1849b6f824dd8f160276aa5c9718be35f8a7bd190bf6154 # @@ -80,10 +80,10 @@ # # LIBGCRYPT # -#+macro: libgcrypt_ver 1.6.4 -#+macro: libgcrypt_date 2015-09-08 +#+macro: libgcrypt_ver 1.6.5 +#+macro: libgcrypt_date 2016-02-09 #+macro: libgcrypt_size 2490k -#+macro: libgcrypt_sha1 ed52add1ce635deeb2f5c6650e52667debd4ec70 +#+macro: libgcrypt_sha1 c3a5a13e717f7b3e3895650afc1b6e0d3fe9c726 # ----------------------------------------------------------------------- Summary of changes: web/faq/gnupg-faq.org | 4 ++-- web/swdb.mac | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 9 17:01:37 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 09 Feb 2016 17:01:37 +0100 Subject: [git] gnupg-doc - branch, master, updated. 07bd2c3f8b218c788f0aa1f6cf8e1a26b56bb514 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 07bd2c3f8b218c788f0aa1f6cf8e1a26b56bb514 (commit) from a0ef42da45e53c0f3001ae2016da47d9d51eaa87 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 07bd2c3f8b218c788f0aa1f6cf8e1a26b56bb514 Author: Werner Koch Date: Tue Feb 9 16:44:39 2016 +0100 web: Release info for libgcrypt 1.6.5. diff --git a/web/index.org b/web/index.org index 168f03a..58fb660 100644 --- a/web/index.org +++ b/web/index.org @@ -65,6 +65,12 @@ The latest release news:\\ # point or paste the [[news.en.rss][RSS file]] into your aggregator. +** Libgcrypt 1.6.5 released (2015-02-27) :important: + +Libgcrypt version 1.6.5 and an updated Windows installer for GnuPG +2.1.11 has been released to mitigate a new side-channel attack. +[[https://lists.gnupg.org/pipermail/gnupg-announce/2016q1/000384.html][{more}]] + ** GnuPG 2.1.11 released (2016-01-26) A new version of the /modern/ branch of GnuPG has been released. ----------------------------------------------------------------------- Summary of changes: web/index.org | 6 ++++++ 1 file changed, 6 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 10 09:50:39 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 10 Feb 2016 09:50:39 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-315-gb12dd55 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via b12dd550fd6af687ef95c584d0d8366c34965cc8 (commit) from 4a19b195697e0b6534d28de9401ae3e9d86adb42 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b12dd550fd6af687ef95c584d0d8366c34965cc8 Author: NIIBE Yutaka Date: Wed Feb 10 17:35:43 2016 +0900 ecc: Fix memory leaks on error. * cipher/ecc.c (ecc_decrypt_raw): Go to leave to release memory. * mpi/ec.c (_gcry_mpi_ec_curve_point): Likewise. -- Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc.c b/cipher/ecc.c index b861925..d1fe823 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1572,8 +1572,8 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) if (!_gcry_mpi_ec_curve_point (&kG, ec)) { - point_free (&kG); - return GPG_ERR_INV_DATA; + rc = GPG_ERR_INV_DATA; + goto leave; } /* R = dkG */ diff --git a/mpi/ec.c b/mpi/ec.c index 346e5f1..f0b8374 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1478,10 +1478,12 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) { case MPI_EC_WEIERSTRASS: { - gcry_mpi_t xxx = mpi_new (0); + gcry_mpi_t xxx; if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) - return 0; + goto leave; + + xxx = mpi_new (0); /* y^2 == x^3 + a?x + b */ ec_pow2 (y, y, ctx); @@ -1502,7 +1504,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) #define xx y /* With Montgomery curve, only X-coordinate is valid. */ if (_gcry_mpi_ec_get_affine (x, NULL, point, ctx)) - return 0; + goto leave; /* The equation is: b * y^2 == x^3 + a ? x^2 + x */ /* We check if right hand is quadratic residue or not by @@ -1530,7 +1532,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) case MPI_EC_EDWARDS: { if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) - return 0; + goto leave; /* a ? x^2 + y^2 - 1 - b ? x^2 ? y^2 == 0 */ ec_pow2 (x, x, ctx); @@ -1553,6 +1555,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) break; } + leave: _gcry_mpi_release (w); _gcry_mpi_release (x); _gcry_mpi_release (y); ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 4 ++-- mpi/ec.c | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 10 09:50:58 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 10 Feb 2016 09:50:58 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.5-2-g72b0d74 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-6-BRANCH has been updated via 72b0d74103fef216479f97f9d5fe23e95f6b3ccc (commit) from 929495541b6b737585a1ba620adbd2789b2cf65f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 72b0d74103fef216479f97f9d5fe23e95f6b3ccc Author: NIIBE Yutaka Date: Wed Feb 10 17:39:14 2016 +0900 ecc: Fix memory leaks on error. * cipher/ecc.c (ecc_generate): Go to leave to release memory. (ecc_check_secret_key, ecc_sign, ecc_verify): Likewise. (ecc_encrypt_raw, ecc_decrypt_raw): Likewise. * mpi/ec.c (_gcry_mpi_ec_curve_point): Likewise. -- Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc.c b/cipher/ecc.c index 9b05d46..29d1d33 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -467,10 +467,12 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) /* NBITS is required if no curve name has been given. */ if (!nbits && !curve_name) - return GPG_ERR_NO_OBJ; /* No NBITS parameter. */ + { + rc = GPG_ERR_NO_OBJ; /* No NBITS parameter. */ + goto leave; + } rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits); - xfree (curve_name); curve_name = NULL; if (rc) goto leave; @@ -513,7 +515,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) !!(flags & PUBKEY_FLAG_COMP), &encpk, &encpklen); if (rc) - return rc; + goto leave; public = mpi_new (0); mpi_set_opaque (public, encpk, encpklen*8); encpk = NULL; @@ -609,6 +611,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) _gcry_mpi_ec_free (ctx); sexp_release (curve_flags); sexp_release (curve_info); + xfree (curve_name); return rc; } @@ -660,7 +663,7 @@ ecc_check_secret_key (gcry_sexp_t keyparms) &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n); if (rc) - return rc; + goto leave; } } if (mpi_g) @@ -800,7 +803,7 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) { rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL); if (rc) - return rc; + goto leave; } } /* Guess required fields if a curve parameter has not been given. @@ -964,7 +967,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) { rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL); if (rc) - return rc; + goto leave; } } /* Guess required fields if a curve parameter has not been given. @@ -1171,7 +1174,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) { rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL); if (rc) - return rc; + goto leave; } } /* Guess required fields if a curve parameter has not been given. */ @@ -1338,7 +1341,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) { rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL); if (rc) - return rc; + goto leave; } } /* Guess required fields if a curve parameter has not been given. */ @@ -1375,8 +1378,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) rc = _gcry_ecc_os2ec (&kG, data_e); if (rc) { - point_free (&kG); - return rc; + goto leave; } ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0, @@ -1384,8 +1386,8 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) if (!_gcry_mpi_ec_curve_point (&kG, ec)) { - point_free (&kG); - return GPG_ERR_INV_DATA; + rc = GPG_ERR_INV_DATA; + goto leave; } /* R = dkG */ diff --git a/mpi/ec.c b/mpi/ec.c index cb4113c..c14b728 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1255,7 +1255,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) w = mpi_new (0); if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) - return 0; + goto leave; switch (ctx->model) { @@ -1304,6 +1304,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) break; } + leave: _gcry_mpi_release (w); _gcry_mpi_release (x); _gcry_mpi_release (y); ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 26 ++++++++++++++------------ mpi/ec.c | 3 ++- 2 files changed, 16 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 10 09:51:17 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 10 Feb 2016 09:51:17 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.4-4-gfcbb9fc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via fcbb9fcc2e6983ea61bf565b6ee2e29816b8cd57 (commit) from 35cd81f134c0da4e7e6fcfe40d270ee1251f52c2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fcbb9fcc2e6983ea61bf565b6ee2e29816b8cd57 Author: NIIBE Yutaka Date: Wed Feb 10 17:43:03 2016 +0900 ecc: Fix for chosen cipher text attacks. * src/mpi.h (_gcry_mpi_ec_curve_point): New internal function. * cipher/ecc.c (ecc_decrypt_raw): Validate input. Remove duplicated point_free. * mpi/ec.c (_gcry_mpi_ec_mul_point):Use simple left-to-right binary method for when SCALAR is secure. (_gcry_mpi_ec_curve_point): New. -- CVE-id: CVE-2015-7511 Thanks to Daniel Genkin, Lev Pachmanov, Itamar Pipman, and Eran Tromer. http://www.cs.tau.ac.IL/~tromer/ecdh/ This could be an effective contermeasure to some chosen cipher text attacks. (backport from master commit 88e1358962e902ff1cbec8d53ba3eee46407851a) (backport from LIBGCRYPT-1-6-BRANCH commit 28eb424e4427b320ec1c9c4ce56af25d495230bd) Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc.c b/cipher/ecc.c index b8487dc..80b67ae 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1535,12 +1535,19 @@ ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a); + if (!_gcry_mpi_ec_curve_point (&kG, sk.E.b, ctx)) + { + point_free (&kG); + point_free (&sk.E.G); + point_free (&sk.Q); + _gcry_mpi_ec_free (ctx); + return GPG_ERR_INV_DATA; + } + /* R = dkG */ point_init (&R); _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx); - point_free (&kG); - /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */ { gcry_mpi_t x, y; diff --git a/mpi/ec.c b/mpi/ec.c index fa00818..bdb155a 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -612,110 +612,154 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result, gcry_mpi_t scalar, mpi_point_t *point, mpi_ec_t ctx) { -#if 0 - /* Simple left to right binary method. GECC Algorithm 3.27 */ - unsigned int nbits; - int i; - - nbits = mpi_get_nbits (scalar); - mpi_set_ui (result->x, 1); - mpi_set_ui (result->y, 1); - mpi_set_ui (result->z, 0); - - for (i=nbits-1; i >= 0; i--) + if (mpi_is_secure(scalar)) { - _gcry_mpi_ec_dup_point (result, result, ctx); - if (mpi_test_bit (scalar, i) == 1) - _gcry_mpi_ec_add_points (result, result, point, ctx); - } - -#else - gcry_mpi_t x1, y1, z1, k, h, yy; - unsigned int i, loops; - mpi_point_t p1, p2, p1inv; - - x1 = mpi_alloc_like (ctx->p); - y1 = mpi_alloc_like (ctx->p); - h = mpi_alloc_like (ctx->p); - k = mpi_copy (scalar); - yy = mpi_copy (point->y); + /* Simple left to right binary method. GECC Algorithm 3.27 */ + unsigned int nbits; + int i; + mpi_point_t tmppnt; - if ( mpi_is_neg (k) ) - { - k->sign = 0; - ec_invm (yy, yy, ctx); - } + nbits = mpi_get_nbits (scalar); + mpi_set_ui (result->x, 1); + mpi_set_ui (result->y, 1); + mpi_set_ui (result->z, 0); - if (!mpi_cmp_ui (point->z, 1)) - { - mpi_set (x1, point->x); - mpi_set (y1, yy); + point_init (&tmppnt); + for (i=nbits-1; i >= 0; i--) + { + _gcry_mpi_ec_dup_point (result, result, ctx); + _gcry_mpi_ec_add_points (&tmppnt, result, point, ctx); + if (mpi_test_bit (scalar, i) == 1) + point_set (result, &tmppnt); + } + point_free (&tmppnt); } else { - gcry_mpi_t z2, z3; - - z2 = mpi_alloc_like (ctx->p); - z3 = mpi_alloc_like (ctx->p); - ec_mulm (z2, point->z, point->z, ctx); - ec_mulm (z3, point->z, z2, ctx); - ec_invm (z2, z2, ctx); - ec_mulm (x1, point->x, z2, ctx); - ec_invm (z3, z3, ctx); - ec_mulm (y1, yy, z3, ctx); - mpi_free (z2); - mpi_free (z3); - } - z1 = mpi_copy (ctx->one); + gcry_mpi_t x1, y1, z1, k, h, yy; + unsigned int i, loops; + mpi_point_t p1, p2, p1inv; - mpi_mul (h, k, ctx->three); /* h = 3k */ - loops = mpi_get_nbits (h); - if (loops < 2) - { - /* If SCALAR is zero, the above mpi_mul sets H to zero and thus - LOOPs will be zero. To avoid an underflow of I in the main - loop we set LOOP to 2 and the result to (0,0,0). */ - loops = 2; - mpi_clear (result->x); - mpi_clear (result->y); - mpi_clear (result->z); - } - else - { - mpi_set (result->x, point->x); - mpi_set (result->y, yy); - mpi_set (result->z, point->z); - } - mpi_free (yy); yy = NULL; + x1 = mpi_alloc_like (ctx->p); + y1 = mpi_alloc_like (ctx->p); + h = mpi_alloc_like (ctx->p); + k = mpi_copy (scalar); + yy = mpi_copy (point->y); - p1.x = x1; x1 = NULL; - p1.y = y1; y1 = NULL; - p1.z = z1; z1 = NULL; - point_init (&p2); - point_init (&p1inv); + if ( mpi_is_neg (k) ) + { + k->sign = 0; + ec_invm (yy, yy, ctx); + } - for (i=loops-2; i > 0; i--) - { - _gcry_mpi_ec_dup_point (result, result, ctx); - if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0) + if (!mpi_cmp_ui (point->z, 1)) + { + mpi_set (x1, point->x); + mpi_set (y1, yy); + } + else { - point_set (&p2, result); - _gcry_mpi_ec_add_points (result, &p2, &p1, ctx); + gcry_mpi_t z2, z3; + + z2 = mpi_alloc_like (ctx->p); + z3 = mpi_alloc_like (ctx->p); + ec_mulm (z2, point->z, point->z, ctx); + ec_mulm (z3, point->z, z2, ctx); + ec_invm (z2, z2, ctx); + ec_mulm (x1, point->x, z2, ctx); + ec_invm (z3, z3, ctx); + ec_mulm (y1, yy, z3, ctx); + mpi_free (z2); + mpi_free (z3); } - if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1) + z1 = mpi_copy (ctx->one); + + mpi_mul (h, k, ctx->three); /* h = 3k */ + loops = mpi_get_nbits (h); + if (loops < 2) { - point_set (&p2, result); - /* Invert point: y = p - y mod p */ - point_set (&p1inv, &p1); - ec_subm (p1inv.y, ctx->p, p1inv.y, ctx); - _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx); + /* If SCALAR is zero, the above mpi_mul sets H to zero and thus + LOOPs will be zero. To avoid an underflow of I in the main + loop we set LOOP to 2 and the result to (0,0,0). */ + loops = 2; + mpi_clear (result->x); + mpi_clear (result->y); + mpi_clear (result->z); + } + else + { + mpi_set (result->x, point->x); + mpi_set (result->y, yy); + mpi_set (result->z, point->z); + } + mpi_free (yy); yy = NULL; + + p1.x = x1; x1 = NULL; + p1.y = y1; y1 = NULL; + p1.z = z1; z1 = NULL; + point_init (&p2); + point_init (&p1inv); + + for (i=loops-2; i > 0; i--) + { + _gcry_mpi_ec_dup_point (result, result, ctx); + if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0) + { + point_set (&p2, result); + _gcry_mpi_ec_add_points (result, &p2, &p1, ctx); + } + if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1) + { + point_set (&p2, result); + /* Invert point: y = p - y mod p */ + point_set (&p1inv, &p1); + ec_subm (p1inv.y, ctx->p, p1inv.y, ctx); + _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx); + } } + + point_free (&p1); + point_free (&p2); + point_free (&p1inv); + mpi_free (h); + mpi_free (k); } +} + + +/* Return true if POINT is on the curve described by CTX. */ +int +_gcry_mpi_ec_curve_point (mpi_point_t *point, gcry_mpi_t b, mpi_ec_t ctx) +{ + int res = 0; + gcry_mpi_t x, y, w; + gcry_mpi_t xxx; + + x = mpi_new (0); + y = mpi_new (0); + w = mpi_new (0); + xxx = mpi_new (0); + + if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + goto leave; + + /* y^2 == x^3 + a?x + b */ + ec_mulm (y, y, y, ctx); + + ec_mulm (xxx, x, x, ctx); + ec_mulm (xxx, xxx, x, ctx); + ec_mulm (w, ctx->a, x, ctx); + ec_addm (w, w, b, ctx); + ec_addm (w, w, xxx, ctx); + + if (!mpi_cmp (y, w)) + res = 1; + + leave: + _gcry_mpi_release (xxx); + _gcry_mpi_release (w); + _gcry_mpi_release (x); + _gcry_mpi_release (y); - point_free (&p1); - point_free (&p2); - point_free (&p1inv); - mpi_free (h); - mpi_free (k); -#endif + return res; } diff --git a/src/mpi.h b/src/mpi.h index 65a4f97..adc65e2 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -257,7 +257,7 @@ void _gcry_mpi_ec_add_points (mpi_point_t *result, void _gcry_mpi_ec_mul_point (mpi_point_t *result, gcry_mpi_t scalar, mpi_point_t *point, mpi_ec_t ctx); - +int _gcry_mpi_ec_curve_point (mpi_point_t *point, gcry_mpi_t b, mpi_ec_t ctx); #endif /*G10_MPI_H*/ ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 11 ++- mpi/ec.c | 226 +++++++++++++++++++++++++++++++++++------------------------ src/mpi.h | 2 +- 3 files changed, 145 insertions(+), 94 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 11 13:41:12 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Thu, 11 Feb 2016 13:41:12 +0100 Subject: [git] gnupg-doc - branch, master, updated. be5354a8f7af9822f9e2b5fcbd51b7ac5b487a63 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via be5354a8f7af9822f9e2b5fcbd51b7ac5b487a63 (commit) from 07bd2c3f8b218c788f0aa1f6cf8e1a26b56bb514 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be5354a8f7af9822f9e2b5fcbd51b7ac5b487a63 Author: Justus Winter Date: Thu Feb 11 13:41:06 2016 +0100 web/documentation: add link to the wiki diff --git a/web/documentation/index.org b/web/documentation/index.org index 32e8c6f..4be0b8d 100644 --- a/web/documentation/index.org +++ b/web/documentation/index.org @@ -20,6 +20,8 @@ hosted on this server and gives instruction on how to subscribe. Links to other GnuPG-related discussion groups are also available. + - [[http://wiki.gnupg.org][Wiki]] :: The official GnuPG Wiki contains community-maintained + documentation for GnuPG and related software. - [[file:bts.org][BTS]] :: Before you report a bug, please consult the list of bugs. - [[http://twitter.com/gnupg][@gnupg]] :: We sometimes post short messages to Twitter. ----------------------------------------------------------------------- Summary of changes: web/documentation/index.org | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 02:37:48 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 12 Feb 2016 02:37:48 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-9-gd9f9b3b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via d9f9b3be036747c9f55060aed47896f951bfb853 (commit) from 75311cfe18071b94c66121a9785b133b6df345a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d9f9b3be036747c9f55060aed47896f951bfb853 Author: NIIBE Yutaka Date: Fri Feb 12 10:10:33 2016 +0900 g10: Make sure to have the directory for trustdb. * g10/tdbio.c (tdbio_set_dbname): Return earlier if !CREATE. Check the directory and create it if none before calling take_write_lock. -- Thanks to Marc Deslauriers for the bug report and his patch. GnuPG-bug-id: 2246 Signed-off-by: NIIBE Yutaka diff --git a/g10/tdbio.c b/g10/tdbio.c index 3cc8bd3..79e1e83 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -603,9 +603,10 @@ create_version_record (void) int tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) { - char *fname; + char *fname, *p; struct stat statbuf; static int initialized = 0; + int save_slash; if (!initialized) { @@ -643,11 +644,48 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) /* OK, we have the valid trustdb.gpg already. */ return 0; } + else if (!create) + { + *r_nofile = 1; + return 0; + } + + /* Here comes: No valid trustdb.gpg AND CREATE==1 */ + + /* + * Make sure the directory exists. This should be done before + * acquiring the lock, which assumes the existence of the directory. + */ + p = strrchr (fname, DIRSEP_C); +#if HAVE_W32_SYSTEM + { + /* Windows may either have a slash or a backslash. Take + care of it. */ + char *pp = strrchr (fname, '/'); + if (!p || pp > p) + p = pp; + } +#endif /*HAVE_W32_SYSTEM*/ + assert (p); + save_slash = *p; + *p = 0; + if (access (fname, F_OK)) + { + try_make_homedir (fname); + if (access (fname, F_OK)) + log_fatal (_("%s: directory does not exist!\n"), fname); + } + *p = save_slash; take_write_lock (); if (access (fname, R_OK)) { + FILE *fp; + TRUSTREC rec; + int rc; + mode_t oldmask; + #ifdef HAVE_W32CE_SYSTEM /* We know how the cegcc implementation of access works ;-). */ if (GetLastError () == ERROR_FILE_NOT_FOUND) @@ -658,66 +696,34 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile) if (errno != ENOENT) log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno)); - if (!create) - *r_nofile = 1; - else + oldmask = umask (077); + if (is_secured_filename (fname)) { - FILE *fp; - TRUSTREC rec; - int rc; - char *p = strrchr (fname, DIRSEP_C); - mode_t oldmask; - int save_slash; - -#if HAVE_W32_SYSTEM - { - /* Windows may either have a slash or a backslash. Take - care of it. */ - char *pp = strrchr (fname, '/'); - if (!p || pp > p) - p = pp; - } -#endif /*HAVE_W32_SYSTEM*/ - assert (p); - save_slash = *p; - *p = 0; - if (access (fname, F_OK)) - { - try_make_homedir (fname); - if (access (fname, F_OK)) - log_fatal (_("%s: directory does not exist!\n"), fname); - } - *p = save_slash; - - oldmask = umask (077); - if (is_secured_filename (fname)) - { - fp = NULL; - gpg_err_set_errno (EPERM); - } - else - fp = fopen (fname, "wb"); - umask(oldmask); - if (!fp) - log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno)); - fclose (fp); + fp = NULL; + gpg_err_set_errno (EPERM); + } + else + fp = fopen (fname, "wb"); + umask(oldmask); + if (!fp) + log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno)); + fclose (fp); - db_fd = open (db_name, O_RDWR | MY_O_BINARY); - if (db_fd == -1) - log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno)); + db_fd = open (db_name, O_RDWR | MY_O_BINARY); + if (db_fd == -1) + log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno)); - rc = create_version_record (); - if (rc) - log_fatal (_("%s: failed to create version record: %s"), - fname, gpg_strerror (rc)); + rc = create_version_record (); + if (rc) + log_fatal (_("%s: failed to create version record: %s"), + fname, gpg_strerror (rc)); - /* Read again to check that we are okay. */ - if (tdbio_read_record (0, &rec, RECTYPE_VER)) - log_fatal (_("%s: invalid trustdb created\n"), db_name); + /* Read again to check that we are okay. */ + if (tdbio_read_record (0, &rec, RECTYPE_VER)) + log_fatal (_("%s: invalid trustdb created\n"), db_name); - if (!opt.quiet) - log_info (_("%s: trustdb created\n"), db_name); - } + if (!opt.quiet) + log_info (_("%s: trustdb created\n"), db_name); } release_write_lock (); ----------------------------------------------------------------------- Summary of changes: g10/tdbio.c | 118 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 62 insertions(+), 56 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 02:38:16 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 12 Feb 2016 02:38:16 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.20-7-gd957e43 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via d957e4388f72581b1ec801613b5629b5ea3f586d (commit) from 22caa5c2d4b65289a0857c36bcded36b34baf4d2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d957e4388f72581b1ec801613b5629b5ea3f586d Author: NIIBE Yutaka Date: Fri Feb 12 10:00:31 2016 +0900 g10: Make sure to have the directory for trustdb. * g10/tdbio.c (tdbio_set_dbname): Return earlier if !CREATE. Check the directory and create it if none before calling take_write_lock. -- Thanks to Marc Deslauriers for the bug report and his patch. GnuPG-bug-id: 2246 Signed-off-by: NIIBE Yutaka (backport from master commit 2f3e42047d17313eeb38d354048f343158402a8d) diff --git a/g10/tdbio.c b/g10/tdbio.c index 9d722c2..b01b550 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -477,7 +477,7 @@ create_version_record (void) int tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile) { - char *fname; + char *fname, *p; struct stat statbuf; static int initialized = 0; @@ -512,57 +512,64 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile) if (stat (fname, &statbuf) == 0 && statbuf.st_size > 0) /* OK, we have the valid trustdb.gpg already. */ return 0; + else if (!create) { + *r_nofile = 1; + return 0; + } + + /* Here comes: No valid trustdb.gpg AND CREATE==1 */ + + /* + * Make sure the directory exists. This should be done before + * acquiring the lock, which assumes the directory existence. + */ + p = strrchr( fname, DIRSEP_C ); + assert(p); /* See the code above. Always, it has DIRSEP_C. */ + *p = 0; + if( access( fname, F_OK ) ) { + try_make_homedir( fname ); + if (access (fname, F_OK )) + log_fatal (_("%s: directory does not exist!\n"), p); + } + *p = DIRSEP_C; take_write_lock (); + /* Check the file after aquiring the lock. */ if( access( fname, R_OK ) ) { + FILE *fp; + TRUSTREC rec; + int rc; + mode_t oldmask; + if( errno != ENOENT ) log_fatal( _("can't access `%s': %s\n"), fname, strerror(errno) ); - if (!create) - *r_nofile = 1; - else { - FILE *fp; - TRUSTREC rec; - int rc; - char *p = strrchr( fname, DIRSEP_C ); - mode_t oldmask; - - assert(p); - *p = 0; - if( access( fname, F_OK ) ) { - try_make_homedir( fname ); - if (access (fname, F_OK )) - log_fatal (_("%s: directory does not exist!\n"), fname); - } - *p = DIRSEP_C; - - oldmask=umask(077); - if (is_secured_filename (fname)) { - fp = NULL; - errno = EPERM; - } - else - fp =fopen( fname, "wb" ); - umask(oldmask); - if( !fp ) - log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) ); - fclose(fp); - db_fd = open( db_name, O_RDWR | MY_O_BINARY ); - if( db_fd == -1 ) - log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) ); - - rc = create_version_record (); - if( rc ) - log_fatal( _("%s: failed to create version record: %s"), - fname, g10_errstr(rc)); - /* and read again to check that we are okay */ - if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) - log_fatal( _("%s: invalid trustdb created\n"), db_name ); - - if( !opt.quiet ) - log_info(_("%s: trustdb created\n"), db_name); - } + oldmask=umask(077); + if (is_secured_filename (fname)) { + fp = NULL; + errno = EPERM; + } + else + fp =fopen( fname, "wb" ); + umask(oldmask); + if( !fp ) + log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) ); + fclose(fp); + db_fd = open( db_name, O_RDWR | MY_O_BINARY ); + if( db_fd == -1 ) + log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) ); + + rc = create_version_record (); + if( rc ) + log_fatal( _("%s: failed to create version record: %s"), + fname, g10_errstr(rc)); + /* and read again to check that we are okay */ + if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) + log_fatal( _("%s: invalid trustdb created\n"), db_name ); + + if( !opt.quiet ) + log_info(_("%s: trustdb created\n"), db_name); } release_write_lock (); ----------------------------------------------------------------------- Summary of changes: g10/tdbio.c | 97 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 45 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 02:38:02 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 12 Feb 2016 02:38:02 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.29-21-geb7806d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via eb7806d63df63663170ba86f0673caa34b944c28 (commit) from 776bee6d370602ff95e93a4aea6a70005dff9ae6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eb7806d63df63663170ba86f0673caa34b944c28 Author: NIIBE Yutaka Date: Fri Feb 12 10:15:52 2016 +0900 g10: Make sure to have the directory for trustdb. * g10/tdbio.c (tdbio_set_dbname): Return earlier if !CREATE. Check the directory and create it if none before calling take_write_lock. -- Thanks to Marc Deslauriers for the bug report and his patch. GnuPG-bug-id: 2246 Signed-off-by: NIIBE Yutaka (backport from master commit 2f3e42047d17313eeb38d354048f343158402a8d) diff --git a/g10/tdbio.c b/g10/tdbio.c index 84a0ba6..5c2fdd1 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -479,9 +479,10 @@ create_version_record (void) int tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile) { - char *fname; + char *fname, *p; struct stat statbuf; static int initialized = 0; + int save_slash; if( !initialized ) { atexit( cleanup ); @@ -514,68 +515,75 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile) if (stat (fname, &statbuf) == 0 && statbuf.st_size > 0) /* OK, we have the valid trustdb.gpg already. */ return 0; + else if (!create) + { + *r_nofile = 1; + return 0; + } + + /* Here comes: No valid trustdb.gpg AND CREATE==1 */ + + /* + * Make sure the directory exists. This should be done before + * acquiring the lock, which assumes the existence of the directory. + */ + p = strrchr( fname, DIRSEP_C ); +#if HAVE_W32_SYSTEM + { + /* Windows may either have a slash or a backslash. Take + care of it. */ + char *pp = strrchr (fname, '/'); + if (!p || pp > p) + p = pp; + } +#endif /*HAVE_W32_SYSTEM*/ + assert (p); + save_slash = *p; + *p = 0; + if ( access( fname, F_OK ) ) { + try_make_homedir( fname ); + if (access (fname, F_OK )) + log_fatal (_("%s: directory does not exist!\n"), fname); + } + *p = save_slash; take_write_lock (); if( access( fname, R_OK ) ) { + FILE *fp; + TRUSTREC rec; + int rc; + mode_t oldmask; + if( errno != ENOENT ) log_fatal( _("can't access `%s': %s\n"), fname, strerror(errno) ); - if (!create) - *r_nofile = 1; - else { - FILE *fp; - TRUSTREC rec; - int rc; - char *p = strrchr( fname, DIRSEP_C ); - mode_t oldmask; - int save_slash; -#if HAVE_W32_SYSTEM - { - /* Windows may either have a slash or a backslash. Take - care of it. */ - char *pp = strrchr (fname, '/'); - if (!p || pp > p) - p = pp; - } -#endif /*HAVE_W32_SYSTEM*/ - assert (p); - save_slash = *p; - *p = 0; - if( access( fname, F_OK ) ) { - try_make_homedir( fname ); - if (access (fname, F_OK )) - log_fatal (_("%s: directory does not exist!\n"), fname); - } - *p = save_slash; - - oldmask=umask(077); - if (is_secured_filename (fname)) { - fp = NULL; - errno = EPERM; - } - else - fp =fopen( fname, "wb" ); - umask(oldmask); - if( !fp ) - log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) ); - fclose(fp); - db_fd = open( db_name, O_RDWR | MY_O_BINARY ); - if( db_fd == -1 ) - log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) ); - - rc = create_version_record (); - if( rc ) - log_fatal( _("%s: failed to create version record: %s"), - fname, g10_errstr(rc)); - /* and read again to check that we are okay */ - if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) - log_fatal( _("%s: invalid trustdb created\n"), db_name ); - - if( !opt.quiet ) - log_info(_("%s: trustdb created\n"), db_name); - } + oldmask=umask(077); + if (is_secured_filename (fname)) { + fp = NULL; + errno = EPERM; + } + else + fp =fopen( fname, "wb" ); + umask(oldmask); + if( !fp ) + log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) ); + fclose(fp); + db_fd = open( db_name, O_RDWR | MY_O_BINARY ); + if( db_fd == -1 ) + log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) ); + + rc = create_version_record (); + if( rc ) + log_fatal( _("%s: failed to create version record: %s"), + fname, g10_errstr(rc)); + /* and read again to check that we are okay */ + if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) + log_fatal( _("%s: invalid trustdb created\n"), db_name ); + + if( !opt.quiet ) + log_info(_("%s: trustdb created\n"), db_name); } release_write_lock (); ----------------------------------------------------------------------- Summary of changes: g10/tdbio.c | 118 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 63 insertions(+), 55 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 05:51:50 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 12 Feb 2016 05:51:50 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-316-g7a019bc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 7a019bc7ecdbdfdef51094e090ce95e062da9b64 (commit) from b12dd550fd6af687ef95c584d0d8366c34965cc8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7a019bc7ecdbdfdef51094e090ce95e062da9b64 Author: NIIBE Yutaka Date: Fri Feb 12 13:50:02 2016 +0900 ecc: Not validate input point for Curve25519. * cipher/ecc.c (ecc_decrypt_raw): Curve25519 is an exception. -- Signed-off-by: NIIBE Yutaka diff --git a/cipher/ecc.c b/cipher/ecc.c index d1fe823..4cdbb14 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1570,7 +1570,9 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) if (DBG_CIPHER) log_printpnt ("ecc_decrypt kG", &kG, NULL); - if (!_gcry_mpi_ec_curve_point (&kG, ec)) + if (!(curvename && !strcmp (curvename, "Curve25519")) + /* For Curve25519, by its definition, validation should not be done. */ + && !_gcry_mpi_ec_curve_point (&kG, ec)) { rc = GPG_ERR_INV_DATA; goto leave; ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 15:19:32 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Fri, 12 Feb 2016 15:19:32 +0100 Subject: [git] gnupg-doc - branch, master, updated. 2c5e9e9e73098be7974ffee59a7ea5676dd35cb9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GnuPG website and other docs". The branch, master has been updated via 2c5e9e9e73098be7974ffee59a7ea5676dd35cb9 (commit) from be5354a8f7af9822f9e2b5fcbd51b7ac5b487a63 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2c5e9e9e73098be7974ffee59a7ea5676dd35cb9 Author: Justus Winter Date: Fri Feb 12 15:19:27 2016 +0100 web/documentation: link to https://wiki.gnupg.org diff --git a/web/documentation/index.org b/web/documentation/index.org index 4be0b8d..66ff139 100644 --- a/web/documentation/index.org +++ b/web/documentation/index.org @@ -20,7 +20,7 @@ hosted on this server and gives instruction on how to subscribe. Links to other GnuPG-related discussion groups are also available. - - [[http://wiki.gnupg.org][Wiki]] :: The official GnuPG Wiki contains community-maintained + - [[https://wiki.gnupg.org][Wiki]] :: The official GnuPG Wiki contains community-maintained documentation for GnuPG and related software. - [[file:bts.org][BTS]] :: Before you report a bug, please consult the list of bugs. - [[http://twitter.com/gnupg][@gnupg]] :: We sometimes post short messages to Twitter. ----------------------------------------------------------------------- Summary of changes: web/documentation/index.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GnuPG website and other docs http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 16:58:52 2016 From: cvs at cvs.gnupg.org (by Andreas Metzler) Date: Fri, 12 Feb 2016 16:58:52 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-317-g1c9cc46 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 1c9cc46562fd7f260f481028b5821f5ae910dc32 (commit) from 7a019bc7ecdbdfdef51094e090ce95e062da9b64 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1c9cc46562fd7f260f481028b5821f5ae910dc32 Author: Andreas Metzler Date: Fri Feb 12 14:19:23 2016 +0100 Document more non LGPL-licensed code. -- Add license and copyright statement for cipher/arcfour-amd64.S (public domain) and cipher/cipher-ocb.c (OCB license 1) diff --git a/LICENSES b/LICENSES index ff8b7fa..ebc18b3 100644 --- a/LICENSES +++ b/LICENSES @@ -84,3 +84,110 @@ with any binary distributions derived from the GNU C Library. ings in this Software without prior written authorization from the X Consor- tium. #+end_quote + +* Public domain + + For files: + - cipher/arcfour-amd64.S + +#+begin_quote + Author: Marc Bevand + Licence: I hereby disclaim the copyright on this code and place it + in the public domain. +#+end_quote + +* OCB license 1 + + For files: + - cipher/cipher-ocb.c + +#+begin_quote + OCB is covered by several patents but may be used freely by most + software. See http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm . + In particular license 1 is suitable for Libgcrypt: See + http://web.cs.ucdavis.edu/~rogaway/ocb/license1.pdf for the full + license document; it basically says: + + License 1 ? License for Open-Source Software Implementations of OCB + (Jan 9, 2013) + + Under this license, you are authorized to make, use, and + distribute open-source software implementations of OCB. This + license terminates for you if you sue someone over their + open-source software implementation of OCB claiming that you have + a patent covering their implementation. + + + + License for Open Source Software Implementations of OCB + January 9, 2013 + + 1 Definitions + + 1.1 ?Licensor? means Phillip Rogaway. + + 1.2 ?Licensed Patents? means any patent that claims priority to United + States Patent Application No. 09/918,615 entitled ?Method and Apparatus + for Facilitating Efficient Authenticated Encryption,? and any utility, + divisional, provisional, continuation, continuations-in-part, reexamination, + reissue, or foreign counterpart patents that may issue with respect to the + aforesaid patent application. This includes, but is not limited to, United + States Patent No. 7,046,802; United States Patent No. 7,200,227; United + States Patent No. 7,949,129; United States Patent No. 8,321,675 ; and any + patent that issues out of United States Patent Application No. 13/669,114. + + 1.3 ?Use? means any practice of any invention claimed in the Licensed Patents. + + 1.4 ?Software Implementation? means any practice of any invention + claimed in the Licensed Patents that takes the form of software executing on + a user-programmable, general-purpose computer or that takes the form of a + computer-readable medium storing such software. Software Implementation does + not include, for example, application-specific integrated circuits (ASICs), + field-programmable gate arrays (FPGAs), embedded systems, or IP cores. + + 1.5 ?Open Source Software? means software whose source code is published + and made available for inspection and use by anyone because either (a) the + source code is subject to a license that permits recipients to copy, modify, + and distribute the source code without payment of fees or royalties, or + (b) the source code is in the public domain, including code released for + public use through a CC0 waiver. All licenses certified by the Open Source + Initiative at opensource.org as of January 9, 2013 and all Creative Commons + licenses identified on the creativecommons.org website as of January 9, + 2013, including the Public License Fallback of the CC0 waiver, satisfy these + requirements for the purposes of this license. + + 1.6 ?Open Source Software Implementation? means a Software + Implementation in which the software implicating the Licensed Patents is + Open Source Software. Open Source Software Implementation does not include + any Software Implementation in which the software implicating the Licensed + Patents is combined, so as to form a larger program, with software that is + not Open Source Software. + + 2 License Grant + + 2.1 License. Subject to your compliance with the term s of this license, + including the restriction set forth in Section 2.2, Licensor hereby + grants to you a perpetual, worldwide, non-exclusive, non-transferable, + non-sublicenseable, no-charge, royalty-free, irrevocable license to practice + any invention claimed in the Licensed Patents in any Open Source Software + Implementation. + + 2.2 Restriction. If you or your affiliates institute patent litigation + (including, but not limited to, a cross-claim or counterclaim in a lawsuit) + against any entity alleging that any Use authorized by this license + infringes another patent, then any rights granted to you under this license + automatically terminate as of the date such litigation is filed. + + 3 Disclaimer + YOUR USE OF THE LICENSED PATENTS IS AT YOUR OWN RISK AND UNLESS REQUIRED + BY APPLICABLE LAW, LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY + KIND CONCERNING THE LICENSED PATENTS OR ANY PRODUCT EMBODYING ANY LICENSED + PATENT, EXPRESS OR IMPLIED, STATUT ORY OR OTHERWISE, INCLUDING, WITHOUT + LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR + PURPOSE, OR NONINFRINGEMENT. IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM OR RELATED TO ANY USE OF THE LICENSED PATENTS, INCLUDING, + WITHOUT LIMITATION, DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE + OR SPECIAL DAMAGES, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGES PRIOR TO SUCH AN OCCURRENCE. +#+end_quote ----------------------------------------------------------------------- Summary of changes: LICENSES | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 12 22:12:38 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Fri, 12 Feb 2016 22:12:38 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-10-gacac103 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via acac103ba5772ae738ce5409d17feab80596cde6 (commit) from d9f9b3be036747c9f55060aed47896f951bfb853 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit acac103ba5772ae738ce5409d17feab80596cde6 Author: Neal H. Walfield Date: Fri Feb 12 22:12:21 2016 +0100 common: Change simple_query to ignore status messages. * common/simple-pwquery.c (simple_query): Ignore status messages. -- Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2229 diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 90d04c0..b2d666c 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -618,6 +618,7 @@ simple_query (const char *query) int fd = -1; int nread; char response[500]; + int have = 0; int rc; rc = agent_open (&fd); @@ -628,40 +629,78 @@ simple_query (const char *query) if (rc) goto leave; - /* get response */ - nread = readline (fd, response, 499); - if (nread < 0) - { - rc = -nread; - goto leave; - } - if (nread < 3) + while (1) { - rc = SPWQ_PROTOCOL_ERROR; - goto leave; - } + if (! have || ! strchr (response, '\n')) + /* get response */ + { + nread = readline (fd, &response[have], + sizeof (response) - 1 /* NUL */ - have); + if (nread < 0) + { + rc = -nread; + goto leave; + } + have += nread; + if (have < 3) + { + rc = SPWQ_PROTOCOL_ERROR; + goto leave; + } + response[have] = 0; + } - if (response[0] == 'O' && response[1] == 'K') - /* OK, do nothing. */; - else if ((nread > 7 && !memcmp (response, "ERR 111", 7) - && (response[7] == ' ' || response[7] == '\n') ) - || ((nread > 4 && !memcmp (response, "ERR ", 4) - && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) - { - /* 111 is the old Assuan code for canceled which might still - be in use by old installations. 99 is GPG_ERR_CANCELED as - used by modern gpg-agents; 0xffff is used to mask out the - error source. */ + if (response[0] == 'O' && response[1] == 'K') + /* OK, do nothing. */; + else if ((nread > 7 && !memcmp (response, "ERR 111", 7) + && (response[7] == ' ' || response[7] == '\n') ) + || ((nread > 4 && !memcmp (response, "ERR ", 4) + && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) + { + /* 111 is the old Assuan code for canceled which might still + be in use by old installations. 99 is GPG_ERR_CANCELED as + used by modern gpg-agents; 0xffff is used to mask out the + error source. */ #ifdef SPWQ_USE_LOGGING - log_info (_("canceled by user\n") ); + log_info (_("canceled by user\n") ); #endif - } - else - { + } + else if (response[0] == 'S' && response[1] == ' ') + { + char *nextline; + int consumed; + + nextline = strchr (response, '\n'); + if (! nextline) + /* Point to the NUL. */ + nextline = &response[have]; + else + /* Move past the \n. */ + nextline ++; + + consumed = (size_t) nextline - (size_t) response; + + /* Skip any additional newlines. */ + while (consumed < have && response[consumed] == '\n') + consumed ++; + + have -= consumed; + + if (have) + memmove (response, &response[consumed], have + 1); + + continue; + } + else + { #ifdef SPWQ_USE_LOGGING - log_error (_("problem with the agent\n")); + log_error (_("problem with the agent (unexpected response \"%s\"\n"), + response); #endif - rc = SPWQ_ERR_RESPONSE; + rc = SPWQ_ERR_RESPONSE; + } + + break; } leave: ----------------------------------------------------------------------- Summary of changes: common/simple-pwquery.c | 95 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 28 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 13 19:13:34 2016 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 13 Feb 2016 19:13:34 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-318-g1da793d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 1da793d089b65ac8c1ead65dacb6b8699f5b6e69 (commit) from 1c9cc46562fd7f260f481028b5821f5ae910dc32 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1da793d089b65ac8c1ead65dacb6b8699f5b6e69 Author: Jussi Kivilinna Date: Sat Feb 13 20:12:58 2016 +0200 bufhelp: disable unaligned memory accesses on powerpc * cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Disable for __powerpc__ and __powerpc64__. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index c1aa52e..aec4f1c 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -27,7 +27,6 @@ #if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ (defined(__i386__) || defined(__x86_64__) || \ - defined(__powerpc__) || defined(__powerpc64__) || \ (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ defined(__aarch64__)) /* These architectures are able of unaligned memory accesses and can ----------------------------------------------------------------------- Summary of changes: cipher/bufhelp.h | 1 - 1 file changed, 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 14 14:51:14 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Sun, 14 Feb 2016 14:51:14 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-27-g9663b08 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 9663b088480cef6734a3c5892d5ddbbd60ecc1a4 (commit) via 5cdde08ea869ef02111f618ad782d392a296eb7f (commit) via c0268c449d0f3d23be5ec7b92fe92e7e078166cf (commit) via ad43dc6cfc2b610a4e34fe55811bd937f9c3238b (commit) from 86f3bb144ad75461eb9b7ac1e59046ac75efccac (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9663b088480cef6734a3c5892d5ddbbd60ecc1a4 Author: Neal H. Walfield Date: Wed Feb 3 14:23:51 2016 +0100 gpg: Improve API documentation. * g10/seskey.c (make_session_key): Improve documentation. (encode_session_key): Improve documentation. * g10/encrypt.c (encrypt_seskey): Remove gratuitous initialization. * g10/dek.h (DEK): Improve documenation. -- Signed-off-by: Neal H. Walfield diff --git a/g10/dek.h b/g10/dek.h index 31ebbb6..1a879e3 100644 --- a/g10/dek.h +++ b/g10/dek.h @@ -22,10 +22,16 @@ typedef struct { + /* The algorithm (e.g., CIPHER_ALGO_AES). */ int algo; + /* The length of the key (in bytes). */ int keylen; + /* Whether we've already printed information about this key. This + is currently only used in decrypt_data() and only if we are in + verbose mode. */ int algo_info_printed; int use_mdc; + /* This key was read from a SK-ESK packet (see proc_symkey_enc). */ int symmetric; byte key[32]; /* This is the largest used keylen (256 bit). */ char s2k_cacheid[1+16+1]; diff --git a/g10/encrypt.c b/g10/encrypt.c index abd8002..46b0be0 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -75,7 +75,6 @@ encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey) if (!*seskey) { *seskey=xmalloc_clear(sizeof(DEK)); - (*seskey)->keylen=dek->keylen; (*seskey)->algo=dek->algo; make_session_key(*seskey); /*log_hexdump( "thekey", c->key, c->keylen );*/ @@ -326,7 +325,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) if (!opt.no_literal) { - /* Note that PT has been initialized above in no_literal mode. */ + /* Note that PT has been initialized above in !no_literal mode. */ pt->timestamp = make_timestamp(); pt->mode = opt.textmode? 't' : 'b'; pt->len = filesize; diff --git a/g10/seskey.c b/g10/seskey.c index e79faf8..507eea1 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -31,9 +31,11 @@ #include "i18n.h" -/**************** - * Make a session key and put it into DEK - */ +/* Generate a new session key in *DEK that is appropriate for the + algorithm DEK->ALGO (i.e., ensure that the key is not weak). + + This function overwrites DEK->KEYLEN, DEK->KEY. The rest of the + fields are left as is. */ void make_session_key( DEK *dek ) { @@ -67,11 +69,12 @@ make_session_key( DEK *dek ) } -/**************** - * Encode the session key. NBITS is the number of bits which should be used - * for packing the session key. - * returns: A mpi with the session key (caller must free) - */ +/* Encode the session key stored in DEK as an MPI in preparation to + encrypt it with the public key algorithm OPENPGP_PK_ALGO with a key + whose length (the size of the public key) is NBITS. + + On success, returns an MPI, which the caller must free using + gcry_mpi_release(). */ gcry_mpi_t encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { @@ -136,14 +139,15 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) log_bug ("can't encode a %d bit key in a %d bits frame\n", dek->keylen*8, nbits ); - /* We encode the session key in this way: + /* We encode the session key according to PKCS#1 v1.5 (see section + * 13.1.1 of RFC 4880): * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) + * 0 2 RND(i bytes) 0 A DEK(k bytes) CSUM(2 bytes) * * (But how can we store the leading 0 - the external representaion * of MPIs doesn't allow leading zeroes =:-) * - * RND are non-zero random bytes. + * RND are (at least 1) non-zero random bytes. * A is the cipher algorithm * DEK is the encryption key (session key) length k depends on the * cipher algorithm (20 is used with blowfish160). @@ -154,6 +158,8 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) n = 0; frame[n++] = 0; frame[n++] = 2; + /* The number of random bytes are the number of otherwise unused + bytes. See diagram above. */ i = nframe - 6 - dek->keylen; assert( i > 0 ); p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); commit 5cdde08ea869ef02111f618ad782d392a296eb7f Author: Neal H. Walfield Date: Tue Feb 2 20:05:45 2016 +0100 gpg: Fix calc_header_length when LEN is 0 and improve documentation. * g10/build-packet.c (calc_header_length): Return the correct haeder size when LEN is 0. Fix documentation. -- Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2240 diff --git a/g10/build-packet.c b/g10/build-packet.c index 269c63c..4245208 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1215,14 +1215,18 @@ write_32(IOBUF out, u32 a) /**************** - * calculate the length of a header + * calculate the length of a header. + * + * LEN is the length of the packet's body. NEW_CTB is whether we are + * using a new or old format packet. + * + * This function does not handle indeterminate lengths or partial body + * lengths. (If you pass LEN as 0, then this function assumes you + * really mean an empty body.) */ static int calc_header_length( u32 len, int new_ctb ) { - if( !len ) - return 1; /* only the ctb */ - if( new_ctb ) { if( len < 192 ) return 2; commit c0268c449d0f3d23be5ec7b92fe92e7e078166cf Author: Neal H. Walfield Date: Mon Feb 8 00:31:35 2016 +0100 gpg: Fix format_keyid when dynamically allocating the buffer. * g10/keyid.c (format_keyid): Return a char *, not a const char *. If BUFFER is NULL, then set LEN to the static buffer's size. -- Signed-off-by: Neal H. Walfield diff --git a/g10/keydb.h b/g10/keydb.h index e679d94..9b4a1cf 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -399,7 +399,7 @@ char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize); #define PUBKEY_STRING_SIZE 32 u32 v3_keyid (gcry_mpi_t a, u32 *ki); void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ); -const char *format_keyid (u32 *keyid, int format, char *buffer, int len); +char *format_keyid (u32 *keyid, int format, char *buffer, int len); size_t keystrlen(void); const char *keystr(u32 *keyid); const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid); diff --git a/g10/keyid.c b/g10/keyid.c index f684276..49eb5f6 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -274,12 +274,15 @@ v3_keyid (gcry_mpi_t a, u32 *ki) } -const char * +char * format_keyid (u32 *keyid, int format, char *buffer, int len) { char tmp[KEYID_STR_SIZE]; if (! buffer) - buffer = tmp; + { + buffer = tmp; + len = sizeof (tmp); + } if (format == KF_DEFAULT) format = opt.keyid_format; commit ad43dc6cfc2b610a4e34fe55811bd937f9c3238b Author: Neal H. Walfield Date: Mon Feb 8 00:30:10 2016 +0100 common: Fix comment. * common/iobuf.c (iobuf_flush_temp): Fix comment. -- Signed-off-by: Neal H. Walfield diff --git a/common/iobuf.c b/common/iobuf.c index b6e7885..00d1b8d 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2260,7 +2260,7 @@ void iobuf_flush_temp (iobuf_t temp) { if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP) - log_bug ("iobuf_writestr called on an input pipeline!\n"); + log_bug ("iobuf_flush_temp called on an input pipeline!\n"); while (temp->chain) pop_filter (temp, temp->filter, NULL); } ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 2 +- g10/build-packet.c | 12 ++++++++---- g10/dek.h | 6 ++++++ g10/encrypt.c | 3 +-- g10/keydb.h | 2 +- g10/keyid.c | 7 +++++-- g10/seskey.c | 28 +++++++++++++++++----------- 7 files changed, 39 insertions(+), 21 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sun Feb 14 16:21:15 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 14 Feb 2016 16:21:15 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-29-g772f6b2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 772f6b29b557e4e80353bc48e34d7214be895f33 (commit) via 9b28b82e7c40d1eacc446d5932cd613c56378ed8 (commit) from 9663b088480cef6734a3c5892d5ddbbd60ecc1a4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 772f6b29b557e4e80353bc48e34d7214be895f33 Author: Werner Koch Date: Sun Feb 14 16:11:06 2016 +0100 Put asterisks in front of two function descriptions. -- This helps visual impaired hackers to easier read comments and also helps use when looking at a printout. diff --git a/g10/seskey.c b/g10/seskey.c index 507eea1..561118a 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -32,10 +32,10 @@ /* Generate a new session key in *DEK that is appropriate for the - algorithm DEK->ALGO (i.e., ensure that the key is not weak). - - This function overwrites DEK->KEYLEN, DEK->KEY. The rest of the - fields are left as is. */ + * algorithm DEK->ALGO (i.e., ensure that the key is not weak). + * + * This function overwrites DEK->KEYLEN, DEK->KEY. The rest of the + * fields are left as is. */ void make_session_key( DEK *dek ) { @@ -70,11 +70,11 @@ make_session_key( DEK *dek ) /* Encode the session key stored in DEK as an MPI in preparation to - encrypt it with the public key algorithm OPENPGP_PK_ALGO with a key - whose length (the size of the public key) is NBITS. - - On success, returns an MPI, which the caller must free using - gcry_mpi_release(). */ + * encrypt it with the public key algorithm OPENPGP_PK_ALGO with a key + * whose length (the size of the public key) is NBITS. + * + * On success, returns an MPI, which the caller must free using + * gcry_mpi_release(). */ gcry_mpi_t encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { commit 9b28b82e7c40d1eacc446d5932cd613c56378ed8 Author: Werner Koch Date: Sun Feb 14 15:50:12 2016 +0100 gpg: Add hidden key-edit subcommand "change-usage". * g10/keyedit.c (cmdCHANGEUSAGE): New. (cmds): Add command "change-usage". (keyedit_menu): Handle that command. (menu_changeusage): New. * g10/keygen.c (keygen_add_key_flags): New. (ask_key_flags): Add optional arg current. -- Signed-off-by: Werner Koch diff --git a/g10/keyedit.c b/g10/keyedit.c index 30f52a4..19ddf29 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -70,6 +70,7 @@ static int menu_clean (KBNODE keyblock, int self_only); static void menu_delkey (KBNODE pub_keyblock); static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive); static int menu_expire (KBNODE pub_keyblock); +static int menu_changeusage (kbnode_t keyblock); static int menu_backsign (KBNODE pub_keyblock); static int menu_set_primary_uid (KBNODE pub_keyblock); static int menu_set_preferences (KBNODE pub_keyblock); @@ -1362,7 +1363,7 @@ enum cmdids cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, - cmdEXPIRE, cmdBACKSIGN, + cmdEXPIRE, cmdCHANGEUSAGE, cmdBACKSIGN, #ifndef NO_TRUST_MODELS cmdENABLEKEY, cmdDISABLEKEY, #endif /*!NO_TRUST_MODELS*/ @@ -1393,6 +1394,7 @@ static struct { "key", cmdSELKEY, 0, N_("select subkey N")}, { "check", cmdCHECK, 0, N_("check signatures")}, { "c", cmdCHECK, 0, NULL}, + { "change-usage", cmdCHANGEUSAGE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL}, { "cross-certify", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL}, { "backsign", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL}, { "sign", cmdSIGN, KEYEDIT_NOT_SK | KEYEDIT_TAIL_MATCH, @@ -2122,6 +2124,15 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, } break; + case cmdCHANGEUSAGE: + if (menu_changeusage (keyblock)) + { + merge_keys_and_selfsig (keyblock); + modified = 1; + redisplay = 1; + } + break; + case cmdBACKSIGN: if (menu_backsign (keyblock)) { @@ -4110,6 +4121,112 @@ menu_expire (KBNODE pub_keyblock) } +/* Change the capability of a selected key. This command should only + * be used to rectify badly created keys and as such is not suggested + * for general use. */ +static int +menu_changeusage (kbnode_t keyblock) +{ + int n1, rc; + int mainkey = 0; + PKT_public_key *main_pk, *sub_pk; + PKT_user_id *uid; + kbnode_t node; + u32 keyid[2]; + + n1 = count_selected_keys (keyblock); + if (n1 > 1) + { + tty_printf (_("You must select exactly one key.\n")); + return 0; + } + else if (n1) + tty_printf ("Changing usage of a subkey.\n"); + else + { + tty_printf ("Changing usage of the primary key.\n"); + mainkey = 1; + } + + /* Now we can actually change the self-signature(s) */ + main_pk = sub_pk = NULL; + uid = NULL; + for (node = keyblock; node; node = node->next) + { + if (node->pkt->pkttype == PKT_PUBLIC_KEY) + { + main_pk = node->pkt->pkt.public_key; + keyid_from_pk (main_pk, keyid); + } + else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + if (node->flag & NODFLG_SELKEY) + sub_pk = node->pkt->pkt.public_key; + else + sub_pk = NULL; + } + else if (node->pkt->pkttype == PKT_USER_ID) + uid = node->pkt->pkt.user_id; + else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE + && (mainkey || sub_pk)) + { + PKT_signature *sig = node->pkt->pkt.signature; + if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] + && ((mainkey && uid + && uid->created && (sig->sig_class & ~3) == 0x10) + || (!mainkey && sig->sig_class == 0x18)) + && sig->flags.chosen_selfsig) + { + /* This is the self-signature which is to be replaced. */ + PKT_signature *newsig; + PACKET *newpkt; + + if ((mainkey && main_pk->version < 4) + || (!mainkey && sub_pk->version < 4)) + { + log_info ("You can't change the capabilities of a v3 key\n"); + return 0; + } + + if (mainkey) + main_pk->pubkey_usage = ask_key_flags (main_pk->pubkey_algo, 0, + main_pk->pubkey_usage); + else + sub_pk->pubkey_usage = ask_key_flags (sub_pk->pubkey_algo, 1, + sub_pk->pubkey_usage); + + if (mainkey) + rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL, + main_pk, keygen_add_key_flags, + main_pk); + else + rc = + update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk, + main_pk, keygen_add_key_flags, sub_pk); + if (rc) + { + log_error ("make_keysig_packet failed: %s\n", + gpg_strerror (rc)); + return 0; + } + + /* Replace the packet. */ + newpkt = xmalloc_clear (sizeof *newpkt); + newpkt->pkttype = PKT_SIGNATURE; + newpkt->pkt.signature = newsig; + free_packet (node->pkt); + xfree (node->pkt); + node->pkt = newpkt; + sub_pk = NULL; + break; + } + } + } + + return 1; +} + + static int menu_backsign (KBNODE pub_keyblock) { diff --git a/g10/keygen.c b/g10/keygen.c index 0f7a6a0..7b5a35b 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -252,6 +252,18 @@ keygen_add_key_expire (PKT_signature *sig, void *opaque) } +/* Add the key usage (i.e. key flags) in SIG from the public keys + * pubkey_usage field. OPAQUE has the public key. */ +int +keygen_add_key_flags (PKT_signature *sig, void *opaque) +{ + PKT_public_key *pk = opaque; + + do_add_key_flags (sig, pk->pubkey_usage); + return 0; +} + + static int keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque) { @@ -1646,9 +1658,10 @@ print_key_flags(int flags) } -/* Returns the key flags */ -static unsigned int -ask_key_flags(int algo,int subkey) +/* Ask for the key flags and return them. CURRENT gives the curren + * usage which should normally be given as 0. */ +unsigned int +ask_key_flags (int algo, int subkey, unsigned int current) { /* TRANSLATORS: Please use only plain ASCII characters for the translation. If this is not possible use single digits. The @@ -1663,7 +1676,6 @@ ask_key_flags(int algo,int subkey) const char *togglers=_("SsEeAaQq"); char *answer=NULL; const char *s; - unsigned int current=0; unsigned int possible=openpgp_pk_algo_usage(algo); if ( strlen(togglers) != 8 ) @@ -1678,8 +1690,12 @@ ask_key_flags(int algo,int subkey) possible&=~PUBKEY_USAGE_CERT; /* Preload the current set with the possible set, minus - authentication, since nobody really uses auth yet. */ - current=possible&~PUBKEY_USAGE_AUTH; + authentication if CURRENT has been given as 0. If CURRENT has + been has non-zero we mask with all possible usages. */ + if (current) + current &= possible; + else + current = (possible&~PUBKEY_USAGE_AUTH); for(;;) { @@ -1922,13 +1938,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, else if ((algo == 7 || !strcmp (answer, "dsa/*")) && opt.expert) { algo = PUBKEY_ALGO_DSA; - *r_usage = ask_key_flags (algo, addmode); + *r_usage = ask_key_flags (algo, addmode, 0); break; } else if ((algo == 8 || !strcmp (answer, "rsa/*")) && opt.expert) { algo = PUBKEY_ALGO_RSA; - *r_usage = ask_key_flags (algo, addmode); + *r_usage = ask_key_flags (algo, addmode, 0); break; } else if ((algo == 9 || !strcmp (answer, "ecc+ecc")) @@ -1947,7 +1963,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, else if ((algo == 11 || !strcmp (answer, "ecc/*")) && opt.expert) { algo = PUBKEY_ALGO_ECDSA; - *r_usage = ask_key_flags (algo, addmode); + *r_usage = ask_key_flags (algo, addmode, 0); break; } else if ((algo == 12 || !strcmp (answer, "ecc/e")) @@ -1985,7 +2001,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, xfree (keygrip); keygrip = answer; answer = NULL; - *r_usage = ask_key_flags (algo, addmode); + *r_usage = ask_key_flags (algo, addmode, 0); break; } else diff --git a/g10/main.h b/g10/main.h index ec24426..863afa9 100644 --- a/g10/main.h +++ b/g10/main.h @@ -280,12 +280,14 @@ void show_basic_key_info (KBNODE keyblock); u32 parse_expire_string(const char *string); u32 ask_expire_interval(int object,const char *def_expire); u32 ask_expiredate(void); +unsigned int ask_key_flags (int algo, int subkey, unsigned int current); void quick_generate_keypair (ctrl_t ctrl, const char *uid); void generate_keypair (ctrl_t ctrl, int full, const char *fname, const char *card_serialno, int card_backup_key); int keygen_set_std_prefs (const char *string,int personal); PKT_user_id *keygen_get_std_prefs (void); int keygen_add_key_expire( PKT_signature *sig, void *opaque ); +int keygen_add_key_flags (PKT_signature *sig, void *opaque); int keygen_add_std_prefs( PKT_signature *sig, void *opaque ); int keygen_upd_std_prefs( PKT_signature *sig, void *opaque ); int keygen_add_keyserver_url(PKT_signature *sig, void *opaque); ----------------------------------------------------------------------- Summary of changes: g10/keyedit.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- g10/keygen.c | 36 +++++++++++++----- g10/main.h | 2 + g10/seskey.c | 18 ++++----- 4 files changed, 155 insertions(+), 20 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 15 03:08:02 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 15 Feb 2016 03:08:02 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-31-gea9cfcf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via ea9cfcfbf76de232221f31787c53d5f46361a9f0 (commit) via 6fbe12a51e8fe2649ffe5a8a02aa93026a8f02cd (commit) from 772f6b29b557e4e80353bc48e34d7214be895f33 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ea9cfcfbf76de232221f31787c53d5f46361a9f0 Author: NIIBE Yutaka Date: Mon Feb 15 11:05:29 2016 +0900 common, g10: Fix indentation to silence GCC-6. * common/iobuf.c (iobuf_ioctl): Fix. * g10/encrypt.c (encrypt_filter): Likewise. * g10/keyring.c (prepare_search): Likewise. -- Signed-off-by: NIIBE Yutaka diff --git a/common/iobuf.c b/common/iobuf.c index 00d1b8d..f5bbfb2 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1515,11 +1515,11 @@ iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval) log_debug ("iobuf-*.*: ioctl '%s' fsync\n", ptrval? (const char*)ptrval:""); - if (!a && !intval && ptrval) - { - return fd_cache_synchronize (ptrval); - } - } + if (!a && !intval && ptrval) + { + return fd_cache_synchronize (ptrval); + } + } return -1; diff --git a/g10/encrypt.c b/g10/encrypt.c index 46b0be0..49ec65b 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -825,18 +825,18 @@ encrypt_filter (void *opaque, int control, if (rc) return rc; - if(efx->symkey_s2k && efx->symkey_dek) - { - rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek, - efx->cfx.dek,a); - if(rc) - return rc; - } + if(efx->symkey_s2k && efx->symkey_dek) + { + rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek, + efx->cfx.dek,a); + if(rc) + return rc; + } - iobuf_push_filter (a, cipher_filter, &efx->cfx); + iobuf_push_filter (a, cipher_filter, &efx->cfx); - efx->header_okay = 1; - } + efx->header_okay = 1; + } rc = iobuf_write (a, buf, size); } diff --git a/g10/keyring.c b/g10/keyring.c index 7c7b355..ee079a9 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -749,8 +749,8 @@ prepare_search (KEYRING_HANDLE hd) if (!hd->current.kr) { if (DBG_LOOKUP) log_debug ("%s: keyring not available!\n", __func__); - hd->current.eof = 1; - return -1; /* keyring not available */ + hd->current.eof = 1; + return -1; /* keyring not available */ } assert (!hd->current.iobuf); } commit 6fbe12a51e8fe2649ffe5a8a02aa93026a8f02cd Author: NIIBE Yutaka Date: Mon Feb 15 10:55:34 2016 +0900 dirmngr: fix for memory alignment. * dirmngr/dns-stuff.c (get_dns_cert): Cast through void *. (getsrv, get_dns_cname): Make sure it's aligned for HEADER. -- Signed-off-by: NIIBE Yutaka diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 40c71f3..191719e 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -821,8 +821,8 @@ get_dns_cert (const char *name, int want_certtype, answer, 65536); /* Not too big, not too small, no errors and at least 1 answer. */ if (r >= sizeof (HEADER) && r <= 65536 - && (((HEADER *) answer)->rcode) == NOERROR - && (count = ntohs (((HEADER *) answer)->ancount))) + && (((HEADER *)(void *) answer)->rcode) == NOERROR + && (count = ntohs (((HEADER *)(void *) answer)->ancount))) { int rc; unsigned char *pt, *emsg; @@ -1081,8 +1081,12 @@ getsrv (const char *name,struct srventry **list) } #else /*!USE_ADNS*/ { - unsigned char answer[2048]; - HEADER *header = (HEADER *)answer; + union { + unsigned char ans[2048]; + HEADER header[1]; + } res; + unsigned char *answer = res.ans; + HEADER *header = res.header; unsigned char *pt, *emsg; int r; u16 dlen; @@ -1305,8 +1309,12 @@ get_dns_cname (const char *name, char **r_cname) } #else /*!USE_ADNS*/ { - unsigned char answer[2048]; - HEADER *header = (HEADER *)answer; + union { + unsigned char ans[2048]; + HEADER header[1]; + } res; + unsigned char *answer = res.ans; + HEADER *header = res.header; unsigned char *pt, *emsg; int r; char *cname; ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 10 +++++----- dirmngr/dns-stuff.c | 20 ++++++++++++++------ g10/encrypt.c | 20 ++++++++++---------- g10/keyring.c | 4 ++-- 4 files changed, 31 insertions(+), 23 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 15 09:15:57 2016 From: cvs at cvs.gnupg.org (by Stef Walter) Date: Mon, 15 Feb 2016 09:15:57 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-0.9.7-3-g2f5bfa0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The standard pinentry collection". The branch, master has been updated via 2f5bfa071ab5eaf86f64404bff448ca29cd0bdb6 (commit) from 954da56c2325c3a5ca628cfc2e3086c1e146a390 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f5bfa071ab5eaf86f64404bff448ca29cd0bdb6 Author: Stef Walter Date: Sun Feb 14 18:06:52 2016 +0100 pinentry: Use stderr to print failures in password-cache.c Otherwise this interferes with the assuan protocol expected on stdout. GnuPG-bug-id: 2243 diff --git a/pinentry/password-cache.c b/pinentry/password-cache.c index 70b33f4..c98c4c5 100644 --- a/pinentry/password-cache.c +++ b/pinentry/password-cache.c @@ -83,7 +83,7 @@ password_cache_save (const char *keygrip, const char *password) "stored-by", "GnuPG Pinentry", "keygrip", keygrip, NULL)) { - printf("Failed to cache password for key %s with secret service: %s\n", + fprintf (stderr, "Failed to cache password for key %s with secret service: %s\n", keygrip, error->message); g_error_free (error); @@ -112,7 +112,7 @@ password_cache_lookup (const char *keygrip) if (error != NULL) { - printf("Failed to lookup password for key %s with secret service: %s\n", + fprintf (stderr, "Failed to lookup password for key %s with secret service: %s\n", keygrip, error->message); g_error_free (error); return NULL; @@ -126,7 +126,7 @@ password_cache_lookup (const char *keygrip) if (password2) strcpy(password2, password); else - printf("secmem_malloc failed: can't copy password!\n"); + fprintf (stderr, "secmem_malloc failed: can't copy password!\n"); secret_password_free (password); @@ -148,7 +148,7 @@ password_cache_clear (const char *keygrip) "keygrip", keygrip, NULL); if (error != NULL) { - printf("Failed to clear password for key %s with secret service: %s\n", + fprintf (stderr, "Failed to clear password for key %s with secret service: %s\n", keygrip, error->message); g_debug("%s", error->message); g_error_free (error); ----------------------------------------------------------------------- Summary of changes: pinentry/password-cache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 16 13:06:33 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 16 Feb 2016 13:06:33 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-32-ga1c1128 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via a1c11283af759c1045a8bb75815db325f415ded4 (commit) from ea9cfcfbf76de232221f31787c53d5f46361a9f0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a1c11283af759c1045a8bb75815db325f415ded4 Author: Werner Koch Date: Tue Feb 16 12:58:53 2016 +0100 doc: Add a gnupg-module-overview picture. * doc/gnupg-module-overview.svg: New. * doc/debugging.texi (Component interaction): New. * doc/Makefile.am (EXTRA_DIST): Add PNG and PDF versions of gnupg-module-overview.svg. Remove two eps files. (BUILT_SOURCES): Add gnupg-module-overview.pdf and .png. Remove gnupg-card-architecture.epsl (gnupg_TEXINFOS): Add gnupg-module-overview.svg (gnupg.dvi): New. (DISTCLEANFILES): Remove build eps files. -- Many thanks to Emanuel Sch?tze for helping with the redesign of the module overview. The original file has been used by mere for years in talks but was never a proper part of GnuPG. The EPS files have been removed due to their size. Thus to build the "dvi" target the convert tool is required. Signed-off-by: Werner Koch diff --git a/doc/Makefile.am b/doc/Makefile.am index a1a570c..c270283 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -33,15 +33,16 @@ helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt \ help.sv.txt help.tr.txt help.zh_CN.txt help.zh_TW.txt EXTRA_DIST = samplekeys.asc mksamplekeys \ - gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png gnupg-logo-tr.png\ - gnupg-card-architecture.eps gnupg-card-architecture.png \ - gnupg-card-architecture.pdf \ + 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 \ FAQ gnupg7.texi mkdefsinc.c defsincdate \ opt-homedir.texi see-also-note.texi specify-user-id.texi \ gpgv.texi yat2m.c ChangeLog-2011 whats-new-in-2.1.txt -BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \ - gnupg-card-architecture.pdf defsincdate defs.inc +BUILT_SOURCES = gnupg-module-overview.png gnupg-module-overview.pdf \ + gnupg-card-architecture.png gnupg-card-architecture.pdf \ + defsincdate defs.inc info_TEXINFOS = gnupg.texi @@ -56,11 +57,18 @@ nobase_dist_doc_DATA = FAQ DETAILS HACKING DCO TRANSLATE OpenPGP KEYSERVER \ gnupg_TEXINFOS = \ gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi instguide.texi \ tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \ - sysnotes.texi gnupg-card-architecture.fig dirmngr.texi \ + sysnotes.texi dirmngr.texi \ + gnupg-module-overview.svg \ + gnupg-card-architecture.fig \ howtos.texi howto-create-a-server-cert.texi gnupg.texi : defs.inc +# We need EPS files for "make distcheck" but we do not want to distribute +# them due to their size. Let's build them as needed. +gnupg.dvi : gnupg-module-overview.eps gnupg-card-architecture.eps + + DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips AM_MAKEINFOFLAGS = -I $(srcdir) --css-ref=/share/site.css @@ -84,6 +92,8 @@ watchgnupg_SOURCE = gnupg.texi CLEANFILES = yat2m mkdefsinc defs.inc DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \ + gnupg-card-architecture.eps \ + gnupg-module-overview.eps \ $(myman_pages) gpg-zip.1 gnupg.7 yat2m: yat2m.c @@ -93,6 +103,14 @@ mkdefsinc: mkdefsinc.c Makefile ../config.h $(CC_FOR_BUILD) -I. -I.. -I$(srcdir) $(AM_CPPFLAGS) \ -o $@ $(srcdir)/mkdefsinc.c +.svg.eps: + convert `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.svg.png: + convert `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.svg.pdf: + convert `test -f '$<' || echo '$(srcdir)/'`$< $@ .fig.png: fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@ @@ -147,10 +165,13 @@ defs.inc : defsincdate Makefile mkdefsinc $(gnupg_TEXINFOS) >$@ -online: gnupg.html gnupg.pdf +online: gnupg.html gnupg.pdf gnupg-module-overview.png \ + gnupg-card-architecture.png set -e; \ echo "Uploading current manuals to www.gnupg.org ..."; \ cp $(srcdir)/gnupg-logo-tr.png gnupg.html/; \ + cp gnupg-module-overview.png gnupg.html/; \ + cp gnupg-card-architecture.png gnupg.html/; \ user=werner ; webhost="ftp.gnupg.org" ; dashdevel="" ; \ if echo "@PACKAGE_VERSION@" | grep -- "-beta" >/dev/null; then \ dashdevel="-devel" ; \ diff --git a/doc/debugging.texi b/doc/debugging.texi index 7965dbc..debdd40 100644 --- a/doc/debugging.texi +++ b/doc/debugging.texi @@ -262,19 +262,30 @@ can't do anything about it without actually downloading the keys. @menu -* GnuPG-1 and GnuPG-2:: Relationship between the two branches. +* Component interaction:: How the components work together. +* GnuPG-1 and GnuPG-2:: Relationship between GnuPG 1.4 and 2.x. @end menu - at node GnuPG-1 and GnuPG-2 - at subsection Relationship between the two branches. -Here is a little picture showing how the components work together: + at node Component interaction + at subsection How the components work together. - at image{gnupg-card-architecture, 10cm} - at noindent -Lets try to explain it: + at float Figure,fig:moduleoverview + at caption{GnuPG module overview} + at center @image{gnupg-module-overview, 150mm,,GnuPG modules} + at end float + + + at node GnuPG-1 and GnuPG-2 + at subsection Relationship between GnuPG 1.4 and 2.x. + +Here is a little picture showing how the different GnuPG versions make +use of a smartcard: -TO BE DONE. + at float Figure,fig:cardarchitecture + at caption{GnuPG card architecture} + at center @image{gnupg-card-architecture, 150mm,, GnuPG card architecture} + at end float diff --git a/doc/gnupg-module-overview.svg b/doc/gnupg-module-overview.svg new file mode 100644 index 0000000..5b22f0d --- /dev/null +++ b/doc/gnupg-module-overview.svg @@ -0,0 +1,892 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Keyserver + + + + + + + + + + gpg-agent + + + + + + + + + + + + + + gpgsm + + + gpg + + + + CRL/Certificate Cache + + + scdaemon + + + + Smartcard + + + + + watchgnupg + + + + Private Keys + + + GPGME aware Applications + + + Pinentry + + + + + Public Keys + + + dirmngr + + + + Log Socket + + + + + + + + gpgconf + + + + + + Config Files + + + + + CRLs/Certificates + + + + + + + GnuPG + + + + + + + + + + 2016-02-16 + + + + + + closely linked + + + + Assuan protocol + + + + + + architecture + + + + execute/access + + + + + + + process + + + + object + + + + + + configure + + + + ----------------------------------------------------------------------- Summary of changes: doc/Makefile.am | 35 +- doc/debugging.texi | 27 +- doc/gnupg-module-overview.svg | 892 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 939 insertions(+), 15 deletions(-) create mode 100644 doc/gnupg-module-overview.svg hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 16 15:34:37 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 16 Feb 2016 15:34:37 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-33-g2f02ed7 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 2f02ed75a9671a7aae36968d5a1618f71b491325 (commit) from a1c11283af759c1045a8bb75815db325f415ded4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f02ed75a9671a7aae36968d5a1618f71b491325 Author: Neal H. Walfield Date: Sun Feb 14 16:00:10 2016 +0100 gpg: Make ASCII armor decoding more robust to encoding errors. * g10/armor.c (radix64_read): If the = is followed by the string "3D", check if the following four characters are valid radix 64 and are followed by a new line. If so, warn and ignore the '3D'. -- Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2250 diff --git a/g10/armor.c b/g10/armor.c index 55ee5d3..e34518e 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -796,6 +796,24 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, } } + /* Occasionally a bug MTA will leave the = escaped as + =3D. If the 4 characters following that are valid + Radix64 characters and they are following by a new + line, assume that this is the case and skip the + 3D. */ + if (afx->buffer_pos + 6 < afx->buffer_len + && afx->buffer[afx->buffer_pos + 0] == '3' + && afx->buffer[afx->buffer_pos + 1] == 'D' + && asctobin[afx->buffer[afx->buffer_pos + 2]] != 255 + && asctobin[afx->buffer[afx->buffer_pos + 3]] != 255 + && asctobin[afx->buffer[afx->buffer_pos + 4]] != 255 + && asctobin[afx->buffer[afx->buffer_pos + 5]] != 255 + && afx->buffer[afx->buffer_pos + 6] == '\n') + { + afx->buffer_pos += 2; + afx->qp_detected = 1; + } + if (!n) onlypad = 1; ----------------------------------------------------------------------- Summary of changes: g10/armor.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 16 15:49:32 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 16 Feb 2016 15:49:32 +0100 Subject: [git] GnuPG - branch, neal/issue2236, created. gnupg-2.1.11-34-gbff529a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, neal/issue2236 has been created at bff529a3ce936a5154bcd4f00abf83a2df3e758f (commit) - Log ----------------------------------------------------------------- commit bff529a3ce936a5154bcd4f00abf83a2df3e758f Author: Neal H. Walfield Date: Tue Feb 16 15:47:30 2016 +0100 gpg: Reorder signatures, if appropriate. XXX -- Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2236 diff --git a/g10/gpg.c b/g10/gpg.c index 330d5a3..458bba0 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -165,6 +165,7 @@ enum cmd_and_opt_values aPasswd, aServer, aTOFUPolicy, + aCheckKey, oTextmode, oNoTextmode, @@ -487,6 +488,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aServer, "server", N_("run in server mode")), ARGPARSE_c (aTOFUPolicy, "tofu-policy", N_("|VALUE|set the TOFU policy for a key")), + ARGPARSE_c (aCheckKey, "check-key", N_("Check a key")), ARGPARSE_group (301, N_("@\nOptions:\n ")), @@ -2464,6 +2466,10 @@ main (int argc, char **argv) set_cmd (&cmd, pargs.r_opt); break; + case aCheckKey: + set_cmd (&cmd, pargs.r_opt); + break; + case oArmor: opt.armor = 1; opt.no_armor=0; break; case oOutput: opt.outfile = pargs.r.ret_str; break; case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break; @@ -4589,6 +4595,31 @@ main (int argc, char **argv) #endif /*USE_TOFU*/ break; + case aCheckKey: + { + int i; + + if (argc < 1) + wrong_args ("--check-key KEYID..."); + + for (i = 0; i < argc; i ++) + { + kbnode_t kb; + + rc = get_pubkey_byname (ctrl, NULL, NULL, argv[i], &kb, + NULL, 1, 1); + if (rc) + { + log_error (_("looking up key '%s': %s\n"), + argv[i], gpg_strerror (rc)); + g10_exit (1); + } + + keyblock_check_sigs (kb, 0); + } + } + break; + case aListPackets: opt.list_packets=2; default: diff --git a/g10/keyedit.c b/g10/keyedit.c index 19ddf29..410817f 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1238,54 +1238,6 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock) -/* - * There are some keys out (due to a bug in gnupg), where the sequence - * of the packets is wrong. This function fixes that. - * Returns: true if the keyblock has been fixed. - * - * Note: This function does not work if there is more than one user ID. - */ -static int -fix_key_signature_order (KBNODE keyblock) -{ - KBNODE node, last, subkey; - int fixed = 0; - - /* Locate key signatures of class 0x10..0x13 behind sub key packets. */ - for (subkey = last = NULL, node = keyblock; node; - last = node, node = node->next) - { - switch (node->pkt->pkttype) - { - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - if (!subkey) - subkey = last; /* Actually it is the one before the subkey. */ - break; - case PKT_SIGNATURE: - if (subkey) - { - PKT_signature *sig = node->pkt->pkt.signature; - if (sig->sig_class >= 0x10 && sig->sig_class <= 0x13) - { - log_info (_("moving a key signature to the correct place\n")); - last->next = node->next; - node->next = subkey->next; - subkey->next = node; - node = last; - fixed = 1; - } - } - break; - default: - break; - } - } - - return fixed; -} - - /* Fix various problems in the keyblock. Returns true if the keyblock was changed. Note that a pointer to the keyblock must be given and the function may change it (i.e. replacing the first node). */ @@ -1294,10 +1246,10 @@ fix_keyblock (kbnode_t *keyblockp) { int changed = 0; - if (fix_key_signature_order (*keyblockp)) - changed++; if (collapse_uids (keyblockp)) changed++; + if (keyblock_check_sigs (*keyblockp, 0)) + changed++; reorder_keyblock (*keyblockp); /* If we modified the keyblock, make sure the flags are right. */ if (changed) @@ -1370,7 +1322,7 @@ enum cmdids cmdSHOWPREF, cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, - cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP + cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdCHECKKEY, cmdNOP }; static struct @@ -1465,6 +1417,8 @@ static struct N_("compact unusable user IDs and remove unusable signatures from key")}, { "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK, N_("compact unusable user IDs and remove all signatures from key")}, + { "checkkey", cmdCHECKKEY, KEYEDIT_NOT_SK, + N_("check the key")}, { NULL, cmdNONE, 0, NULL} }; @@ -2280,6 +2234,11 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, redisplay = modified = 1; break; + case cmdCHECKKEY: + if (keyblock_check_sigs (keyblock, 0)) + redisplay = modified = 1; + break; + case cmdQUIT: if (have_commands) goto leave; diff --git a/g10/main.h b/g10/main.h index 863afa9..bfa501d 100644 --- a/g10/main.h +++ b/g10/main.h @@ -263,6 +263,15 @@ int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, PKT_public_key *ret_pk, int *is_selfsig, u32 *r_expiredate, int *r_expired ); +int check_signature_end (PKT_public_key *pk, PKT_signature *sig, + gcry_md_hd_t digest, + int *r_expired, int *r_revoked, + PKT_public_key *ret_pk); +int check_signature_only_end (PKT_public_key *pk, PKT_signature *sig, + gcry_md_hd_t digest); +void hash_uid_node( KBNODE unode, gcry_md_hd_t md, PKT_signature *sig ); + + /*-- delkey.c --*/ gpg_error_t delete_keys (strlist_t names, int secret, int allow_both); diff --git a/g10/packet.h b/g10/packet.h index 16524f8..f8f46d5 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -651,6 +651,8 @@ int check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, int *r_expired, int *r_revoked, PKT_public_key *ret_pk); +/* Checks KB's signatures and possible reorders them. */ +int keyblock_check_sigs (KBNODE kb, int only_selfsigs); /*-- pubkey-enc.c --*/ gpg_error_t get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek); diff --git a/g10/sig-check.c b/g10/sig-check.c index 292adb9..d298765 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -34,11 +34,7 @@ #include "i18n.h" #include "options.h" #include "pkglue.h" - -static int check_signature_end (PKT_public_key *pk, PKT_signature *sig, - gcry_md_hd_t digest, - int *r_expired, int *r_revoked, - PKT_public_key *ret_pk); +#include "host2net.h" /* Check a signature. This is shorthand for check_signature2 with the unnamed arguments passed as NULL. */ @@ -371,19 +367,34 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig, * If RET_PK is not NULL, PK is copied into RET_PK on success. * * Returns 0 on success. An error code other. */ -static int +int check_signature_end (PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest, int *r_expired, int *r_revoked, PKT_public_key *ret_pk) { - gcry_mpi_t result = NULL; int rc = 0; - const struct weakhash *weak; if ((rc = check_signature_metadata_validity (pk, sig, r_expired, r_revoked))) return rc; + if ((rc = check_signature_only_end (pk, sig, digest))) + return rc; + + if(!rc && ret_pk) + copy_public_key(ret_pk,pk); + + return rc; +} + +int +check_signature_only_end (PKT_public_key *pk, PKT_signature *sig, + gcry_md_hd_t digest) +{ + gcry_mpi_t result = NULL; + int rc = 0; + const struct weakhash *weak; + if (!opt.flags.allow_weak_digest_algos) for (weak = opt.weak_digests; weak; weak = weak->next) if (sig->digest_algo == weak->algo) @@ -453,16 +464,13 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig, rc = GPG_ERR_BAD_SIGNATURE; } - if(!rc && ret_pk) - copy_public_key(ret_pk,pk); - return rc; } /* Add a uid node to a hash context. See section 5.2.4, paragraph 4 of RFC 4880. */ -static void +void hash_uid_node( KBNODE unode, gcry_md_hd_t md, PKT_signature *sig ) { PKT_user_id *uid = unode->pkt->pkt.user_id; @@ -893,3 +901,661 @@ check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, return rc; } + + +void +sig_print (estream_t fp, + PKT_public_key *pk, PKT_signature *sig, gpg_error_t sig_status, + int print_without_key, int extended) +{ + int sigrc; + int is_rev = sig->sig_class == 0x30; + + switch (gpg_err_code (sig_status)) + { + case GPG_ERR_NO_VALUE: /* Unknown. */ + sigrc = ' '; + break; + case 0: + sigrc = '!'; + break; + case GPG_ERR_BAD_SIGNATURE: + sigrc = '-'; + break; + case GPG_ERR_NO_PUBKEY: + case GPG_ERR_UNUSABLE_PUBKEY: + sigrc = '?'; + break; + default: + sigrc = '%'; + break; + } + if (sigrc != '?' || print_without_key) + { + es_fprintf (fp, "%s%c%c %c%c%c%c%c%c %s %s", + is_rev ? "rev" : "sig", sigrc, + (sig->sig_class - 0x10 > 0 && + sig->sig_class - 0x10 < + 4) ? '0' + sig->sig_class - 0x10 : ' ', + sig->flags.exportable ? ' ' : 'L', + sig->flags.revocable ? ' ' : 'R', + sig->flags.policy_url ? 'P' : ' ', + sig->flags.notation ? 'N' : ' ', + sig->flags.expired ? 'X' : ' ', + (sig->trust_depth > 9) ? 'T' : (sig->trust_depth > + 0) ? '0' + + sig->trust_depth : ' ', + keystr (sig->keyid), + datestr_from_sig (sig)); + if ((opt.list_options & LIST_SHOW_SIG_EXPIRE) || extended ) + es_fprintf (fp, " %s", expirestr_from_sig (sig)); + es_fprintf (fp, " "); + if (sigrc == '%') + es_fprintf (fp, "[%s] ", gpg_strerror (sig_status)); + else if (sigrc == '?') + ; + else + { + size_t n; + char *p = get_user_id (sig->keyid, &n); + tty_print_utf8_string2 (fp, p, n, + opt.screen_columns - keystrlen () - 26 - + ((opt. + list_options & LIST_SHOW_SIG_EXPIRE) ? 11 + : 0)); + xfree (p); + } + es_fprintf (fp, "\n"); + + if (sig->flags.policy_url + && ((opt.list_options & LIST_SHOW_POLICY_URLS) || extended)) + /* XXX: Change to print to FP. */ + show_policy_url (sig, 3, 0); + + if (sig->flags.notation + && ((opt.list_options & LIST_SHOW_NOTATIONS) || extended)) + /* XXX: Change to print to FP. */ + show_notation (sig, 3, 0, + ((opt. + list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + + ((opt. + list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0)); + + if (sig->flags.pref_ks + && ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended)) + /* XXX: Change to print to FP. */ + show_keyserver_url (sig, 3, 0); + + if (extended) + { + const unsigned char *s; + + s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL); + if (s && *s) + es_fprintf (fp, " [primary]\n"); + + s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); + if (s && buf32_to_u32 (s)) + es_fprintf (fp, " [expires: %s]\n", + isotimestamp (pk->timestamp + buf32_to_u32 (s))); + } + } +} + + +char * +sig_format (PKT_public_key *pk, PKT_signature *sig, gpg_error_t sig_status, + int print_without_key, int extended) +{ + estream_t fp; + char *s; + + fp = es_fopenmem (0, "rw,samethread"); + if (! fp) + log_fatal ("Error creating memory stream\n"); + + sig_print (fp, pk, sig, sig_status, print_without_key, extended); + + es_fputc (0, fp); + if (es_fclose_snatch (fp, (void **) &s, NULL)) + log_fatal ("error snatching memory stream\n"); + + if (s[strlen (s) - 1] == '\n') + s[strlen (s) - 1] = '\0'; + + return s; +} + +/* Order two signatures. The actual ordering isn't important. Our + goal is to ensure that identical signatures occur together. */ +static int +sig_comparison (const void *av, const void *bv) +{ + const KBNODE an = *(const KBNODE *) av; + const KBNODE bn = *(const KBNODE *) bv; + const PKT_signature *a; + const PKT_signature *b; + int ndataa; + int ndatab; + int i; + + assert (an->pkt->pkttype == PKT_SIGNATURE); + assert (bn->pkt->pkttype == PKT_SIGNATURE); + + a = an->pkt->pkt.signature; + b = bn->pkt->pkt.signature; + + if (a->digest_algo < b->digest_algo) + return -1; + if (a->digest_algo > b->digest_algo) + return 1; + + ndataa = pubkey_get_nsig (a->pubkey_algo); + ndatab = pubkey_get_nsig (a->pubkey_algo); + assert (ndataa == ndatab); + + for (i = 0; i < ndataa; i ++) + { + int c = gcry_mpi_cmp (a->data[i], b->data[i]); + if (c != 0) + return c; + } + + /* Okay, they are equal. */ + return 0; +} + +/* Check that a keyblock is okay and possibly repair some damage. + Concretely: + + - Detect duplicate signatures and remove them. + + - Detect out of order signatures and relocate them (e.g., a sig + over a user id located under a subkey) + + Note: this function does not remove signatures that don't belong or + components that are not signed! (Although it would be trivial to + do.) + + If ONLY_SELFSIGS is true, then this function only reorders self + signatures (it still checks all signatures for duplicates, + however). + + Returns 1 if the keyblock was modified, 0 otherwise. + */ +int +keyblock_check_sigs (KBNODE kb, int only_selfsigs) +{ + gpg_error_t err; + PKT_public_key *pk; + u32 pk_keyid[2]; + KBNODE n, n_next, *n_prevp, n2; + char *pending_desc = NULL; + PKT_public_key *issuer; + KBNODE current_component = NULL; + int dups = 0; + int missing_issuer = 0; + int reordered = 0; + int bad_signature = 0; + int modified = 0; + + assert (kb->pkt->pkttype == PKT_PUBLIC_KEY); + pk = kb->pkt->pkt.public_key; + keyid_from_pk (pk, pk_keyid); + + /* First we look for duplicates. */ + { + int nsigs = 0; + KBNODE *sigs; + int i; + int last_i; + + /* Count the sigs. */ + for (n = kb; n; n = n->next) + if (is_deleted_kbnode (n)) + continue; + else if (n->pkt->pkttype == PKT_SIGNATURE) + nsigs ++; + + /* Add them all to the SIGS array. */ + sigs = xmalloc_clear (sizeof (*sigs) * nsigs); + + i = 0; + for (n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + + if (n->pkt->pkttype != PKT_SIGNATURE) + continue; + + sigs[i] = n; + i ++; + } + assert (i == nsigs); + + qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison); + + last_i = 0; + for (i = 1; i < nsigs; i ++) + { + assert (sigs[last_i]); + assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE); + assert (sigs[i]); + assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE); + + if (sig_comparison (&sigs[last_i], &sigs[i]) == 0) + /* They are the same. Kill the latter. */ + { + if (opt.verbose) + { + PKT_signature *sig = sigs[i]->pkt->pkt.signature; + + log_info (_("Signature appears multiple times, deleting duplicate:\n")); + log_info (" sig: class 0x%x, issuer: %s, timestamp: %s (%lld), digest: %02x %02x\n", + sig->sig_class, keystr (sig->keyid), + isotimestamp (sig->timestamp), + (long long) sig->timestamp, + sig->digest_start[0], sig->digest_start[1]); + } + + /* Remove sigs[i] from the keyblock. */ + { + KBNODE z, *prevp; + int to_kill = i; + + for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next) + if (z == sigs[to_kill]) + break; + + *prevp = sigs[to_kill]->next; + + sigs[to_kill]->next = NULL; + release_kbnode (sigs[to_kill]); + sigs[to_kill] = NULL; + + dups ++; + modified = 1; + } + } + else + last_i = i; + } + + if (dups) + log_info (_("Ignored %d duplicate signatures (total: %d).\n"), + dups, nsigs); + + xfree (sigs); + } + + /* Make sure the sigs occur after the component (public key, subkey, + user id) that they sign. */ + issuer = NULL; + for (n_prevp = &kb, n = kb; n; n_prevp = &n->next, n = n_next) + { + PACKET *p; + int processed_current_component; + KBNODE sig_over = NULL; + PKT_signature *sig; + int algo; + int pkttype; + gcry_md_hd_t md; + int dump_sig_params = 0; + + n_next = n->next; + + if (is_deleted_kbnode (n)) + continue; + + p = n->pkt; + + if (issuer != pk) + free_public_key (issuer); + issuer = NULL; + + xfree (pending_desc); + pending_desc = NULL; + + switch (p->pkttype) + { + case PKT_PUBLIC_KEY: + assert (p->pkt.public_key == pk); + keyid_from_pk (pk, NULL); + log_info ("public key %s: timestamp: %s (%lld)\n", + keystr (pk->keyid), + isotimestamp (pk->timestamp), + (long long) pk->timestamp); + current_component = n; + break; + case PKT_PUBLIC_SUBKEY: + keyid_from_pk (p->pkt.public_key, NULL); + log_info ("subkey %s: timestamp: %s (%lld)\n", + keystr (p->pkt.public_key->keyid), + isotimestamp (p->pkt.public_key->timestamp), + (long long) p->pkt.public_key->timestamp); + current_component = n; + break; + case PKT_USER_ID: + log_info ("user id: %s\n", + p->pkt.user_id->attrib_data + ? "[ photo id ]" + : p->pkt.user_id->name); + current_component = n; + break; + case PKT_SIGNATURE: + sig = n->pkt->pkt.signature; + algo = sig->digest_algo; + +#if 1 + pending_desc = xasprintf (" sig: class: 0x%x, issuer: %s, timestamp: %s (%lld), digest: %02x %02x", + sig->sig_class, + keystr (sig->keyid), + isotimestamp (sig->timestamp), + (long long) sig->timestamp, + sig->digest_start[0], sig->digest_start[1]); +#else + pending_desc = sig_format (pk, sig, GPG_ERR_NO_VALUE, 1, 0); +#endif + + + if (pk_keyid[0] == sig->keyid[0] && pk_keyid[1] == sig->keyid[1]) + issuer = pk; + else + /* Issuer is a different key. */ + { + if (only_selfsigs) + continue; + + issuer = xmalloc (sizeof (*issuer)); + err = get_pubkey (issuer, sig->keyid); + if (err) + { + xfree (issuer); + issuer = NULL; + if (opt.verbose) + { + if (pending_desc) + log_info ("%s", pending_desc); + log_info (_(" Can't check signature allegedly issued by %s: %s\n"), + keystr (sig->keyid), gpg_strerror (err)); + } + missing_issuer ++; + break; + } + } + + if ((err = openpgp_pk_test_algo (sig->pubkey_algo))) + { + if (pending_desc) + log_info ("%s", pending_desc); + log_info (_(" Unsupported algorithm: %s.\n"), + gpg_strerror (err)); + break; + } + if ((err = openpgp_md_test_algo(algo))) + { + if (pending_desc) + log_info ("%s", pending_desc); + log_info (_(" Unimplemented algorithm: %s.\n"), + gpg_strerror (err)); + break; + } + + /* We iterate over the keyblock. Most likely, the matching + component is the current component so always try that + first. */ + processed_current_component = 0; + for (n2 = current_component; + n2; + n2 = (processed_current_component ? n2->next : kb), + processed_current_component = 1) + if (is_deleted_kbnode (n2)) + continue; + else if (processed_current_component && n2 == current_component) + /* Don't process it twice. */ + continue; + else if (! ((pkttype = n2->pkt->pkttype) + && (pkttype == PKT_PUBLIC_KEY + || pkttype == PKT_PUBLIC_SUBKEY + || pkttype == PKT_USER_ID))) + continue; + else if (sig->sig_class == 0x20) + { + PKT_public_key *k; + + if (pkttype != PKT_PUBLIC_KEY) + continue; + + k = n2->pkt->pkt.public_key; + + /* If issuer != pk, then we (may) have a designated + revoker. */ + + if (gcry_md_open (&md, algo, 0)) + BUG (); + hash_public_key (md, k); + err = check_signature_only_end (issuer, sig, md); + gcry_md_close (md); + if (! err) + { + assert (! sig_over); + sig_over = n2; + break; + } + } + else if (sig->sig_class == 0x28) + /* subkey revocation */ + { + PKT_public_key *k; + + if (pkttype != PKT_PUBLIC_SUBKEY) + continue; + + if (issuer != pk) + /* Definately invalid: class 0x28 keys must be made + by the primary key. */ + { + n2 = NULL; + break; + } + + k = n2->pkt->pkt.public_key; + + if (gcry_md_open (&md, algo, 0)) + BUG (); + hash_public_key (md, pk); + hash_public_key (md, k); + err = check_signature_only_end (pk, sig, md); + gcry_md_close (md); + if (! err) + { + assert (! sig_over); + sig_over = n2; + break; + } + } + else if (sig->sig_class == 0x18) + /* key binding */ + { + PKT_public_key *k; + + if (pkttype != PKT_PUBLIC_SUBKEY) + continue; + + if (issuer != pk) + /* Definately invalid: class 0x18 keys must be made + by the primary key. */ + { + n2 = NULL; + break; + } + + k = n2->pkt->pkt.public_key; + + if (gcry_md_open (&md, algo, 0)) + BUG (); + hash_public_key (md, pk); + hash_public_key (md, k); + err = check_signature_only_end (pk, sig, md); + gcry_md_close (md); + if (! err) + { + assert (! sig_over); + sig_over = n2; + break; + } + } + else if (sig->sig_class == 0x1f) + /* direct key signature */ + { + if (pkttype != PKT_PUBLIC_KEY) + continue; + + if (issuer != pk) + /* Definately invalid: class 0x1f keys must be made + by the primary key. */ + { + n2 = NULL; + break; + } + + if (gcry_md_open (&md, algo, 0 )) + BUG (); + hash_public_key (md, pk); + err = check_signature_only_end (pk, sig, md); + gcry_md_close (md); + if (! err) + { + assert (! sig_over); + sig_over = n2; + break; + } + } + else + /* all other classes */ + { + if (pkttype != PKT_USER_ID) + continue; + + if (gcry_md_open (&md, algo, 0)) + BUG (); + hash_public_key (md, pk); + hash_uid_node (n2, md, sig); + err = check_signature_only_end (issuer, sig, md); + gcry_md_close (md); + if (! err) + { + assert (! sig_over); + sig_over = n2; + break; + } + } + + /* n/sig is a signature and n2 is the component (public key, + subkey or user id) that it signs, if any. + current_component is that component that it appears to + apply to (according to the ordering). */ + + if (current_component == n2) + { + log_info ("%s", pending_desc); + log_info (_(" Good signature over last major component!\n")); + cache_sig_result (sig, 0); + } + else if (n2) + { + assert (n2->pkt->pkttype == PKT_USER_ID + || n2->pkt->pkttype == PKT_PUBLIC_KEY + || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY); + + log_info ("%s", pending_desc); + log_info (_(" Good signature out of order! (Over %s (%d) '%s')\n"), + n2->pkt->pkttype == PKT_USER_ID + ? "user id" + : n2->pkt->pkttype == PKT_PUBLIC_SUBKEY + ? "subkey" + : "primary key", + n2->pkt->pkttype, + n2->pkt->pkttype == PKT_USER_ID + ? n2->pkt->pkt.user_id->name + : keystr (n2->pkt->pkt.public_key->keyid)); + + /* Reorder the packets: move the signature n to be just + after n2. */ + assert (n_prevp); + *n_prevp = n->next; + n->next = n2->next; + n2->next = n; + + cache_sig_result (sig, 0); + + reordered ++; + modified = 1; + } + else + { + log_info ("%s", pending_desc); +#if 0 + log_info (_(" Bad signature, removing from key block.\n")); + + /* Remove the signature n. */ + *n_prevp = n->next; + n->next = NULL; + release_kbnode (n); + + modified = 1; +#else + log_info (_(" Bad signature.\n")); +#endif + + cache_sig_result (sig, GPG_ERR_BAD_SIGNATURE); + + if (opt.verbose) + dump_sig_params = 1; + + bad_signature ++; + } + + if (dump_sig_params) + { + int i; + + for (i = 0; i < pubkey_get_nsig (sig->pubkey_algo); i ++) + { + char buffer[1024]; + size_t len; + char *printable; + gcry_mpi_print (GCRYMPI_FMT_USG, + buffer, sizeof (buffer), &len, + sig->data[i]); + printable = bin2hex (buffer, len, NULL); + log_info (" %d: %s\n", i, printable); + xfree (printable); + } + } + break; + default: + if (DBG_PACKET) + log_debug ("unhandled packet: %d\n", p->pkttype); + break; + } + } + + xfree (pending_desc); + pending_desc = NULL; + + if (issuer != pk) + free_public_key (issuer); + issuer = NULL; + + if (missing_issuer) + log_info (_("Couldn't check %d signatures due to missing issuer keys.\n"), + missing_issuer); + if (bad_signature) + log_info (_("%d bad signatures.\n"), bad_signature); + if (reordered) + log_info (_("Reordered %d packets.\n"), reordered); + + return modified; +} ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 16 17:01:56 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 16 Feb 2016 17:01:56 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-35-ge1ceff1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via e1ceff16765b0342531709cf97d03ef0158c29d5 (commit) via 44b02e1beb4f38f26551d932827d5317fddd27c2 (commit) from 2f02ed75a9671a7aae36968d5a1618f71b491325 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e1ceff16765b0342531709cf97d03ef0158c29d5 Author: Werner Koch Date: Tue Feb 16 16:47:22 2016 +0100 w32: Make scdaemon build again due to libusb problem. * configure.ac: Add hack to disable libusb for Windows. Also use $host instead of $target in the switch -- The new test for libusb does not support cross-compiling. As a quick workaround we disable libusb for Windows because we can't use it anyway. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 81fde82..7770894 100644 --- a/configure.ac +++ b/configure.ac @@ -783,7 +783,11 @@ AM_PATH_KSBA("$NEED_KSBA_API:$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no) # # FiXME: Use GNUPG_CHECK_LIBUSB and modify to use separate AC_SUBSTs. if test "$use_ccid_driver" = yes ; then - case $target in + case "${host}" in + *-mingw32*) + LIBUSB_LIBS= + LIBUSB_CPPFLAGS= + ;; *-*-darwin*) LIBUSB_LIBS="-lusb-1.0 -Wl,-framework,CoreFoundation -Wl,-framework,IOKit" ;; @@ -795,6 +799,8 @@ if test "$use_ccid_driver" = yes ; then LIBUSB_LIBS="-lusb-1.0" ;; esac +fi +if test x"$LIBUSB_LIBS" != x ; then AC_CHECK_LIB(usb-1.0, libusb_init, [ LIBUSB_LIBS="$LIBUSB_LIBS" have_libusb=yes ]) commit 44b02e1beb4f38f26551d932827d5317fddd27c2 Author: Werner Koch Date: Tue Feb 16 16:07:44 2016 +0100 w32: Do not error out if gpgconf is not installed. * common/homedir.c (check_portable_app): Remove error message. -- It is sometimes useful to install just gpgv and no other parts. Our test for a portable application returned an error if gpgconf is not installed. That error is not required but was merely a debug aid. Signed-off-by: Werner Koch diff --git a/common/homedir.c b/common/homedir.c index 3918693..e0a88fa 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -256,9 +256,7 @@ check_portable_app (const char *dir) char *fname; fname = xstrconcat (dir, DIRSEP_S "gpgconf.exe", NULL); - if (access (fname, F_OK)) - log_error ("required binary '%s' is not installed\n", fname); - else + if (!access (fname, F_OK)) { strcpy (fname + strlen (fname) - 3, "ctl"); if (!access (fname, F_OK)) ----------------------------------------------------------------------- Summary of changes: common/homedir.c | 4 +--- configure.ac | 8 +++++++- 2 files changed, 8 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 17 20:00:18 2016 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Wed, 17 Feb 2016 20:00:18 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.5-4-g5369520 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-6-BRANCH has been updated via 53695204acb315deb10705ad35f133815418aa8b (commit) via 2ea6ce6b0e9b644f7db4df49f08726c7cbfefeac (commit) from 72b0d74103fef216479f97f9d5fe23e95f6b3ccc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 53695204acb315deb10705ad35f133815418aa8b Author: Jussi Kivilinna Date: Wed Apr 29 18:18:07 2015 +0300 Disable building mpi assembly routines on WIN64 * mpi/config.links: Disable assembly for host 'x86_64-*mingw32*'. -- Signed-off-by: Jussi Kivilinna (cherry picked from commit e78560a4b717f7154f910a8ce4128de152f586da) diff --git a/mpi/config.links b/mpi/config.links index 9500f08..477774c 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -134,6 +134,11 @@ case "${host}" in path="amd64" mpi_cpu_arch="x86" ;; + x86_64-*mingw32*) + echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h + path="" + mpi_cpu_arch="x86" + ;; x86_64-*-*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h commit 2ea6ce6b0e9b644f7db4df49f08726c7cbfefeac Author: Jussi Kivilinna Date: Wed Apr 29 18:18:07 2015 +0300 Fix rndhw for 64-bit Windows build * configure.ac: Add sizeof check for 'void *'. * random/rndhw.c (poll_padlock): Check for SIZEOF_VOID_P == 8 instead of defined(__LP64__). (RDRAND_LONG): Check for SIZEOF_UNSIGNED_LONG == 8 instead of defined(__LP64__). -- __LP64__ is not predefined for 64-bit mingw64-gcc, which caused wrong assembly code selections. Do selection based on type sizes instead, to support x86_64, x32 and win64 properly. Signed-off-by: Jussi Kivilinna (cherry picked from commit d5a7e00b6b222566a5650639ef29684b047c1909) diff --git a/configure.ac b/configure.ac index b58fd6b..75d3a06 100644 --- a/configure.ac +++ b/configure.ac @@ -341,6 +341,7 @@ AC_CHECK_SIZEOF(unsigned short, 2) AC_CHECK_SIZEOF(unsigned int, 4) AC_CHECK_SIZEOF(unsigned long, 4) AC_CHECK_SIZEOF(unsigned long long, 0) +AC_CHECK_SIZEOF(void *, 0) AC_TYPE_UINTPTR_T diff --git a/random/rndhw.c b/random/rndhw.c index e625512..8e50751 100644 --- a/random/rndhw.c +++ b/random/rndhw.c @@ -69,7 +69,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), nbytes = 0; while (nbytes < 64) { -#if defined(__x86_64__) && defined(__LP64__) +#if defined(__x86_64__) && SIZEOF_VOID_P == 8 asm volatile ("movq %1, %%rdi\n\t" /* Set buffer. */ "xorq %%rdx, %%rdx\n\t" /* Request up to 8 bytes. */ @@ -123,7 +123,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), #ifdef USE_DRNG # define RDRAND_RETRY_LOOPS 10 # define RDRAND_INT ".byte 0x0f,0xc7,0xf0" -# if defined(__x86_64__) && defined(__LP64__) +# if defined(__x86_64__) && SIZEOF_UNSIGNED_LONG == 8 # define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0" # else # define RDRAND_LONG RDRAND_INT ----------------------------------------------------------------------- Summary of changes: configure.ac | 1 + mpi/config.links | 5 +++++ random/rndhw.c | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 18 09:42:34 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 18 Feb 2016 09:42:34 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.4-6-g3128e44 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via 3128e444aa9c9eaca15ba696d5056da7a61e7cb3 (commit) via 4d9e959e6a4f3a3cf5353ee545aa113b2af85570 (commit) from fcbb9fcc2e6983ea61bf565b6ee2e29816b8cd57 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3128e444aa9c9eaca15ba696d5056da7a61e7cb3 Author: Werner Koch Date: Thu Feb 18 09:33:09 2016 +0100 Post release updates. -- diff --git a/NEWS b/NEWS index 54d8594..13ac832 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.5.6 (unreleased) [C19/A8/R_] +------------------------------------------------ + + Noteworthy changes in version 1.5.5 (2016-02-18) [C19/A8/R4] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 6a87a59..367acd2 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ min_automake_version="1.11" # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [5]) -m4_define(mym4_version_micro, [5]) +m4_define(mym4_version_micro, [6]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag commit 4d9e959e6a4f3a3cf5353ee545aa113b2af85570 Author: Werner Koch Date: Thu Feb 18 08:44:45 2016 +0100 Release 1.5.5. * configure.ac: Set LT version to C19/A8/R4. diff --git a/Makefile.am b/Makefile.am index 8b4d451..c2dc6d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = dist-bzip2 DISTCHECK_CONFIGURE_FLAGS = --enable-random-daemon \ --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia diff --git a/NEWS b/NEWS index 56d7237..54d8594 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,11 @@ -Noteworthy changes in version 1.5.5 (unreleased) [C19/A8/R_] +Noteworthy changes in version 1.5.5 (2016-02-18) [C19/A8/R4] ------------------------------------------------ + * Mitigate chosen cipher text attacks on ECDH with Weierstrass + curves. [CVE-2015-7511] + + * Use ciphertext blinding for Elgamal decryption. [CVE-2014-3591] + Noteworthy changes in version 1.5.4 (2014-08-07) [C19/A8/R3] ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 8f54c28..6a87a59 100644 --- a/configure.ac +++ b/configure.ac @@ -59,7 +59,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # LIBGCRYPT_LT_CURRENT=19 LIBGCRYPT_LT_AGE=8 -LIBGCRYPT_LT_REVISION=3 +LIBGCRYPT_LT_REVISION=4 # If the API is changed in an incompatible way: increment the next counter. @@ -71,7 +71,7 @@ PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION AC_CONFIG_SRCDIR([src/libgcrypt.vers]) -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([serial-tests dist-bzip2]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_LIBOBJ_DIR([compat]) ----------------------------------------------------------------------- Summary of changes: Makefile.am | 1 - NEWS | 11 ++++++++++- configure.ac | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 18 12:24:56 2016 From: cvs at cvs.gnupg.org (by Daniel Kahn Gillmor) Date: Thu, 18 Feb 2016 12:24:56 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-37-g7e7f35a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 7e7f35a2d7d40267a4dd30791df77420efeebfa7 (commit) via 813df2fe6656e55bea4d0be07cc964a140218412 (commit) from e1ceff16765b0342531709cf97d03ef0158c29d5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7e7f35a2d7d40267a4dd30791df77420efeebfa7 Author: Daniel Kahn Gillmor Date: Mon Feb 8 15:44:07 2016 -0500 gpgparsemail: Allow weirdly-mixed pkcs7 signatures. * tools/gpgparsemail.c: Add and check info->signing_protocol_2. -- Some mailers in the wild will generate messages that have the a weird structure where they use the x- prefix in one part and drop it in another. For example, the main MIME part as a whole has: Content-Type: multipart/signed; protocol="application/x-pkcs7-signature" but the signature sub-part has: Content-Type: application/pkcs7-signature (or vice versa, where the x- prefix is in the sub-part but not the protocol= section on the main MIME object) This change also avoids allocating strings for these comparisons, since the const strings in question are already available in the built executable, and no dynamic labels are needed. === - 2 lines reformatted to keep them below 90 cols. - wk diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index 98bbad0..57a6203 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -67,7 +67,9 @@ struct parse_info_s { int smfm_state; /* State of PGP/MIME or S/MIME parsing. */ int is_smime; /* This is S/MIME and not PGP/MIME. */ - char *signing_protocol; + const char *signing_protocol; + const char *signing_protocol_2; /* there are two ways to present + PKCS7 */ int hashing_level; /* The nesting level we are hashing. */ int hashing; FILE *hash_file; @@ -139,15 +141,15 @@ xmalloc (size_t n) /* return p; */ /* } */ -static char * -xstrdup (const char *string) -{ - void *p = malloc (strlen (string)+1); - if (!p) - die ("out of core: %s", strerror (errno)); - strcpy (p, string); - return p; -} +/* static char * */ +/* xstrdup (const char *string) */ +/* { */ +/* void *p = malloc (strlen (string)+1); */ +/* if (!p) */ +/* die ("out of core: %s", strerror (errno)); */ +/* strcpy (p, string); */ +/* return p; */ +/* } */ #ifndef HAVE_STPCPY static char * @@ -364,8 +366,8 @@ mime_signed_begin (struct parse_info_s *info, rfc822parse_t msg, { info->smfm_state = 1; info->is_smime = 0; - free (info->signing_protocol); - info->signing_protocol = xstrdup (s); + info->signing_protocol = "application/pgp-signature"; + info->signing_protocol_2 = NULL; } } else if (!strcmp (s, "application/pkcs7-signature") @@ -377,8 +379,8 @@ mime_signed_begin (struct parse_info_s *info, rfc822parse_t msg, { info->smfm_state = 1; info->is_smime = 1; - free (info->signing_protocol); - info->signing_protocol = xstrdup (s); + info->signing_protocol = "application/pkcs7-signature"; + info->signing_protocol_2 = "application/x-pkcs7-signature"; } } else if (verbose) @@ -516,10 +518,15 @@ message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) char *buf = xmalloc (strlen (s1) + strlen (s2) + 2); strcpy (stpcpy (stpcpy (buf, s1), "/"), s2); assert (info->signing_protocol); - if (strcmp (buf, info->signing_protocol)) - err ("invalid %s structure; expected '%s', found '%s'", + if (strcmp (buf, info->signing_protocol) && + (!info->signing_protocol_2 + || strcmp (buf,info->signing_protocol_2))) + err ("invalid %s structure; expected %s%s%s, found '%s'", info->is_smime? "S/MIME":"PGP/MIME", - info->signing_protocol, buf); + info->signing_protocol, + info->signing_protocol_2 ? " or " : "", + info->signing_protocol_2 ? info->signing_protocol_2:"", + buf); else { printf ("c begin_signature\n"); commit 813df2fe6656e55bea4d0be07cc964a140218412 Author: Daniel Kahn Gillmor Date: Thu Feb 11 07:08:55 2016 -0500 gpg: Clean up dangling agent_open and agent_closed declarations. * g10/keydb.h: Remove agent_open, agent_close declarations/ * g10/migrate.c: #include for access() -- agent_open() is only defined statically in common/simple-pw-query.c, it is neither used nor referenced anywhere else. agent_close doesn't exist anywhere. The removal of these declarations removes an unecessary inclusion of libassuan.h. migrate.c was relying on keydb.h -> libassuan.h -> unistd.h for the declaration of access(), so we now handle that explicitly instead. diff --git a/g10/keydb.h b/g10/keydb.h index 9b4a1cf..8d4e36c 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -22,8 +22,6 @@ #ifndef G10_KEYDB_H #define G10_KEYDB_H -#include - #include "types.h" #include "util.h" #include "packet.h" @@ -248,8 +246,6 @@ gpg_error_t build_sk_list (ctrl_t ctrl, strlist_t locusr, /*-- passphrase.h --*/ unsigned char encode_s2k_iterations (int iterations); -assuan_context_t agent_open (int try, const char *orig_codeset); -void agent_close (assuan_context_t ctx); int have_static_passphrase(void); const char *get_static_passphrase (void); void set_passphrase_from_string(const char *pass); diff --git a/g10/migrate.c b/g10/migrate.c index 96ca5c2..48cbdd0 100644 --- a/g10/migrate.c +++ b/g10/migrate.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "gpg.h" ----------------------------------------------------------------------- Summary of changes: g10/keydb.h | 4 ---- g10/migrate.c | 1 + tools/gpgparsemail.c | 41 ++++++++++++++++++++++++----------------- 3 files changed, 25 insertions(+), 21 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 19 15:52:44 2016 From: cvs at cvs.gnupg.org (by Stephan Mueller) Date: Fri, 19 Feb 2016 15:52:44 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-330-ge9b692d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via e9b692d25d1c149b5417b70e18f2ce173bc25b6d (commit) from 934ba2ae5a95a96fdbb3b935b51ba43df66f11df (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e9b692d25d1c149b5417b70e18f2ce173bc25b6d Author: Stephan Mueller Date: Tue Feb 16 22:04:53 2016 +0100 random: Remove ANSI X9.31 DRNG * random-fips.c: Remove. -- The ANSI X9.31 DRNG is removed as it is completely replaced with the SP800-90A DRBG. Signed-off-by: Stephan Mueller diff --git a/random/Makefile.am b/random/Makefile.am index 610387d..92aba20 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -34,7 +34,6 @@ librandom_la_SOURCES = \ random.c random.h \ rand-internal.h \ random-csprng.c \ -random-fips.c \ random-drbg.c \ random-system.c \ rndhw.c diff --git a/random/rand-internal.h b/random/rand-internal.h index dbd23df..8c8623e 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -63,31 +63,6 @@ void _gcry_rngcsprng_set_seed_file (const char *name); void _gcry_rngcsprng_update_seed_file (void); void _gcry_rngcsprng_fast_poll (void); -/*-- random-fips.c --*/ -void _gcry_rngfips_initialize (int full); -void _gcry_rngfips_close_fds (void); -void _gcry_rngfips_dump_stats (void); -int _gcry_rngfips_is_faked (void); -gcry_error_t _gcry_rngfips_add_bytes (const void *buf, size_t buflen, - int quality); -void _gcry_rngfips_randomize (void *buffer, size_t length, - enum gcry_random_level level); -void _gcry_rngfips_create_nonce (void *buffer, size_t length); - -gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report); - -gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context, - unsigned int flags, - const void *key, - size_t keylen, - const void *seed, - size_t seedlen, - const void *dt, - size_t dtlen); -gcry_err_code_t _gcry_rngfips_run_external_test (void *context, - char *buffer, size_t buflen); -void _gcry_rngfips_deinit_external_test (void *context); - /*-- random-drbg.c --*/ void _gcry_rngdrbg_inititialize (int full); void _gcry_rngdrbg_close_fds (void); ----------------------------------------------------------------------- Summary of changes: random/Makefile.am | 1 - random/rand-internal.h | 25 ------------------------- 2 files changed, 26 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 19 16:40:05 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Fri, 19 Feb 2016 16:40:05 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-44-g2d1d795 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 2d1d795481bc011447284f8ce0a3ae96a08daf17 (commit) via 44cdb9d73f1a0b7d2c8483a119b9c4d6caabc1ec (commit) via 5fbd80579aea0f75ca1d2700515c5b8747a75c7d (commit) via ac5aea95455372145f3f06df2b4c1584d759d660 (commit) via 10671c3a4c18ea26035a5819a9f2b8fd6c7e41ea (commit) via bf9d1248c80205795e26156f67aff0b3f796cfce (commit) via c45633a571bf663bc7f3610fc481acded6acfc19 (commit) from 7e7f35a2d7d40267a4dd30791df77420efeebfa7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2d1d795481bc011447284f8ce0a3ae96a08daf17 Author: Neal H. Walfield Date: Fri Feb 19 15:52:08 2016 +0100 gpg: Systematically detect and fix signatures that are out of order. * g10/keyedit.c (sig_comparison): New function. (fix_key_signature_order): Merge functionality into... (check_all_keysigs): ... this function. Rewrite to eliminate duplicates and use a systematic approach to detecting and moving signatures that are out of order instead of a heuristic. (fix_keyblock): Don't call fix_key_signature_order. Call check_all_keysigs instead after collapsing the uids. -- Signed-off-by: Neal H. Walfield GnuPG-bug-id: 2236 diff --git a/g10/keyedit.c b/g10/keyedit.c index 8cec66a..d7c2a4b 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -322,97 +322,584 @@ print_and_check_one_sig (KBNODE keyblock, KBNODE node, -/* - * Check the keysigs and set the flags to indicate errors. - * Returns true if error found. - */ +/* Order two signatures. The actual ordering isn't important. Our + goal is to ensure that identical signatures occur together. */ static int -check_all_keysigs (KBNODE keyblock, int only_selected, int only_selfsigs) +sig_comparison (const void *av, const void *bv) { - KBNODE kbctx; - KBNODE node; - int inv_sigs = 0; - int no_key = 0; - int oth_err = 0; - int has_selfsig = 0; - int mis_selfsig = 0; - int selected = !only_selected; - int anyuid = 0; - u32 keyid[2]; + const KBNODE an = *(const KBNODE *) av; + const KBNODE bn = *(const KBNODE *) bv; + const PKT_signature *a; + const PKT_signature *b; + int ndataa; + int ndatab; + int i; + + assert (an->pkt->pkttype == PKT_SIGNATURE); + assert (bn->pkt->pkttype == PKT_SIGNATURE); + + a = an->pkt->pkt.signature; + b = bn->pkt->pkt.signature; - for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));) + if (a->digest_algo < b->digest_algo) + return -1; + if (a->digest_algo > b->digest_algo) + return 1; + + ndataa = pubkey_get_nsig (a->pubkey_algo); + ndatab = pubkey_get_nsig (a->pubkey_algo); + assert (ndataa == ndatab); + + for (i = 0; i < ndataa; i ++) { - if (node->pkt->pkttype == PKT_PUBLIC_KEY) + int c = gcry_mpi_cmp (a->data[i], b->data[i]); + if (c != 0) + return c; + } + + /* Okay, they are equal. */ + return 0; +} + +/* Perform a few sanity checks on a keyblock is okay and possibly + repair some damage. Concretely: + + - Detect duplicate signatures and remove them. + + - Detect out of order signatures and relocate them (e.g., a sig + over user id X located under subkey Y). + + Note: this function does not remove signatures that don't belong or + components that are not signed! (Although it would be trivial to + do so.) + + If ONLY_SELFSIGS is true, then this function only reorders self + signatures (it still checks all signatures for duplicates, + however). + + Returns 1 if the keyblock was modified, 0 otherwise. */ +static int +check_all_keysigs (KBNODE kb, int only_selected, int only_selfsigs) +{ + gpg_error_t err; + PKT_public_key *pk; + KBNODE n, n_next, *n_prevp, n2; + char *pending_desc = NULL; + PKT_public_key *issuer; + KBNODE last_printed_component; + KBNODE current_component = NULL; + int dups = 0; + int missing_issuer = 0; + int reordered = 0; + int bad_signature = 0; + int missing_selfsig = 0; + int modified = 0; + + assert (kb->pkt->pkttype == PKT_PUBLIC_KEY); + pk = kb->pkt->pkt.public_key; + + /* First we look for duplicates. */ + { + int nsigs = 0; + KBNODE *sigs; + int i; + int last_i; + + /* Count the sigs. */ + for (n = kb; n; n = n->next) + if (is_deleted_kbnode (n)) + continue; + else if (n->pkt->pkttype == PKT_SIGNATURE) + nsigs ++; + + /* Add them all to the SIGS array. */ + sigs = xmalloc_clear (sizeof (*sigs) * nsigs); + + i = 0; + for (n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + + if (n->pkt->pkttype != PKT_SIGNATURE) + continue; + + sigs[i] = n; + i ++; + } + assert (i == nsigs); + + qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison); + + last_i = 0; + for (i = 1; i < nsigs; i ++) + { + assert (sigs[last_i]); + assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE); + assert (sigs[i]); + assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE); + + if (sig_comparison (&sigs[last_i], &sigs[i]) == 0) + /* They are the same. Kill the latter. */ + { + if (DBG_PACKET) + { + PKT_signature *sig = sigs[i]->pkt->pkt.signature; + + log_debug ("Signature appears multiple times, deleting duplicate:\n"); + log_debug (" sig: class 0x%x, issuer: %s, timestamp: %s (%lld), digest: %02x %02x\n", + sig->sig_class, keystr (sig->keyid), + isotimestamp (sig->timestamp), + (long long) sig->timestamp, + sig->digest_start[0], sig->digest_start[1]); + } + + /* Remove sigs[i] from the keyblock. */ + { + KBNODE z, *prevp; + int to_kill = last_i; + last_i = i; + + for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next) + if (z == sigs[to_kill]) + break; + + *prevp = sigs[to_kill]->next; + + sigs[to_kill]->next = NULL; + release_kbnode (sigs[to_kill]); + sigs[to_kill] = NULL; + + dups ++; + modified = 1; + } + } + else + last_i = i; + } + + xfree (sigs); + } + + /* Make sure the sigs occur after the component (public key, subkey, + user id) that they sign. */ + issuer = NULL; + last_printed_component = NULL; + for (n_prevp = &kb, n = kb; + n; + /* If we moved n, then n_prevp is need valid. */ + n_prevp = (n->next == n_next ? &n->next : n_prevp), n = n_next) + { + PACKET *p; + int processed_current_component; + PKT_signature *sig; + int rc; + int dump_sig_params = 0; + + n_next = n->next; + + if (is_deleted_kbnode (n)) + continue; + + p = n->pkt; + + if (issuer && issuer != pk) { - if (only_selfsigs) - keyid_from_pk (node->pkt->pkt.public_key, keyid); + free_public_key (issuer); + issuer = NULL; } - else if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - if (only_selected) - selected = (node->flag & NODFLG_SELUID); - if (selected) - { - tty_printf ("uid "); - tty_print_utf8_string (uid->name, uid->len); - tty_printf ("\n"); - if (anyuid && !has_selfsig) - mis_selfsig++; - has_selfsig = 0; - anyuid = 1; - } - } - else if (selected && node->pkt->pkttype == PKT_SIGNATURE - && ((node->pkt->pkt.signature->sig_class & ~3) == 0x10 - || node->pkt->pkt.signature->sig_class == 0x30)) - { - int selfsig; - PKT_signature *sig = node->pkt->pkt.signature; + xfree (pending_desc); + pending_desc = NULL; - if (only_selfsigs - && !(keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1])) + switch (p->pkttype) + { + case PKT_PUBLIC_KEY: + assert (p->pkt.public_key == pk); + if (only_selected && ! (n->flag & NODFLG_SELKEY)) { - /* Not a selfsig but we want only selfsigs - skip. */ - /* Static analyzer note: A claim that KEYID above has - garbage is not correct because KEYID is set from the - public key packet which is always the first packet in - a keyblock and thus parsed before this signature. */ + current_component = NULL; + break; } - else if (print_and_check_one_sig (keyblock, node, &inv_sigs, - &no_key, &oth_err, &selfsig, - 0, only_selfsigs)) - { - if (selfsig) - has_selfsig = 1; - } - /* Hmmm: should we update the trustdb here? */ - } + + if (DBG_PACKET) + log_debug ("public key %s: timestamp: %s (%lld)\n", + pk_keyid_str (pk), + isotimestamp (pk->timestamp), + (long long) pk->timestamp); + current_component = n; + break; + case PKT_PUBLIC_SUBKEY: + if (only_selected && ! (n->flag & NODFLG_SELKEY)) + { + current_component = NULL; + break; + } + + if (DBG_PACKET) + log_debug ("subkey %s: timestamp: %s (%lld)\n", + pk_keyid_str (p->pkt.public_key), + isotimestamp (p->pkt.public_key->timestamp), + (long long) p->pkt.public_key->timestamp); + current_component = n; + break; + case PKT_USER_ID: + if (only_selected && ! (n->flag & NODFLG_SELUID)) + { + current_component = NULL; + break; + } + + if (DBG_PACKET) + log_debug ("user id: %s\n", + p->pkt.user_id->attrib_data + ? "[ photo id ]" + : p->pkt.user_id->name); + current_component = n; + break; + case PKT_SIGNATURE: + if (! current_component) + /* The current component is not selected, don't check the + sigs under it. */ + break; + + sig = n->pkt->pkt.signature; + + pending_desc = xasprintf (" sig: class: 0x%x, issuer: %s, timestamp: %s (%lld), digest: %02x %02x", + sig->sig_class, + keystr (sig->keyid), + isotimestamp (sig->timestamp), + (long long) sig->timestamp, + sig->digest_start[0], sig->digest_start[1]); + + + if (keyid_cmp (pk_keyid (pk), sig->keyid) == 0) + issuer = pk; + else + /* Issuer is a different key. */ + { + if (only_selfsigs) + continue; + + issuer = xmalloc (sizeof (*issuer)); + err = get_pubkey (issuer, sig->keyid); + if (err) + { + xfree (issuer); + issuer = NULL; + if (DBG_PACKET) + { + if (pending_desc) + log_debug ("%s", pending_desc); + log_debug (" Can't check signature allegedly issued by %s: %s\n", + keystr (sig->keyid), gpg_strerror (err)); + } + missing_issuer ++; + break; + } + } + + if ((err = openpgp_pk_test_algo (sig->pubkey_algo))) + { + if (DBG_PACKET && pending_desc) + log_debug ("%s", pending_desc); + tty_printf (_("can't check signature with unsupported public-key algorithm (%d): %s.\n"), + sig->pubkey_algo, gpg_strerror (err)); + break; + } + if ((err = openpgp_md_test_algo (sig->digest_algo))) + { + if (DBG_PACKET && pending_desc) + log_debug ("%s", pending_desc); + tty_printf (_("can't check signature with unsupported message-digest algorithm %d: %s.\n"), + sig->digest_algo, gpg_strerror (err)); + break; + } + + /* We iterate over the keyblock. Most likely, the matching + component is the current component so always try that + first. */ + processed_current_component = 0; + for (n2 = current_component; + n2; + n2 = (processed_current_component ? n2->next : kb), + processed_current_component = 1) + if (is_deleted_kbnode (n2)) + continue; + else if (processed_current_component && n2 == current_component) + /* Don't process it twice. */ + continue; + else + { + err = check_signature_over_key_or_uid (issuer, sig, kb, n2->pkt, + NULL, NULL); + if (! err) + break; + } + + /* n/sig is a signature and n2 is the component (public key, + subkey or user id) that it signs, if any. + current_component is that component that it appears to + apply to (according to the ordering). */ + + if (current_component == n2) + { + if (DBG_PACKET) + { + log_debug ("%s", pending_desc); + log_debug (" Good signature over last key or uid!\n"); + } + + rc = 0; + } + else if (n2) + { + assert (n2->pkt->pkttype == PKT_USER_ID + || n2->pkt->pkttype == PKT_PUBLIC_KEY + || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY); + + if (DBG_PACKET) + { + log_debug ("%s", pending_desc); + log_debug (" Good signature out of order! (Over %s (%d) '%s')\n", + n2->pkt->pkttype == PKT_USER_ID + ? "user id" + : n2->pkt->pkttype == PKT_PUBLIC_SUBKEY + ? "subkey" + : "primary key", + n2->pkt->pkttype, + n2->pkt->pkttype == PKT_USER_ID + ? n2->pkt->pkt.user_id->name + : pk_keyid_str (n2->pkt->pkt.public_key)); + } + + /* Reorder the packets: move the signature n to be just + after n2. */ + + /* Unlink the signature. */ + assert (n_prevp); + *n_prevp = n->next; + + /* Insert the sig immediately after the component. */ + n->next = n2->next; + n2->next = n; + + reordered ++; + modified = 1; + + rc = 0; + } + else + { + if (DBG_PACKET) + { + log_debug ("%s", pending_desc); + log_debug (" Bad signature.\n"); + } + + if (DBG_PACKET) + dump_sig_params = 1; + + bad_signature ++; + + rc = GPG_ERR_BAD_SIGNATURE; + } + + /* We don't cache the result here, because we haven't + completely checked that the signature is legitimate. For + instance, if we have a revocation certificate on Alice's + key signed by Bob, the signature may be good, but we + haven't checked that Bob is a designated revoker. */ + /* cache_sig_result (sig, rc); */ + + { + int has_selfsig = 0; + if (! rc && issuer == pk) + { + if (n2->pkt->pkttype == PKT_PUBLIC_KEY + && (/* Direct key signature. */ + sig->sig_class == 0x1f + /* Key revocation signature. */ + || sig->sig_class == 0x20)) + has_selfsig = 1; + if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY + && (/* Subkey binding sig. */ + sig->sig_class == 0x18 + /* Subkey revocation sig. */ + || sig->sig_class == 0x28)) + has_selfsig = 1; + if (n2->pkt->pkttype == PKT_USER_ID + && (/* Certification sigs. */ + sig->sig_class == 0x10 + || sig->sig_class == 0x11 + || sig->sig_class == 0x12 + || sig->sig_class == 0x13 + /* Certification revocation sig. */ + || sig->sig_class == 0x30)) + has_selfsig = 1; + } + + if ((n2 && n2 != last_printed_component) + || (! n2 && last_printed_component != current_component)) + { + int is_reordered = n2 && n2 != current_component; + if (n2) + last_printed_component = n2; + else + last_printed_component = current_component; + + if (last_printed_component->pkt->pkttype == PKT_USER_ID) + { + tty_printf ("uid "); + tty_print_utf8_string (last_printed_component + ->pkt->pkt.user_id->name, + last_printed_component + ->pkt->pkt.user_id->len); + } + else if (last_printed_component->pkt->pkttype + == PKT_PUBLIC_KEY) + tty_printf ("pub %s", + pk_keyid_str (last_printed_component + ->pkt->pkt.public_key)); + else + tty_printf ("sub %s", + pk_keyid_str (last_printed_component + ->pkt->pkt.public_key)); + + if (is_reordered) + tty_printf (_(" (reordered signatures follow)")); + tty_printf ("\n"); + } + + print_one_sig (rc, kb, n, NULL, NULL, NULL, has_selfsig, + 0, only_selfsigs); + } + + if (dump_sig_params) + { + int i; + + for (i = 0; i < pubkey_get_nsig (sig->pubkey_algo); i ++) + { + char buffer[1024]; + size_t len; + char *printable; + gcry_mpi_print (GCRYMPI_FMT_USG, + buffer, sizeof (buffer), &len, + sig->data[i]); + printable = bin2hex (buffer, len, NULL); + log_info (" %d: %s\n", i, printable); + xfree (printable); + } + } + break; + default: + if (DBG_PACKET) + log_debug ("unhandled packet: %d\n", p->pkttype); + break; + } } - if (!has_selfsig) - mis_selfsig++; - if (inv_sigs) - tty_printf (ngettext("%d bad signature\n", - "%d bad signatures\n", inv_sigs), inv_sigs); + xfree (pending_desc); + pending_desc = NULL; - if (no_key) - tty_printf (ngettext("%d signature not checked due to a missing key\n", - "%d signatures not checked due to missing keys\n", - no_key), no_key); + if (issuer != pk) + free_public_key (issuer); + issuer = NULL; - if (oth_err) - tty_printf (ngettext("%d signature not checked due to an error\n", - "%d signatures not checked due to errors\n", - oth_err), oth_err); + /* Identify keys / uids that don't have a self-sig. */ + { + int has_selfsig = 0; + PACKET *p; + PKT_signature *sig; + + current_component = NULL; + for (n = kb; n; n = n->next) + { + if (is_deleted_kbnode (n)) + continue; + + p = n->pkt; + + switch (p->pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_USER_ID: + if (current_component && ! has_selfsig) + missing_selfsig ++; + current_component = n; + has_selfsig = 0; + break; - if (mis_selfsig) - tty_printf (ngettext("%d user ID without valid self-signature detected\n", - "%d user IDs without valid self-signatures detected\n", - mis_selfsig), mis_selfsig); + case PKT_SIGNATURE: + if (! current_component || has_selfsig) + break; + + sig = n->pkt->pkt.signature; + + if (! (sig->flags.checked && sig->flags.valid)) + break; + + if (keyid_cmp (pk_keyid (pk), sig->keyid) != 0) + /* Different issuer, couldn't be a self-sig. */ + break; + + if (current_component->pkt->pkttype == PKT_PUBLIC_KEY + && (/* Direct key signature. */ + sig->sig_class == 0x1f + /* Key revocation signature. */ + || sig->sig_class == 0x20)) + has_selfsig = 1; + if (current_component->pkt->pkttype == PKT_PUBLIC_SUBKEY + && (/* Subkey binding sig. */ + sig->sig_class == 0x18 + /* Subkey revocation sig. */ + || sig->sig_class == 0x28)) + has_selfsig = 1; + if (current_component->pkt->pkttype == PKT_USER_ID + && (/* Certification sigs. */ + sig->sig_class == 0x10 + || sig->sig_class == 0x11 + || sig->sig_class == 0x12 + || sig->sig_class == 0x13 + /* Certification revocation sig. */ + || sig->sig_class == 0x30)) + has_selfsig = 1; + + break; + + default: + if (current_component && ! has_selfsig) + missing_selfsig ++; + current_component = NULL; + } + } + } - return inv_sigs || no_key || oth_err || mis_selfsig; + if (dups || missing_issuer || bad_signature || reordered) + tty_printf (_("key %s:\n"), pk_keyid_str (pk)); + + if (dups) + tty_printf (ngettext ("%d duplicate signature removed\n", + "%d duplicate signatures removed\n", dups), dups); + if (missing_issuer) + tty_printf (ngettext ("%d signature not checked due to a missing key\n", + "%d signatures not checked due to missing keys\n", + missing_issuer), missing_issuer); + if (bad_signature) + tty_printf (ngettext ("%d bad signature\n", + "%d bad signatures\n", + bad_signature), bad_signature); + if (reordered) + tty_printf (ngettext ("%d signature reordered\n", + "%d signatures reordered\n", + reordered), reordered); + + if (only_selfsigs && (bad_signature || reordered)) + tty_printf (_("Warning: errors found and only checked self-signatures, run 'check' to check all signatures.\n")); + + return modified; } @@ -1247,54 +1734,6 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock) -/* - * There are some keys out (due to a bug in gnupg), where the sequence - * of the packets is wrong. This function fixes that. - * Returns: true if the keyblock has been fixed. - * - * Note: This function does not work if there is more than one user ID. - */ -static int -fix_key_signature_order (KBNODE keyblock) -{ - KBNODE node, last, subkey; - int fixed = 0; - - /* Locate key signatures of class 0x10..0x13 behind sub key packets. */ - for (subkey = last = NULL, node = keyblock; node; - last = node, node = node->next) - { - switch (node->pkt->pkttype) - { - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - if (!subkey) - subkey = last; /* Actually it is the one before the subkey. */ - break; - case PKT_SIGNATURE: - if (subkey) - { - PKT_signature *sig = node->pkt->pkt.signature; - if (sig->sig_class >= 0x10 && sig->sig_class <= 0x13) - { - log_info (_("moving a key signature to the correct place\n")); - last->next = node->next; - node->next = subkey->next; - subkey->next = node; - node = last; - fixed = 1; - } - } - break; - default: - break; - } - } - - return fixed; -} - - /* Fix various problems in the keyblock. Returns true if the keyblock was changed. Note that a pointer to the keyblock must be given and the function may change it (i.e. replacing the first node). */ @@ -1303,10 +1742,10 @@ fix_keyblock (kbnode_t *keyblockp) { int changed = 0; - if (fix_key_signature_order (*keyblockp)) - changed++; if (collapse_uids (keyblockp)) changed++; + if (check_all_keysigs (*keyblockp, 0, 1)) + changed++; reorder_keyblock (*keyblockp); /* If we modified the keyblock, make sure the flags are right. */ if (changed) commit 44cdb9d73f1a0b7d2c8483a119b9c4d6caabc1ec Author: Neal H. Walfield Date: Fri Feb 19 15:30:03 2016 +0100 gpg: Split check_key_signature2. * g10/sig-check.c (hash_uid_node): Rename from this... (hash_uid_packet): ... to this. Take a PKT_user_id instead of a KBNODE. (check_key_signature2): Split the basic signature checking functionality into... (check_signature_over_key_or_uid): ... this new function. -- Signed-off-by: Neal H. Walfield diff --git a/g10/main.h b/g10/main.h index 863afa9..f7c47e9 100644 --- a/g10/main.h +++ b/g10/main.h @@ -263,6 +263,19 @@ int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, PKT_public_key *ret_pk, int *is_selfsig, u32 *r_expiredate, int *r_expired ); +/* Returns whether SIGNER generated the signature SIG over the packet + PACKET, which is a key, subkey or uid, and comes from the key block + KB. If SIGNER is NULL, it is looked up based on the information in + SIG. If not NULL, sets *IS_SELFSIG to indicate whether the + signature is a self-signature and *RET_PK to a copy of the signer's + key. */ +gpg_error_t check_signature_over_key_or_uid (PKT_public_key *signer, + PKT_signature *sig, + KBNODE kb, PACKET *packet, + int *is_selfsig, + PKT_public_key *ret_pk); + + /*-- delkey.c --*/ gpg_error_t delete_keys (strlist_t names, int secret, int allow_both); diff --git a/g10/sig-check.c b/g10/sig-check.c index 262afed..4530a64 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -1,7 +1,7 @@ /* sig-check.c - Check a signature * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, * 2004, 2006 Free Software Foundation, Inc. - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015, 2016 g10 Code GmbH * * This file is part of GnuPG. * @@ -481,11 +481,8 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig, /* Add a uid node to a hash context. See section 5.2.4, paragraph 4 of RFC 4880. */ static void -hash_uid_node( KBNODE unode, gcry_md_hd_t md, PKT_signature *sig ) +hash_uid_packet (PKT_user_id *uid, gcry_md_hd_t md, PKT_signature *sig ) { - PKT_user_id *uid = unode->pkt->pkt.user_id; - - assert( unode->pkt->pkttype == PKT_USER_ID ); if( uid->attrib_data ) { if( sig->version >=4 ) { byte buf[5]; @@ -691,6 +688,232 @@ check_key_signature (KBNODE root, KBNODE node, int *is_selfsig) } +/* Returns whether SIGNER generated the signature SIG over the packet + PACKET, which is a key, subkey or uid, and comes from the key block + KB. (KB is PACKET's corresponding keyblock; we don't assume that + SIG has been added to the keyblock.) + + If SIGNER is set, then checks whether SIGNER generated the + signature. Otherwise, uses SIG->KEYID to find the alleged signer. + This parameter can be used to effectively override the alleged + signer that is stored in SIG. + + KB may be NULL if SIGNER is set. + + Unlike check_key_signature, this function ignores any cached + results! That is, it does not consider SIG->FLAGS.CHECKED and + SIG->FLAGS.VALID nor does it set them. + + This doesn't check the signature's semantic mean. Concretely, it + doesn't check whether a non-self signed revocation signature was + created by a designated revoker. In fact, it doesn't return an + error for a binding generated by a completely different key! + + Returns 0 if the signature is valid. Returns GPG_ERR_SIG_CLASS if + this signature can't be over PACKET. Returns GPG_ERR_NOT_FOUND if + the key that generated the signature (according to SIG) could not + be found. Returns GPG_ERR_BAD_SIGNATURE if the signature is bad. + Other errors codes may be returned if something else goes wrong. + + IF IS_SELFSIG is not NULL, sets *IS_SELFSIG to 1 if this is a + self-signature (by the key's primary key) or 0 if not. + + If RET_PK is not NULL, returns a copy of the public key that + generated the signature (i.e., the signer) on success. This must + be released by the caller using release_public_key_parts (). */ +gpg_error_t +check_signature_over_key_or_uid (PKT_public_key *signer, + PKT_signature *sig, KBNODE kb, PACKET *packet, + int *is_selfsig, PKT_public_key *ret_pk) +{ + int rc; + PKT_public_key *pripk = kb->pkt->pkt.public_key; + gcry_md_hd_t md; + int signer_alloced = 0; + + rc = openpgp_pk_test_algo (sig->pubkey_algo); + if (rc) + return rc; + rc = openpgp_md_test_algo (sig->digest_algo); + if (rc) + return rc; + + /* A signature's class indicates the type of packet that it + signs. */ + if (/* Primary key binding (made by a subkey). */ + sig->sig_class == 0x19 + /* Direct key signature. */ + || sig->sig_class == 0x1f + /* Primary key revocation. */ + || sig->sig_class == 0x20) + { + if (packet->pkttype != PKT_PUBLIC_KEY) + /* Key revocations can only be over primary keys. */ + return gpg_error (GPG_ERR_SIG_CLASS); + } + else if (/* Subkey binding. */ + sig->sig_class == 0x18 + /* Subkey revocation. */ + || sig->sig_class == 0x28) + { + if (packet->pkttype != PKT_PUBLIC_SUBKEY) + return gpg_error (GPG_ERR_SIG_CLASS); + } + else if (/* Certification. */ + sig->sig_class == 0x10 + || sig->sig_class == 0x11 + || sig->sig_class == 0x12 + || sig->sig_class == 0x13 + /* Certification revocation. */ + || sig->sig_class == 0x30) + { + if (packet->pkttype != PKT_USER_ID) + return gpg_error (GPG_ERR_SIG_CLASS); + } + else + return gpg_error (GPG_ERR_SIG_CLASS); + + /* PACKET is the right type for SIG. */ + + if (signer) + { + if (is_selfsig) + { + if (signer->keyid[0] == pripk->keyid[0] + && signer->keyid[1] == pripk->keyid[1]) + *is_selfsig = 1; + else + *is_selfsig = 0; + } + } + else + { + /* Get the signer. If possible, avoid a look up. */ + if (sig->keyid[0] == pripk->keyid[0] + && sig->keyid[1] == pripk->keyid[1]) + /* Issued by the primary key. */ + { + signer = pripk; + if (is_selfsig) + *is_selfsig = 1; + } + else + /* See if one of the subkeys was the signer (although this is + extremely unlikely). */ + { + kbnode_t ctx = NULL; + kbnode_t n; + + while ((n = walk_kbnode (kb, &ctx, PKT_PUBLIC_SUBKEY))) + { + PKT_public_key *subk = n->pkt->pkt.public_key; + if (sig->keyid[0] == subk->keyid[0] + && sig->keyid[1] == subk->keyid[1]) + /* Issued by a subkey. */ + { + signer = subk; + break; + } + } + + if (! signer) + /* Signer by some other key. */ + { + if (is_selfsig) + *is_selfsig = 0; + if (ret_pk) + { + signer = ret_pk; + memset (signer, 0, sizeof (*signer)); + signer_alloced = 1; + } + else + { + signer = xmalloc_clear (sizeof (*signer)); + signer_alloced = 2; + } + + rc = get_pubkey (signer, sig->keyid); + if (rc) + { + xfree (signer); + signer = NULL; + signer_alloced = 0; + goto out; + } + } + } + } + + /* We checked above that we supported this algo, so an error here is + a bug. */ + if (gcry_md_open (&md, sig->digest_algo, 0)) + BUG (); + + /* Hash the relevant data. */ + + if (/* Direct key signature. */ + sig->sig_class == 0x1f + /* Primary key revocation. */ + || sig->sig_class == 0x20) + { + assert (packet->pkttype == PKT_PUBLIC_KEY); + hash_public_key (md, packet->pkt.public_key); + rc = check_signature_end_simple (signer, sig, md); + } + else if (/* Primary key binding (made by a subkey). */ + sig->sig_class == 0x19) + { + assert (packet->pkttype == PKT_PUBLIC_KEY); + hash_public_key (md, packet->pkt.public_key); + hash_public_key (md, signer); + rc = check_signature_end_simple (signer, sig, md); + } + else if (/* Subkey binding. */ + sig->sig_class == 0x18 + /* Subkey revocation. */ + || sig->sig_class == 0x28) + { + assert (packet->pkttype == PKT_PUBLIC_SUBKEY); + hash_public_key (md, pripk); + hash_public_key (md, packet->pkt.public_key); + rc = check_signature_end_simple (signer, sig, md); + } + else if (/* Certification. */ + sig->sig_class == 0x10 + || sig->sig_class == 0x11 + || sig->sig_class == 0x12 + || sig->sig_class == 0x13 + /* Certification revocation. */ + || sig->sig_class == 0x30) + { + assert (packet->pkttype == PKT_USER_ID); + hash_public_key (md, pripk); + hash_uid_packet (packet->pkt.user_id, md, sig); + rc = check_signature_end_simple (signer, sig, md); + } + else + /* We should never get here. (The first if above should have + already caught this error.) */ + BUG (); + + gcry_md_close (md); + + out: + if (! rc && ret_pk && (signer_alloced == -1 || ret_pk != signer)) + copy_public_key (ret_pk, signer); + if (signer_alloced == 1) + /* We looked up SIGNER; it is not a pointer into KB. */ + { + release_public_key_parts (signer); + if (signer_alloced == 2) + /* We also allocated the memory. */ + xfree (signer); + } + + return rc; +} + /* Check that a signature over a key (e.g., a key revocation, key * binding, user id certification, etc.) is valid. If the function * detects a self-signature, it uses the public key from the specified @@ -730,7 +953,6 @@ check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, PKT_public_key *ret_pk, int *is_selfsig, u32 *r_expiredate, int *r_expired ) { - gcry_md_hd_t md; PKT_public_key *pk; PKT_signature *sig; int algo; @@ -791,114 +1013,69 @@ check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, rc = check_revocation_keys (pk, sig); else { - if (gcry_md_open (&md, algo, 0)) - BUG (); - hash_public_key (md, pk); - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result (sig, rc); - gcry_md_close (md); + rc = check_signature_metadata_validity (pk, sig, + r_expired, NULL); + if (! rc) + rc = check_signature_over_key_or_uid (pk, sig, root, root->pkt, + is_selfsig, ret_pk); } } - else if (sig->sig_class == 0x28) /* subkey revocation */ + else if (sig->sig_class == 0x28 /* subkey revocation */ + || sig->sig_class == 0x18) /* key binding */ { kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY); if (snode) { - if (gcry_md_open (&md, algo, 0)) - BUG (); - hash_public_key (md, pk); - hash_public_key (md, snode->pkt->pkt.public_key); - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result (sig, rc); - gcry_md_close (md); + rc = check_signature_metadata_validity (pk, sig, + r_expired, NULL); + if (! rc) + /* 0x28 must be a self-sig, but 0x18 needn't be. */ + rc = check_signature_over_key_or_uid (sig->sig_class == 0x18 + ? NULL : pk, + sig, root, snode->pkt, + is_selfsig, ret_pk); } else { if (opt.verbose) - log_info (_("key %s: no subkey for subkey" - " revocation signature\n"), keystr_from_pk(pk)); + { + if (sig->sig_class == 0x28) + log_info (_("key %s: no subkey for subkey" + " revocation signature\n"), keystr_from_pk(pk)); + else if (sig->sig_class == 0x18) + log_info(_("key %s: no subkey for subkey" + " binding signature\n"), keystr_from_pk(pk)); + } rc = GPG_ERR_SIG_CLASS; } } - else if (sig->sig_class == 0x18) /* key binding */ - { - kbnode_t snode = find_prev_kbnode (root, node, PKT_PUBLIC_SUBKEY); - - if (snode) - { - if (is_selfsig) - { - /* Does this make sense? It should always be a - selfsig. Yes: We can't be sure about this and we - need to be able to indicate that it is a selfsig. - FIXME: The question is whether we should reject - such a signature if it is not a selfsig. */ - u32 keyid[2]; - - keyid_from_pk (pk, keyid); - if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]) - *is_selfsig = 1; - } - if (gcry_md_open (&md, algo, 0)) - BUG (); - hash_public_key (md, pk); - hash_public_key (md, snode->pkt->pkt.public_key); - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result ( sig, rc ); - gcry_md_close (md); - } - else - { - if (opt.verbose) - log_info(_("key %s: no subkey for subkey" - " binding signature\n"), keystr_from_pk(pk)); - rc = GPG_ERR_SIG_CLASS; - } - } else if (sig->sig_class == 0x1f) /* direct key signature */ { - if (gcry_md_open (&md, algo, 0 )) - BUG (); - hash_public_key( md, pk ); - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - cache_sig_result (sig, rc); - gcry_md_close (md); + rc = check_signature_metadata_validity (pk, sig, + r_expired, NULL); + if (! rc) + rc = check_signature_over_key_or_uid (pk, sig, root, root->pkt, + is_selfsig, ret_pk); } - else /* all other classes */ + else if (/* Certification. */ + sig->sig_class == 0x10 + || sig->sig_class == 0x11 + || sig->sig_class == 0x12 + || sig->sig_class == 0x13 + /* Certification revocation. */ + || sig->sig_class == 0x30) { kbnode_t unode = find_prev_kbnode (root, node, PKT_USER_ID); if (unode) { - u32 keyid[2]; - - keyid_from_pk (pk, keyid); - if (gcry_md_open (&md, algo, 0)) - BUG (); - hash_public_key (md, pk); - hash_uid_node (unode, md, sig); - if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]) - { /* The primary key is the signing key. */ - - if (is_selfsig) - *is_selfsig = 1; - rc = check_signature_end (pk, sig, md, r_expired, NULL, ret_pk); - } - else if (check_pk) - { /* The caller specified a key. Try that. */ - - rc = check_signature_end (check_pk, sig, md, - r_expired, NULL, ret_pk); - } - else - { /* Look up the key. */ - rc = check_signature2 (sig, md, r_expiredate, r_expired, - NULL, ret_pk); - } - - cache_sig_result (sig, rc); - gcry_md_close (md); + rc = check_signature_metadata_validity (pk, sig, r_expired, NULL); + if (! rc) + /* If this is a self-sig, ignore check_pk. */ + rc = check_signature_over_key_or_uid + (keyid_cmp (pk_keyid (pk), sig->keyid) == 0 ? pk : check_pk, + sig, root, unode->pkt, NULL, ret_pk); } else { @@ -908,6 +1085,10 @@ check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, rc = GPG_ERR_SIG_CLASS; } } + else + BUG (); + + cache_sig_result (sig, rc); return rc; } commit 5fbd80579aea0f75ca1d2700515c5b8747a75c7d Author: Neal H. Walfield Date: Fri Feb 19 15:13:22 2016 +0100 gpg: Split print_and_check_one_sig. * g10/keyedit.c (print_and_check_one_sig): Split the print functionality into... (print_one_sig): ... this new function. -- Signed-off-by: Neal H. Walfield diff --git a/g10/keyedit.c b/g10/keyedit.c index f2ef613..8cec66a 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1,7 +1,7 @@ /* keyedit.c - Edit properties of a key * Copyright (C) 1998-2010 Free Software Foundation, Inc. * Copyright (C) 1998-2015 Werner Koch - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015, 2016 g10 Code GmbH * * This file is part of GnuPG. * @@ -189,24 +189,23 @@ print_and_check_one_sig_colon (KBNODE keyblock, KBNODE node, /* - * Print information about a signature, check it and return true if - * the signature is okay. NODE must be a signature packet. With - * EXTENDED set all possible signature list options will always be - * printed. + * Print information about a signature (rc is its status), check it + * and return true if the signature is okay. NODE must be a signature + * packet. With EXTENDED set all possible signature list options will + * always be printed. */ static int -print_and_check_one_sig (KBNODE keyblock, KBNODE node, - int *inv_sigs, int *no_key, int *oth_err, - int *is_selfsig, int print_without_key, int extended) +print_one_sig (int rc, KBNODE keyblock, KBNODE node, + int *inv_sigs, int *no_key, int *oth_err, + int is_selfsig, int print_without_key, int extended) { PKT_signature *sig = node->pkt->pkt.signature; - int rc, sigrc; + int sigrc; int is_rev = sig->sig_class == 0x30; /* TODO: Make sure a cached sig record here still has the pk that issued it. See also keylist.c:list_keyblock_print */ - rc = check_key_signature (keyblock, node, is_selfsig); switch (gpg_err_code (rc)) { case 0: @@ -257,7 +256,7 @@ print_and_check_one_sig (KBNODE keyblock, KBNODE node, tty_printf ("[%s] ", gpg_strerror (rc)); else if (sigrc == '?') ; - else if (*is_selfsig) + else if (is_selfsig) { tty_printf (is_rev ? _("[revocation]") : _("[self-signature]")); if (extended && sig->flags.chosen_selfsig) @@ -311,6 +310,16 @@ print_and_check_one_sig (KBNODE keyblock, KBNODE node, return (sigrc == '!'); } +static int +print_and_check_one_sig (KBNODE keyblock, KBNODE node, + int *inv_sigs, int *no_key, int *oth_err, + int *is_selfsig, int print_without_key, int extended) +{ + return print_one_sig (check_key_signature (keyblock, node, is_selfsig), + keyblock, node, inv_sigs, no_key, oth_err, + *is_selfsig, print_without_key, extended); +} + /* commit ac5aea95455372145f3f06df2b4c1584d759d660 Author: Neal H. Walfield Date: Fri Feb 19 14:10:09 2016 +0100 gpg: Split the function check_signature_end. * g10/sig-check.c (check_signature_end): Break the basic signature check into... (check_signature_end_simple): ... this new function. -- Signed-off-by: Neal H. Walfield diff --git a/g10/sig-check.c b/g10/sig-check.c index 292adb9..262afed 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -40,6 +40,9 @@ static int check_signature_end (PKT_public_key *pk, PKT_signature *sig, int *r_expired, int *r_revoked, PKT_public_key *ret_pk); +static int check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig, + gcry_md_hd_t digest); + /* Check a signature. This is shorthand for check_signature2 with the unnamed arguments passed as NULL. */ int @@ -376,14 +379,32 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest, int *r_expired, int *r_revoked, PKT_public_key *ret_pk) { - gcry_mpi_t result = NULL; int rc = 0; - const struct weakhash *weak; if ((rc = check_signature_metadata_validity (pk, sig, r_expired, r_revoked))) return rc; + if ((rc = check_signature_end_simple (pk, sig, digest))) + return rc; + + if(!rc && ret_pk) + copy_public_key(ret_pk,pk); + + return rc; +} + +/* This function is similar to check_signature_end, but it only checks + whether the signature was generated by PK. It does not check + expiration, revocation, etc. */ +static int +check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig, + gcry_md_hd_t digest) +{ + gcry_mpi_t result = NULL; + int rc = 0; + const struct weakhash *weak; + if (!opt.flags.allow_weak_digest_algos) for (weak = opt.weak_digests; weak; weak = weak->next) if (sig->digest_algo == weak->algo) @@ -453,9 +474,6 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig, rc = GPG_ERR_BAD_SIGNATURE; } - if(!rc && ret_pk) - copy_public_key(ret_pk,pk); - return rc; } commit 10671c3a4c18ea26035a5819a9f2b8fd6c7e41ea Author: Neal H. Walfield Date: Fri Feb 19 14:59:19 2016 +0100 gpg: Use format_keyid rather than manually formatting the keyid. * g10/keyedit.c (menu_addrevoker): Use format_keyid rather than manually formatting the keyid. * g10/keygen.c (card_write_key_to_backup_file): Likewise. -- Signed-off-by: Neal H. Walfield diff --git a/g10/keyedit.c b/g10/keyedit.c index 19ddf29..f2ef613 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3953,8 +3953,7 @@ menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive) log_error (_("this key has already been designated " "as a revoker\n")); - sprintf (buf, "%08lX%08lX", - (ulong) pk->keyid[0], (ulong) pk->keyid[1]); + format_keyid (pk_keyid (pk), KF_LONG, buf, sizeof (buf)); write_status_text (STATUS_ALREADY_SIGNED, buf); break; diff --git a/g10/keygen.c b/g10/keygen.c index be132bb..8f25fe9 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3840,15 +3840,15 @@ card_write_key_to_backup_file (PKT_public_key *sk, const char *backup_dir) { gpg_error_t err = 0; int rc; + char keyid_buffer[2 * 8 + 1]; char name_buffer[50]; char *fname; IOBUF fp; mode_t oldmask; PACKET *pkt = NULL; - keyid_from_pk (sk, NULL); - snprintf (name_buffer, sizeof name_buffer, "sk_%08lX%08lX.gpg", - (ulong)sk->keyid[0], (ulong)sk->keyid[1]); + format_keyid (pk_keyid (sk), KF_LONG, keyid_buffer, sizeof (keyid_buffer)); + snprintf (name_buffer, sizeof name_buffer, "sk_%s.gpg", keyid_buffer); fname = make_filename (backup_dir, name_buffer, NULL); /* Note that the umask call is not anymore needed because commit bf9d1248c80205795e26156f67aff0b3f796cfce Author: Neal H. Walfield Date: Fri Feb 19 14:53:29 2016 +0100 gpg: Initialize the primary key when generating a key. * g10/keygen.c (do_generate_keypair): Initialize pri_psk->flags.primary, pri_psk->keyid and pri_psk->main_keyid. -- Signed-off-by: Neal H. Walfield diff --git a/g10/keygen.c b/g10/keygen.c index 7b5a35b..be132bb 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -4079,6 +4079,13 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, assert (pri_psk); } + /* Make sure a few fields are correctly set up before going further. */ + pri_psk->flags.primary = 1; + keyid_from_pk (pri_psk, NULL); + /* We don't use pk_keyid to get keyid, because it also asserts that + main_keyid is set! */ + keyid_copy (pri_psk->main_keyid, pri_psk->keyid); + if (!err && (revkey = get_parameter_revkey (para, pREVOKER))) err = write_direct_sig (pub_root, pri_psk, revkey, timestamp, cache_nonce); commit c45633a571bf663bc7f3610fc481acded6acfc19 Author: Neal H. Walfield Date: Fri Feb 19 14:48:56 2016 +0100 gpg: Add accessor & utility functions for pk->keyid and pk->main_keyid. * g10/keydb.h (keyid_cmp): New function. * g10/keyid.c (pk_keyid): New function. (pk_main_keyid): New function. (keyid_copy): New function. (pk_keyid_str): New function. * g10/packet.h (PKT_public_key): Update comments for main_keyid and keyid. -- Signed-off-by: Neal H. Walfield Before accessing pk->keyid, it is necessary to call keyid_from_pk (pk, NULL) to ensure that pk->keyid is valid. Because it is easy to forget to do this, these accessor functions take care of it. diff --git a/g10/keydb.h b/g10/keydb.h index 8d4e36c..8896eea 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -1,7 +1,7 @@ /* keydb.h - Key database * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, * 2006, 2010 Free Software Foundation, Inc. - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015, 2016 g10 Code GmbH * * This file is part of GnuPG. * @@ -396,12 +396,44 @@ char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize); u32 v3_keyid (gcry_mpi_t a, u32 *ki); void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ); char *format_keyid (u32 *keyid, int format, char *buffer, int len); + +/* Return PK's keyid. The memory is owned by PK. */ +u32 *pk_keyid (PKT_public_key *pk); + +/* Return the keyid of the primary key associated with PK. The memory + is owned by PK. */ +u32 *pk_main_keyid (PKT_public_key *pk); + +/* Order A and B. If A < B then return -1, if A == B then return 0, + and if A > B then return 1. */ +static int GPGRT_ATTR_UNUSED +keyid_cmp (const u32 *a, const u32 *b) +{ + if (a[0] < b[0]) + return -1; + if (a[0] > b[0]) + return 1; + if (a[1] < b[1]) + return -1; + if (a[1] > b[1]) + return 1; + return 0; +} + +/* Copy the keyid in SRC to DEST and return DEST. */ +u32 *keyid_copy (u32 *dest, const u32 *src); + size_t keystrlen(void); const char *keystr(u32 *keyid); const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid); const char *keystr_from_pk(PKT_public_key *pk); const char *keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk); + +/* Return PK's key id as a string using the default format. PK owns + the storage. */ +const char *pk_keyid_str (PKT_public_key *pk); + const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc); u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid ); u32 keyid_from_sig( PKT_signature *sig, u32 *keyid ); diff --git a/g10/keyid.c b/g10/keyid.c index 49eb5f6..f2a5e03 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -2,6 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, * 2004, 2006, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch + * Copyright (C) 2016 g10 Code GmbH * * This file is part of GnuPG. * @@ -274,6 +275,52 @@ v3_keyid (gcry_mpi_t a, u32 *ki) } +/* Return PK's keyid. The memory is owned by PK. */ +u32 * +pk_keyid (PKT_public_key *pk) +{ + keyid_from_pk (pk, NULL); + + /* Uncomment this for help tracking down bugs related to keyid or + main_keyid not being set correctly. */ +#if 0 + if (! (pk->main_keyid[0] || pk->main_keyid[1])) + log_bug ("pk->main_keyid not set!\n"); + if (keyid_cmp (pk->keyid, pk->main_keyid) == 0 + && ! pk->flags.primary) + log_bug ("keyid and main_keyid are the same, but primary flag not set!\n"); + if (keyid_cmp (pk->keyid, pk->main_keyid) != 0 + && pk->flags.primary) + log_bug ("keyid and main_keyid are different, but primary flag set!\n"); +#endif + + return pk->keyid; +} + +/* Return the keyid of the primary key associated with PK. The memory + is owned by PK. */ +u32 * +pk_main_keyid (PKT_public_key *pk) +{ + /* Uncomment this for help tracking down bugs related to keyid or + main_keyid not being set correctly. */ +#if 0 + if (! (pk->main_keyid[0] || pk->main_keyid[1])) + log_bug ("pk->main_keyid not set!\n"); +#endif + + return pk->main_keyid; +} + +/* Copy the keyid in SRC to DEST and return DEST. */ +u32 * +keyid_copy (u32 *dest, const u32 *src) +{ + dest[0] = src[0]; + dest[1] = src[1]; + return dest; +} + char * format_keyid (u32 *keyid, int format, char *buffer, int len) { @@ -396,6 +443,14 @@ keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk) } +/* Return PK's key id as a string using the default format. PK owns + the storage. */ +const char * +pk_keyid_str (PKT_public_key *pk) +{ + return keystr (pk_keyid (pk)); +} + const char * keystr_from_desc(KEYDB_SEARCH_DESC *desc) diff --git a/g10/packet.h b/g10/packet.h index 16524f8..dfd3a00 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -279,8 +279,12 @@ typedef struct byte pubkey_usage; /* for now only used to pass it to getkey() */ byte req_usage; /* hack to pass a request to getkey() */ u32 has_expired; /* set to the expiration date if expired */ - u32 main_keyid[2]; /* keyid of the primary key */ - u32 keyid[2]; /* calculated by keyid_from_pk() */ + /* keyid of the primary key. Never access this value directly. + Instead, use pk_main_keyid(). */ + u32 main_keyid[2]; + /* keyid of this key. Never access this value directly! Instead, + use pk_keyid(). */ + u32 keyid[2]; prefitem_t *prefs; /* list of preferences (may be NULL) */ struct { ----------------------------------------------------------------------- Summary of changes: g10/keydb.h | 34 ++- g10/keyedit.c | 723 +++++++++++++++++++++++++++++++++++++++++++++----------- g10/keygen.c | 13 +- g10/keyid.c | 55 +++++ g10/main.h | 13 + g10/packet.h | 8 +- g10/sig-check.c | 393 ++++++++++++++++++++++-------- 7 files changed, 998 insertions(+), 241 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 20 14:47:39 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 20 Feb 2016 14:47:39 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-332-g839d12c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 839d12c221430b60db5e0d6fbb107f22e0a6837f (commit) via 3b57e5a1ba68e26dcaea38b763287fddba9b6b7c (commit) from e9b692d25d1c149b5417b70e18f2ce173bc25b6d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 839d12c221430b60db5e0d6fbb107f22e0a6837f Author: Werner Koch Date: Sat Feb 20 14:41:56 2016 +0100 tests: Do not test DRBG_REINIT from "make check" * tests/random.c (main): Run check_drbg_reinit only if the envvar GCRYPT_IN_REGRESSION_TEST is set. -- Without a hardware entropy generator (e.g. the moonbase token) running the regression suite would take too long. We better use a set of test vectors when run from "make check". Signed-off-by: Werner Koch diff --git a/tests/random.c b/tests/random.c index 8aa730b..2a4b698 100644 --- a/tests/random.c +++ b/tests/random.c @@ -666,7 +666,10 @@ main (int argc, char **argv) check_nonce_forking (); check_close_random_device (); } - check_drbg_reinit (); + /* For now we do not run the drgb_reinit check from "make check" due + to its high requirement for entropy. */ + if (!getenv ("GCRYPT_IN_REGRESSION_TEST")) + check_drbg_reinit (); check_rng_type_switching (); if (!in_recursion) commit 3b57e5a1ba68e26dcaea38b763287fddba9b6b7c Author: Werner Koch Date: Wed Feb 17 19:34:21 2016 +0100 doc: Fix possible dependency problem. * doc/Makefile.am (gcrypt.texi): Use the right traget. Signed-off-by: Werner Koch diff --git a/doc/Makefile.am b/doc/Makefile.am index 30330bb..6a7cc8e 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -83,7 +83,7 @@ $(myman_pages) : yat2m-stamp # Make sure that gcrypt.texi is touched if any other source file has # been modified. This is required so that the version.texi magic # updates the release date. -gnupg.texi : $(gcrypt_TEXINFOS) +gcrypt.texi : $(gcrypt_TEXINFOS) touch $(srcdir)/gcrypt.texi online: gcrypt.html gcrypt.pdf gcrypt.info ----------------------------------------------------------------------- Summary of changes: doc/Makefile.am | 2 +- tests/random.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Sat Feb 20 20:37:18 2016 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 20 Feb 2016 20:37:18 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-333-g531b25a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 531b25aa94c58f6d2168a9537c8cea6c53d7bbe0 (commit) from 839d12c221430b60db5e0d6fbb107f22e0a6837f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 531b25aa94c58f6d2168a9537c8cea6c53d7bbe0 Author: Jussi Kivilinna Date: Sat Feb 20 21:27:15 2016 +0200 Fix building random-drbg for Win32/64 * random/random-drbg.c: Remove include for sys/types.h and asm/types.h. (DRBG_PREDICTION_RESIST, DRBG_CTRAES, DRBG_CTRSERPENT, DRBG_CTRTWOFISH) (DRBG_HASHSHA1, DRBG_HASHSHA224, DRBG_HASHSHA256, DRBG_HASHSHA384) (DRBG_HASHSHA512, DRBG_HMAC, DRBG_SYM128, DRBG_SYM192) (DRBG_SYM256): Change 'u_int32_t' to 'u32'. (drbg_get_entropy) [USE_RNDUNIX, USE_RNDW32]: Fix parameters 'drbg_read_cb' and 'len'. -- Signed-off-by: Jussi Kivilinna diff --git a/random/random-drbg.c b/random/random-drbg.c index c7b6484..f9d11a3 100644 --- a/random/random-drbg.c +++ b/random/random-drbg.c @@ -146,8 +146,6 @@ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); */ -#include -#include #include #include #include @@ -177,29 +175,29 @@ */ /* Internal state control flags (B) */ -#define DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) +#define DRBG_PREDICTION_RESIST ((u32)1<<28) /* CTR type modifiers (A.1)*/ -#define DRBG_CTRAES ((u_int32_t)1<<0) -#define DRBG_CTRSERPENT ((u_int32_t)1<<1) -#define DRBG_CTRTWOFISH ((u_int32_t)1<<2) +#define DRBG_CTRAES ((u32)1<<0) +#define DRBG_CTRSERPENT ((u32)1<<1) +#define DRBG_CTRTWOFISH ((u32)1<<2) #define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT \ | DRBG_CTRTWOFISH) /* HASH type modifiers (A.2)*/ -#define DRBG_HASHSHA1 ((u_int32_t)1<<4) -#define DRBG_HASHSHA224 ((u_int32_t)1<<5) -#define DRBG_HASHSHA256 ((u_int32_t)1<<6) -#define DRBG_HASHSHA384 ((u_int32_t)1<<7) -#define DRBG_HASHSHA512 ((u_int32_t)1<<8) +#define DRBG_HASHSHA1 ((u32)1<<4) +#define DRBG_HASHSHA224 ((u32)1<<5) +#define DRBG_HASHSHA256 ((u32)1<<6) +#define DRBG_HASHSHA384 ((u32)1<<7) +#define DRBG_HASHSHA512 ((u32)1<<8) #define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 \ | DRBG_HASHSHA256 | DRBG_HASHSHA384 \ | DRBG_HASHSHA512) /* type modifiers (A.3)*/ -#define DRBG_HMAC ((u_int32_t)1<<12) -#define DRBG_SYM128 ((u_int32_t)1<<13) -#define DRBG_SYM192 ((u_int32_t)1<<14) -#define DRBG_SYM256 ((u_int32_t)1<<15) +#define DRBG_HMAC ((u32)1<<12) +#define DRBG_SYM128 ((u32)1<<13) +#define DRBG_SYM192 ((u32)1<<14) +#define DRBG_SYM256 ((u32)1<<15) #define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 \ | DRBG_SYM256) #define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK \ @@ -632,12 +630,12 @@ drbg_get_entropy (drbg_state_t drbg, unsigned char *buffer, rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, GCRY_VERY_STRONG_RANDOM); #elif USE_RNDUNIX - rc = _gcry_rndunix_gather_random (read_cb, 0, length, + rc = _gcry_rndunix_gather_random (drbg_read_cb, 0, len, GCRY_VERY_STRONG_RANDOM); #elif USE_RNDW32 do { - rc = _gcry_rndw32_gather_random (read_cb, 0, length, + rc = _gcry_rndw32_gather_random (drbg_read_cb, 0, len, GCRY_VERY_STRONG_RANDOM); } while (rc >= 0 && read_cb_len < read_cb_size); ----------------------------------------------------------------------- Summary of changes: random/random-drbg.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Feb 22 08:19:12 2016 From: cvs at cvs.gnupg.org (by Andreas Metzler) Date: Mon, 22 Feb 2016 08:19:12 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-334-g2b40a16 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 2b40a16333fa75f1cee85ab901a5aa9cff845a92 (commit) from 531b25aa94c58f6d2168a9537c8cea6c53d7bbe0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2b40a16333fa75f1cee85ab901a5aa9cff845a92 Author: Andreas Metzler Date: Sun Feb 21 12:18:33 2016 +0100 Do not ship generated header file in tarball. * src/Makefile.am: Move gcrypt.h from include_HEADERS to nodist_include_HEADERS to prevent inclusion in release tarball. This could break out-of-tree-builds because the potentially outdated src/gcrypt.h was not updated but was in the compiler search path. diff --git a/src/Makefile.am b/src/Makefile.am index 4ef95cb..aee2828 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ EXTRA_DIST = libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \ bin_SCRIPTS = libgcrypt-config m4datadir = $(datadir)/aclocal m4data_DATA = libgcrypt.m4 -include_HEADERS = gcrypt.h +nodist_include_HEADERS = gcrypt.h lib_LTLIBRARIES = libgcrypt.la bin_PROGRAMS = dumpsexp hmac256 mpicalc ----------------------------------------------------------------------- Summary of changes: src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 23 15:53:31 2016 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 23 Feb 2016 15:53:31 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-60-gf7968db Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via f7968db30b0e0ccae038e354568accb0a05d877c (commit) via f26867928c451443769fecc41c3283e077e8c49f (commit) from ede0061febe5b2edde6a1a79d599e3c7c0faed5a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f7968db30b0e0ccae038e354568accb0a05d877c Author: Werner Koch Date: Tue Feb 23 14:32:46 2016 +0100 g13: Add commands --suspend and --remove. * g13/g13.c (aSuspend, aResume): New. (opts): Add commands --suspend and --resume. (main): Implement dummy command aUmount. Implement commands aResume and aSuspend. * g13/sh-cmd.c (cmd_suspend): New. (cmd_resume): New. (register_commands): Add commands RESUME and SUSPEND. * g13/server.c (cmd_suspend): New. (cmd_resume): New. (register_commands): Add commands RESUME and SUSPEND. * g13/be-dmcrypt.c (be_dmcrypt_suspend_container): New. (be_dmcrypt_resume_container): New. * g13/backend.c (be_suspend_container): New. (be_resume_container): New. * g13/suspend.c, g13/suspend.h: New. * g13/mount.c (parse_header, read_keyblob_prefix, read_keyblob) (decrypt_keyblob, g13_is_container): Move to ... * g13/keyblob.c: new file. (keyblob_read): Rename to g13_keyblob_read and make global. (keyblob_decrypt): Rename to g13_keyblob_decrypt and make global. * g13/sh-dmcrypt.c (check_blockdev): Add arg expect_busy. (sh_dmcrypt_suspend_container): New. (sh_dmcrypt_resume_container): New. * g13/call-syshelp.c (call_syshelp_run_suspend): New. (call_syshelp_run_resume): New. -- The --suspend command can be used before a hibernate operation to make the encrypted partition inaccessible and wipe the key from the memory. Before --suspend is called a sync(1) should be run to make sure that their are no dirty buffers (dmsetup, as called by g13, actually does this for you but it does not harm to do it anyway. After the partition has been suspended a echo 3 >proc/sys/vm/drop_caches required to flush all caches which may still have content from the encrypted partition. The --resume command reverses the effect of the suspend but to do this it needs to decrypt again. Now, if the .gnupg directory lives on the encrypted partition this will be problematic because due to the suspend all processes accessing data on the encrypted partition will be put into an uninterruptible sleep (ps(1) shows a state of 'D'). This needs to be avoided. A workaround is to have a separate GnuPG home directory (say, "~/.gnupg-fallback") with only the public keys required to decrypt the partition along with a properly setup conf files. A GNUPGHOME=$(pwd)/.gnupg-fallback g13 --resume should then be able to resume the encrypted partition using the private key stored on a smartcard. The implementation is pretty basic right now but useful to me. Signed-off-by: Werner Koch diff --git a/g13/Makefile.am b/g13/Makefile.am index 4244a74..05963c8 100644 --- a/g13/Makefile.am +++ b/g13/Makefile.am @@ -35,11 +35,12 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) g13_SOURCES = \ g13.c g13.h \ g13-common.c g13-common.h \ - keyblob.h \ + keyblob.c keyblob.h \ g13tuple.c g13tuple.h \ server.c server.h \ create.c create.h \ mount.c mount.h \ + suspend.c suspend.h \ mountinfo.c mountinfo.h \ call-syshelp.c call-syshelp.h \ runner.c runner.h \ diff --git a/g13/backend.c b/g13/backend.c index bb7bfcc..dd21768 100644 --- a/g13/backend.c +++ b/g13/backend.c @@ -198,7 +198,7 @@ be_create_new_keys (int conttype, membuf_t *mb) } -/* Dispatcher to the backend's create function. */ +/* Dispatcher to the backend's create function. */ gpg_error_t be_create_container (ctrl_t ctrl, int conttype, const char *fname, int fd, tupledesc_t tuples, @@ -220,7 +220,7 @@ be_create_container (ctrl_t ctrl, int conttype, } -/* Dispatcher to the backend's mount function. */ +/* Dispatcher to the backend's mount function. */ gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, const char *fname, const char *mountpoint, @@ -238,3 +238,40 @@ be_mount_container (ctrl_t ctrl, int conttype, return no_such_backend (conttype); } } + + +/* Dispatcher to the backend's suspend function. */ +gpg_error_t +be_suspend_container (ctrl_t ctrl, int conttype, const char *fname) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_suspend_container (ctrl, fname); + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's resume function. */ +gpg_error_t +be_resume_container (ctrl_t ctrl, int conttype, const char *fname, + tupledesc_t tuples) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_resume_container (ctrl, fname, tuples); + + default: + return no_such_backend (conttype); + } +} diff --git a/g13/backend.h b/g13/backend.h index 0f391d0..66d9cd5 100644 --- a/g13/backend.h +++ b/g13/backend.h @@ -39,6 +39,10 @@ gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, const char *fname, const char *mountpoint, tupledesc_t tuples, unsigned int *r_id); +gpg_error_t be_suspend_container (ctrl_t ctrl, int conttype, + const char *fname); +gpg_error_t be_resume_container (ctrl_t ctrl, int conttype, + const char *fname, tupledesc_t tuples); #endif /*G13_BACKEND_H*/ diff --git a/g13/be-dmcrypt.c b/g13/be-dmcrypt.c index 3255676..e5e9b33 100644 --- a/g13/be-dmcrypt.c +++ b/g13/be-dmcrypt.c @@ -62,3 +62,38 @@ be_dmcrypt_mount_container (ctrl_t ctrl, leave: return err; } + + +/* Suspend the container described by the filename FNAME. */ +gpg_error_t +be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_suspend (ctrl, CONTTYPE_DM_CRYPT); + + leave: + return err; +} + + +/* Resume the container described by the filename FNAME and the keyblob + * information in TUPLES. */ +gpg_error_t +be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_resume (ctrl, CONTTYPE_DM_CRYPT, tuples); + + leave: + return err; +} diff --git a/g13/be-dmcrypt.h b/g13/be-dmcrypt.h index 1521860..d74e09f 100644 --- a/g13/be-dmcrypt.h +++ b/g13/be-dmcrypt.h @@ -27,6 +27,9 @@ gpg_error_t be_dmcrypt_mount_container (ctrl_t ctrl, const char *fname, const char *mountpoint, tupledesc_t tuples); +gpg_error_t be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname); +gpg_error_t be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname, + tupledesc_t tuples); #endif /*G13_BE_DMCRYPT_H*/ diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index 0e69e9c..bc93d20 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -337,6 +337,7 @@ mount_status_cb (void *opaque, const char *line) } +/* Inquire callback for MOUNT and RESUME. */ static gpg_error_t mount_inq_cb (void *opaque, const char *line) { @@ -363,9 +364,11 @@ mount_inq_cb (void *opaque, const char *line) } -/* Run the MOUNT command on the current device. CONTTYPES gives the - requested content type for the new container. MOUNTPOINT the - desired mount point or NULL for default. */ +/* + * Run the MOUNT command on the current device. CONTTYPES gives the + * requested content type for the new container. MOUNTPOINT the + * desired mount point or NULL for default. + */ gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, tupledesc_t tuples) @@ -406,3 +409,80 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, leave: return err; } + + + +/* + * Run the SUSPEND command on the current device. CONTTYPES gives the + * requested content type for the new container. + */ +gpg_error_t +call_syshelp_run_suspend (ctrl_t ctrl, int conttype) +{ + gpg_error_t err; + assuan_context_t ctx; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + if (conttype == CONTTYPE_DM_CRYPT) + { + err = assuan_transact (ctx, "SUSPEND dm-crypt", + NULL, NULL, + NULL, NULL, + NULL, NULL); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} + + + +/* Run the RESUME command on the current device. CONTTYPES gives the + requested content type for the container. */ +gpg_error_t +call_syshelp_run_resume (ctrl_t ctrl, int conttype, tupledesc_t tuples) +{ + gpg_error_t err; + assuan_context_t ctx; + struct mount_parm_s parm; + + memset (&parm, 0, sizeof parm); + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + /* tty_get ("waiting for debugger"); */ + /* tty_kill_prompt (); */ + + parm.ctx = ctx; + parm.ctrl = ctrl; + if (conttype == CONTTYPE_DM_CRYPT) + { + ref_tupledesc (tuples); + parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen); + err = assuan_transact (ctx, "RESUME dm-crypt", + NULL, NULL, + mount_inq_cb, &parm, + NULL, NULL); + unref_tupledesc (tuples); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h index 60cc776..c2578f2 100644 --- a/g13/call-syshelp.h +++ b/g13/call-syshelp.h @@ -28,6 +28,9 @@ gpg_error_t call_syshelp_run_create (ctrl_t ctrl, int conttype); gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, tupledesc_t tuples); +gpg_error_t call_syshelp_run_suspend (ctrl_t ctrl, int conttype); +gpg_error_t call_syshelp_run_resume (ctrl_t ctrl, int conttype, + tupledesc_t tuples); #endif /*GNUPG_G13_CALL_SYSHELP_H*/ diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h index 087fff6..dae2bd0 100644 --- a/g13/g13-syshelp.h +++ b/g13/g13-syshelp.h @@ -86,6 +86,10 @@ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp); gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, tupledesc_t keyblob); +gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname); +gpg_error_t sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname, + tupledesc_t keyblob); + #endif /*G13_SYSHELP_H*/ diff --git a/g13/g13.c b/g13/g13.c index b8a2dda..4489b2f 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -42,6 +42,7 @@ #include "runner.h" #include "create.h" #include "mount.h" +#include "suspend.h" #include "mountinfo.h" #include "backend.h" #include "call-syshelp.h" @@ -58,6 +59,8 @@ enum cmd_and_opt_values { aCreate, aMount, aUmount, + aSuspend, + aResume, aServer, oOptions, @@ -109,6 +112,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aCreate, "create", N_("Create a new file system container")), ARGPARSE_c (aMount, "mount", N_("Mount a file system container") ), ARGPARSE_c (aUmount, "umount", N_("Unmount a file system container") ), + ARGPARSE_c (aSuspend, "suspend", N_("Suspend a file system container") ), + ARGPARSE_c (aResume, "resume", N_("Resume a file system container") ), ARGPARSE_c (aServer, "server", N_("Run in server mode")), ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"), @@ -490,7 +495,8 @@ main ( int argc, char **argv) case aServer: case aMount: case aUmount: - /* nokeysetup = 1; */ + case aSuspend: + case aResume: case aCreate: set_cmd (&cmd, pargs.r_opt); break; @@ -770,6 +776,40 @@ main ( int argc, char **argv) } break; + case aUmount: /* Unmount a mounted container. */ + { + if (argc != 1) + wrong_args ("--umount filename"); + err = GPG_ERR_NOT_IMPLEMENTED; + log_error ("error unmounting container '%s': %s <%s>\n", + *argv, gpg_strerror (err), gpg_strsource (err)); + } + break; + + case aSuspend: /* Suspend a container. */ + { + /* Fixme: Should we add a suspend all container option? */ + if (argc != 1) + wrong_args ("--suspend filename"); + err = g13_suspend_container (&ctrl, argv[0]); + if (err) + log_error ("error suspending container '%s': %s <%s>\n", + *argv, gpg_strerror (err), gpg_strsource (err)); + } + break; + + case aResume: /* Resume a suspended container. */ + { + /* Fixme: Should we add a resume all container option? */ + if (argc != 1) + wrong_args ("--resume filename"); + err = g13_resume_container (&ctrl, argv[0]); + if (err) + log_error ("error resuming container '%s': %s <%s>\n", + *argv, gpg_strerror (err), gpg_strsource (err)); + } + break; + default: log_error (_("invalid command (there is no implicit command)\n")); break; diff --git a/g13/keyblob.c b/g13/keyblob.c new file mode 100644 index 0000000..cad0c4f --- /dev/null +++ b/g13/keyblob.c @@ -0,0 +1,229 @@ +/* keyblob.c - Keyblob parser and builder. + * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2015-2016 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "i18n.h" +#include "mount.h" + +#include "keyblob.h" +#include "../common/sysutils.h" +#include "../common/call-gpg.h" +#include "host2net.h" + + +/* Parse the header prefix and return the length of the entire header. */ +static gpg_error_t +parse_header (const char *filename, + const unsigned char *packet, size_t packetlen, + size_t *r_headerlen) +{ + unsigned int len; + + if (packetlen != 32) + return gpg_error (GPG_ERR_BUG); + + len = buf32_to_uint (packet+2); + if (packet[0] != (0xc0|61) || len < 26 + || memcmp (packet+6, "GnuPG/G13", 10)) + { + log_error ("file '%s' is not valid container\n", filename); + return gpg_error (GPG_ERR_INV_OBJ); + } + if (packet[16] != 1) + { + log_error ("unknown version %u of container '%s'\n", + (unsigned int)packet[16], filename); + return gpg_error (GPG_ERR_INV_OBJ); + } + if (packet[17] || packet[18] + || packet[26] || packet[27] || packet[28] || packet[29] + || packet[30] || packet[31]) + log_info ("WARNING: unknown meta information in '%s'\n", filename); + if (packet[19]) + log_info ("WARNING: OS flag is not supported in '%s'\n", filename); + if (packet[24] > 1 ) + log_info ("Note: meta data copies in '%s' are ignored\n", filename); + + len = buf32_to_uint (packet+20); + + /* Do a basic sanity check on the length. */ + if (len < 32 || len > 1024*1024) + { + log_error ("bad length given in container '%s'\n", filename); + return gpg_error (GPG_ERR_INV_OBJ); + } + + *r_headerlen = len; + return 0; +} + + +/* Read the prefix of the keyblob and do some basic parsing. On + success returns an open estream file at R_FP and the length of the + header at R_HEADERLEN. */ +static gpg_error_t +read_keyblob_prefix (const char *filename, estream_t *r_fp, size_t *r_headerlen) +{ + gpg_error_t err; + estream_t fp; + unsigned char packet[32]; + + *r_fp = NULL; + + fp = es_fopen (filename, "rb"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("error reading '%s': %s\n", filename, gpg_strerror (err)); + return err; + } + + /* Read the header. It is defined as 32 bytes thus we read it in one go. */ + if (es_fread (packet, 32, 1, fp) != 1) + { + err = gpg_error_from_syserror (); + log_error ("error reading the header of '%s': %s\n", + filename, gpg_strerror (err)); + es_fclose (fp); + return err; + } + + err = parse_header (filename, packet, 32, r_headerlen); + if (err) + es_fclose (fp); + else + *r_fp = fp; + + return err; +} + + + +/* + * Test whether the container with name FILENAME is a suitable G13 + * container. This function may even be called on a mounted + * container. + */ +gpg_error_t +g13_is_container (ctrl_t ctrl, const char *filename) +{ + gpg_error_t err; + estream_t fp = NULL; + size_t dummy; + + (void)ctrl; + + /* Read just the prefix of the header. */ + err = read_keyblob_prefix (filename, &fp, &dummy); + if (!err) + es_fclose (fp); + return err; +} + + +/* + * Read the keyblob at FILENAME. The caller should have acquired a + * lockfile and checked that the file exists. + */ +gpg_error_t +g13_keyblob_read (const char *filename, + void **r_enckeyblob, size_t *r_enckeybloblen) +{ + gpg_error_t err; + estream_t fp = NULL; + size_t headerlen = 0; + size_t msglen; + void *msg = NULL; + + *r_enckeyblob = NULL; + *r_enckeybloblen = 0; + + err = read_keyblob_prefix (filename, &fp, &headerlen); + if (err) + goto leave; + + if (opt.verbose) + log_info ("header length of '%s' is %zu\n", filename, headerlen); + + /* Read everything including the padding. We should eventually do a + regular OpenPGP parsing to detect the padding packet and pass + only the actual used OpenPGP data to the engine. This is in + particular required when supporting CMS which will be + encapsulated in an OpenPGP packet. */ + assert (headerlen >= 32); + msglen = headerlen - 32; + if (!msglen) + { + err = gpg_error (GPG_ERR_NO_DATA); + goto leave; + } + msg = xtrymalloc (msglen); + if (!msglen) + { + err = gpg_error_from_syserror (); + goto leave; + } + if (es_fread (msg, msglen, 1, fp) != 1) + { + err = gpg_error_from_syserror (); + log_error ("error reading keyblob of '%s': %s\n", + filename, gpg_strerror (err)); + goto leave; + } + + *r_enckeyblob = msg; + msg = NULL; + *r_enckeybloblen = msglen; + + leave: + xfree (msg); + es_fclose (fp); + + return err; +} + + +/* + * Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result + * at (R_KEYBLOB, R_KEYBLOBLEN). Returns 0 on success or an error + * code. On error R_KEYBLOB is set to NULL. + */ +gpg_error_t +g13_keyblob_decrypt (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen, + void **r_keyblob, size_t *r_keybloblen) +{ + gpg_error_t err; + + /* FIXME: For now we only implement OpenPGP. */ + err = gpg_decrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments, + enckeyblob, enckeybloblen, + r_keyblob, r_keybloblen); + + return err; +} diff --git a/g13/keyblob.h b/g13/keyblob.h index 7540e4b..3415e9a 100644 --- a/g13/keyblob.h +++ b/g13/keyblob.h @@ -152,5 +152,14 @@ possible to prepend a truecrypt container with our keyblob. */ + +/*-- keyblob.c --*/ +gpg_error_t g13_is_container (ctrl_t ctrl, const char *filename); +gpg_error_t g13_keyblob_read (const char *filename, + void **r_enckeyblob, size_t *r_enckeybloblen); +gpg_error_t g13_keyblob_decrypt (ctrl_t ctrl, + const void *enckeyblob, size_t enckeybloblen, + void **r_keyblob, size_t *r_keybloblen); + #endif /*G13_KEYBLOB_H*/ diff --git a/g13/mount.c b/g13/mount.c index c5c8f22..272cd77 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -33,178 +33,10 @@ #include "keyblob.h" #include "backend.h" #include "g13tuple.h" -#include "../common/sysutils.h" -#include "../common/call-gpg.h" #include "mountinfo.h" #include "runner.h" #include "host2net.h" - - -/* Parse the header prefix and return the length of the entire header. */ -static gpg_error_t -parse_header (const char *filename, - const unsigned char *packet, size_t packetlen, - size_t *r_headerlen) -{ - unsigned int len; - - if (packetlen != 32) - return gpg_error (GPG_ERR_BUG); - - len = buf32_to_uint (packet+2); - if (packet[0] != (0xc0|61) || len < 26 - || memcmp (packet+6, "GnuPG/G13", 10)) - { - log_error ("file '%s' is not valid container\n", filename); - return gpg_error (GPG_ERR_INV_OBJ); - } - if (packet[16] != 1) - { - log_error ("unknown version %u of container '%s'\n", - (unsigned int)packet[16], filename); - return gpg_error (GPG_ERR_INV_OBJ); - } - if (packet[17] || packet[18] - || packet[26] || packet[27] || packet[28] || packet[29] - || packet[30] || packet[31]) - log_info ("WARNING: unknown meta information in '%s'\n", filename); - if (packet[19]) - log_info ("WARNING: OS flag is not supported in '%s'\n", filename); - if (packet[24] > 1 ) - log_info ("Note: meta data copies in '%s' are ignored\n", filename); - - len = buf32_to_uint (packet+20); - - /* Do a basic sanity check on the length. */ - if (len < 32 || len > 1024*1024) - { - log_error ("bad length given in container '%s'\n", filename); - return gpg_error (GPG_ERR_INV_OBJ); - } - - *r_headerlen = len; - return 0; -} - - -/* Read the prefix of the keyblob and do some basic parsing. On - success returns an open estream file at R_FP and the length of the - header at R_HEADERLEN. */ -static gpg_error_t -read_keyblob_prefix (const char *filename, estream_t *r_fp, size_t *r_headerlen) -{ - gpg_error_t err; - estream_t fp; - unsigned char packet[32]; - - *r_fp = NULL; - - fp = es_fopen (filename, "rb"); - if (!fp) - { - err = gpg_error_from_syserror (); - log_error ("error reading '%s': %s\n", filename, gpg_strerror (err)); - return err; - } - - /* Read the header. It is defined as 32 bytes thus we read it in one go. */ - if (es_fread (packet, 32, 1, fp) != 1) - { - err = gpg_error_from_syserror (); - log_error ("error reading the header of '%s': %s\n", - filename, gpg_strerror (err)); - es_fclose (fp); - return err; - } - - err = parse_header (filename, packet, 32, r_headerlen); - if (err) - es_fclose (fp); - else - *r_fp = fp; - - return err; -} - - -/* Read the keyblob at FILENAME. The caller should have acquired a - lockfile and checked that the file exists. */ -static gpg_error_t -read_keyblob (const char *filename, - void **r_enckeyblob, size_t *r_enckeybloblen) -{ - gpg_error_t err; - estream_t fp = NULL; - size_t headerlen = 0; - size_t msglen; - void *msg = NULL; - - *r_enckeyblob = NULL; - *r_enckeybloblen = 0; - - err = read_keyblob_prefix (filename, &fp, &headerlen); - if (err) - goto leave; - - if (opt.verbose) - log_info ("header length of '%s' is %zu\n", filename, headerlen); - - /* Read everything including the padding. We should eventually do a - regular OpenPGP parsing to detect the padding packet and pass - only the actual used OpenPGP data to the engine. This is in - particular required when supporting CMS which will be - encapsulated in an OpenPGP packet. */ - assert (headerlen >= 32); - msglen = headerlen - 32; - if (!msglen) - { - err = gpg_error (GPG_ERR_NO_DATA); - goto leave; - } - msg = xtrymalloc (msglen); - if (!msglen) - { - err = gpg_error_from_syserror (); - goto leave; - } - if (es_fread (msg, msglen, 1, fp) != 1) - { - err = gpg_error_from_syserror (); - log_error ("error reading keyblob of '%s': %s\n", - filename, gpg_strerror (err)); - goto leave; - } - - *r_enckeyblob = msg; - msg = NULL; - *r_enckeybloblen = msglen; - - leave: - xfree (msg); - es_fclose (fp); - - return err; -} - - - - -/* Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result at - (R_KEYBLOB, R_KEYBLOBLEN). Returns 0 on success or an error code. - On error R_KEYBLOB is set to NULL. */ -static gpg_error_t -decrypt_keyblob (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen, - void **r_keyblob, size_t *r_keybloblen) -{ - gpg_error_t err; - - /* FIXME: For now we only implement OpenPGP. */ - err = gpg_decrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments, - enckeyblob, enckeybloblen, - r_keyblob, r_keybloblen); - - return err; -} +#include "../common/sysutils.h" /* Mount the container with name FILENAME at MOUNTPOINT. */ @@ -285,13 +117,13 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) /* Read the encrypted keyblob. */ /* Fixme: Should we move this to syshelp for dm-crypt or do we assume that the encrypted device is world readable? */ - err = read_keyblob (filename, &enckeyblob, &enckeybloblen); + err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen); if (err) goto leave; /* Decrypt that keyblob and store it in a tuple descriptor. */ - err = decrypt_keyblob (ctrl, enckeyblob, enckeybloblen, - &keyblob, &keybloblen); + err = g13_keyblob_decrypt (ctrl, enckeyblob, enckeybloblen, + &keyblob, &keybloblen); if (err) goto leave; xfree (enckeyblob); @@ -386,23 +218,3 @@ g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) return 0; } - - -/* Test whether the container with name FILENAME is a suitable G13 - container. This function may even be called on a mounted - container. */ -gpg_error_t -g13_is_container (ctrl_t ctrl, const char *filename) -{ - gpg_error_t err; - estream_t fp = NULL; - size_t dummy; - - (void)ctrl; - - /* Read just the prefix of the header. */ - err = read_keyblob_prefix (filename, &fp, &dummy); - if (!err) - es_fclose (fp); - return err; -} diff --git a/g13/mount.h b/g13/mount.h index b2fe99e..0037682 100644 --- a/g13/mount.h +++ b/g13/mount.h @@ -27,7 +27,5 @@ gpg_error_t g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint); -gpg_error_t g13_is_container (ctrl_t ctrl, const char *filename); - #endif /*G13_MOUNT_H*/ diff --git a/g13/server.c b/g13/server.c index 2f4acf5..60a69bc 100644 --- a/g13/server.c +++ b/g13/server.c @@ -30,8 +30,9 @@ #include "i18n.h" #include "keyblob.h" #include "server.h" -#include "mount.h" #include "create.h" +#include "mount.h" +#include "suspend.h" /* The filepointer for status message used in non-server mode */ @@ -356,6 +357,56 @@ cmd_umount (assuan_context_t ctx, char *line) } +static const char hlp_suspend[] = + "SUSPEND\n" + "\n" + "Suspend the currently set device."; +static gpg_error_t +cmd_suspend (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + line = skip_options (line); + if (*line) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + + /* Perform the suspend operation. */ + err = g13_suspend_container (ctrl, ctrl->server_local->containername); + + leave: + return leave_cmd (ctx, err); +} + + +static const char hlp_resume[] = + "RESUME\n" + "\n" + "Resume the currently set device."; +static gpg_error_t +cmd_resume (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + line = skip_options (line); + if (*line) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + + /* Perform the suspend operation. */ + err = g13_resume_container (ctrl, ctrl->server_local->containername); + + leave: + return leave_cmd (ctx, err); +} + + static const char hlp_recipient[] = "RECIPIENT \n" "\n" @@ -543,6 +594,8 @@ register_commands (assuan_context_t ctx) { "OPEN", cmd_open, hlp_open }, { "MOUNT", cmd_mount, hlp_mount}, { "UMOUNT", cmd_umount, hlp_umount }, + { "SUSPEND", cmd_suspend, hlp_suspend }, + { "RESUME", cmd_resume, hlp_resume }, { "RECIPIENT", cmd_recipient, hlp_recipient }, { "SIGNER", cmd_signer, hlp_signer }, { "CREATE", cmd_create, hlp_create }, diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index 6ba4cd8..fe596f4 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -379,6 +379,121 @@ cmd_mount (assuan_context_t ctx, char *line) } +static const char hlp_suspend[] = + "SUSPEND \n" + "\n" + "Suspend an encrypted partition and wipe the key.\n" + " must be \"dm-crypt\" for now."; +static gpg_error_t +cmd_suspend (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + + line = skip_options (line); + + if (strcmp (line, "dm-crypt")) + { + err = set_error (GPG_ERR_INV_ARG, "Type must be \"dm-crypt\""); + goto leave; + } + + if (!ctrl->server_local->devicename + || !ctrl->server_local->devicefp + || !ctrl->devti) + { + err = set_error (GPG_ERR_ENOENT, "No device has been set"); + goto leave; + } + + err = sh_is_empty_partition (ctrl->server_local->devicename); + if (!err) + { + err = gpg_error (GPG_ERR_ENODEV); + assuan_set_error (ctx, err, "Partition is empty"); + goto leave; + } + err = 0; + + err = sh_dmcrypt_suspend_container (ctrl, ctrl->server_local->devicename); + + leave: + return leave_cmd (ctx, err); +} + + +static const char hlp_resume[] = + "RESUME \n" + "\n" + "Resume an encrypted partition and set the key.\n" + " must be \"dm-crypt\" for now."; +static gpg_error_t +cmd_resume (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + unsigned char *keyblob = NULL; + size_t keybloblen; + tupledesc_t tuples = NULL; + + line = skip_options (line); + + if (strcmp (line, "dm-crypt")) + { + err = set_error (GPG_ERR_INV_ARG, "Type must be \"dm-crypt\""); + goto leave; + } + + if (!ctrl->server_local->devicename + || !ctrl->server_local->devicefp + || !ctrl->devti) + { + err = set_error (GPG_ERR_ENOENT, "No device has been set"); + goto leave; + } + + err = sh_is_empty_partition (ctrl->server_local->devicename); + if (!err) + { + err = gpg_error (GPG_ERR_ENODEV); + assuan_set_error (ctx, err, "Partition is empty"); + goto leave; + } + err = 0; + + /* We expect that the client already decrypted the keyblob. + * Eventually we should move reading of the keyblob to here and ask + * the client to decrypt it. */ + assuan_begin_confidential (ctx); + err = assuan_inquire (ctx, "KEYBLOB", + &keyblob, &keybloblen, 4 * 1024); + assuan_end_confidential (ctx); + if (err) + { + log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err)); + goto leave; + } + err = create_tupledesc (&tuples, keyblob, keybloblen); + if (!err) + keyblob = NULL; + else + { + if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) + log_error ("unknown keyblob version received\n"); + goto leave; + } + + err = sh_dmcrypt_resume_container (ctrl, + ctrl->server_local->devicename, + tuples); + + leave: + xfree (tuples); + destroy_tupledesc (tuples); + return leave_cmd (ctx, err); +} + + static const char hlp_getinfo[] = "GETINFO \n" "\n" @@ -476,6 +591,8 @@ register_commands (assuan_context_t ctx, int fail_all) { "DEVICE", cmd_device, hlp_device }, { "CREATE", cmd_create, hlp_create }, { "MOUNT", cmd_mount, hlp_mount }, + { "SUSPEND", cmd_suspend,hlp_suspend}, + { "RESUME", cmd_resume, hlp_resume }, { "INPUT", NULL }, { "OUTPUT", NULL }, { "GETINFO", cmd_getinfo, hlp_getinfo }, diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index 9510a81..e0cd2e1 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -72,10 +72,13 @@ #endif -/* Check whether the block device DEVNAME is used by device mapper. - Returns: 0 if the device is good and not yet used by DM. */ +/* + * Check whether the block device DEVNAME is used by device mapper. + * If EXPECT_BUSY is set no error message is printed if the device is + * busy. Returns: 0 if the device is good and not yet used by DM. + */ static gpg_error_t -check_blockdev (const char *devname) +check_blockdev (const char *devname, int expect_busy) { gpg_error_t err; struct stat sb; @@ -147,8 +150,10 @@ check_blockdev (const char *devname) if (xmajor == devmajor && xminor == devminor) { - log_error ("device '%s' (%u:%u) already used by device mapper\n", - devname, devmajor, devminor); + if (!expect_busy) + log_error ("device '%s' (%u:%u)" + " already in use by device mapper\n", + devname, devmajor, devminor); err = gpg_error (GPG_ERR_EBUSY); goto leave; } @@ -290,7 +295,7 @@ sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) } /* Check that the device is not used by device mapper. */ - err = check_blockdev (devname); + err = check_blockdev (devname, 0); if (err) goto leave; @@ -525,7 +530,7 @@ sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) } -/* Mount a DM-Crypt congtainer on device DEVNAME taking keys and other +/* Mount a DM-Crypt container on device DEVNAME taking keys and other * meta data from KEYBLOB. */ gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, @@ -549,7 +554,7 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, g13_syshelp_i_know_what_i_am_doing (); /* Check that the device is not yet used by device mapper. */ - err = check_blockdev (devname); + err = check_blockdev (devname, 0); if (err) goto leave; @@ -716,3 +721,223 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, xfree (result); return err; } + + +/* Suspend a DM-Crypt container on device DEVNAME and wipe the keys. */ +gpg_error_t +sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname) +{ + gpg_error_t err; + char *targetname_abs = NULL; + const char *targetname; + char *result = NULL; + + if (!ctrl->devti) + return gpg_error (GPG_ERR_INV_ARG); + + g13_syshelp_i_know_what_i_am_doing (); + + /* Check that the device is used by device mapper. */ + err = check_blockdev (devname, 1); + if (gpg_err_code (err) != GPG_ERR_EBUSY) + { + log_error ("device '%s' is not used by the device mapper: %s\n", + devname, gpg_strerror (err)); + goto leave; + } + + /* Fixme: Check that this is really a g13 partition. */ + + /* Device mapper needs a name for the device: Take it from the label + or use "0". */ + targetname_abs = strconcat ("/dev/mapper/", + "g13-", ctrl->client.uname, "-", + ctrl->devti->label? ctrl->devti->label : "0", + NULL); + if (!targetname_abs) + { + err = gpg_error_from_syserror (); + goto leave; + } + targetname = strrchr (targetname_abs, '/'); + if (!targetname) + BUG (); + targetname++; + + /* Send the suspend command. */ + { + const char *argv[3]; + + argv[0] = "suspend"; + argv[1] = targetname; + argv[2] = NULL; + log_debug ("now running \"dmsetup suspend %s\"\n", targetname); + err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL); + } + if (err) + { + log_error ("error running \"dmsetup suspend %s\": %s\n", + targetname, gpg_strerror (err)); + goto leave; + } + if (result && *result) + log_debug ("dmsetup result: %s\n", result); + xfree (result); + result = NULL; + + /* Send the wipe key command. */ + { + const char *argv[5]; + + argv[0] = "message"; + argv[1] = targetname; + argv[2] = "0"; + argv[3] = "key wipe"; + argv[4] = NULL; + log_debug ("now running \"dmsetup message %s 0 key wipe\"\n", targetname); + err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL); + } + if (err) + { + log_error ("error running \"dmsetup message %s 0 key wipe\": %s\n", + targetname, gpg_strerror (err)); + goto leave; + } + if (result && *result) + log_debug ("dmsetup result: %s\n", result); + xfree (result); + result = NULL; + + + leave: + xfree (targetname_abs); + xfree (result); + return err; +} + + +/* Resume a DM-Crypt container on device DEVNAME taking keys and other + * meta data from KEYBLOB. */ +gpg_error_t +sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname, + tupledesc_t keyblob) +{ + gpg_error_t err; + char *targetname_abs = NULL; + const char *targetname; + char hexkey[8+16*2+1]; /* 8 is used to prepend "key set ". */ + char *table = NULL; + char *result = NULL; + size_t n; + const char *s; + const char *algostr; + size_t algostrlen; + + if (!ctrl->devti) + return gpg_error (GPG_ERR_INV_ARG); + + g13_syshelp_i_know_what_i_am_doing (); + + /* Check that the device is used by device mapper. */ + err = check_blockdev (devname, 1); + if (gpg_err_code (err) != GPG_ERR_EBUSY) + { + log_error ("device '%s' is not used by the device mapper: %s\n", + devname, gpg_strerror (err)); + goto leave; + } + + /* Device mapper needs a name for the device: Take it from the label + or use "0". */ + targetname_abs = strconcat ("/dev/mapper/", + "g13-", ctrl->client.uname, "-", + ctrl->devti->label? ctrl->devti->label : "0", + NULL); + if (!targetname_abs) + { + err = gpg_error_from_syserror (); + goto leave; + } + targetname = strrchr (targetname_abs, '/'); + if (!targetname) + BUG (); + targetname++; + + /* Get the algorithm string. */ + algostr = find_tuple (keyblob, KEYBLOB_TAG_ALGOSTR, &algostrlen); + if (!algostr || algostrlen > 100) + { + log_error ("algo string not found in keyblob or too long\n"); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + + /* Get the key. */ + s = find_tuple (keyblob, KEYBLOB_TAG_ENCKEY, &n); + if (!s || n != 16) + { + if (!s) + log_error ("no key found in keyblob\n"); + else + log_error ("unexpected size of key (%zu)\n", n); + err = gpg_error (GPG_ERR_INV_KEYLEN); + goto leave; + } + strcpy (hexkey, "key set "); + bin2hex (s, 16, hexkey+8); + + /* Send the key */ + { + const char *argv[4]; + + argv[0] = "message"; + argv[1] = targetname; + argv[2] = "0"; + argv[3] = NULL; + log_debug ("now running \"dmsetup message %s 0 [key set]\"\n", targetname); + err = gnupg_exec_tool ("/sbin/dmsetup", argv, hexkey, &result, NULL); + } + wipememory (hexkey, sizeof hexkey); + if (err) + { + log_error ("error running \"dmsetup message %s 0 [key set]\": %s\n", + devname, gpg_strerror (err)); + goto leave; + } + if (result && *result) + log_debug ("dmsetup result: %s\n", result); + xfree (result); + result = NULL; + + /* Send the resume command. */ + { + const char *argv[3]; + + argv[0] = "resume"; + argv[1] = targetname; + argv[2] = NULL; + log_debug ("now running \"dmsetup resume %s\"\n", targetname); + err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL); + } + if (err) + { + log_error ("error running \"dmsetup resume %s\": %s\n", + targetname, gpg_strerror (err)); + goto leave; + } + if (result && *result) + log_debug ("dmsetup result: %s\n", result); + xfree (result); + result = NULL; + + leave: + wipememory (hexkey, sizeof hexkey); + if (table) + { + wipememory (table, strlen (table)); + xfree (table); + } + xfree (targetname_abs); + xfree (result); + return err; +} diff --git a/g13/suspend.c b/g13/suspend.c new file mode 100644 index 0000000..0532c8b --- /dev/null +++ b/g13/suspend.c @@ -0,0 +1,143 @@ +/* suspend.c - Suspend/Resume a crypto container + * Copyright (C) 2016 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "i18n.h" +#include "suspend.h" + +#include "keyblob.h" +#include "backend.h" +#include "g13tuple.h" + + + +/* Suspend the container with name FILENAME. */ +gpg_error_t +g13_suspend_container (ctrl_t ctrl, const char *filename) +{ + gpg_error_t err; + int needs_syshelp; + + /* A quick check to see whether the container exists. */ + if (access (filename, R_OK)) + return gpg_error_from_syserror (); + + /* Decide whether we need to use the g13-syshelp because we can't + use lock files for them. This is most likely the case for device + files; thus we test for this. FIXME: The correct solution would + be to call g13-syshelp to match the file against the g13tab. */ + needs_syshelp = !strncmp (filename, "/dev/", 5); + + if (!needs_syshelp) + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + else + err = be_suspend_container (ctrl, CONTTYPE_DM_CRYPT, filename); + + return err; +} + + +/* Resume the container with name FILENAME. */ +gpg_error_t +g13_resume_container (ctrl_t ctrl, const char *filename) +{ + gpg_error_t err; + int needs_syshelp; + void *enckeyblob = NULL; + size_t enckeybloblen; + void *keyblob = NULL; + size_t keybloblen; + tupledesc_t tuples = NULL; + size_t n; + const unsigned char *value; + int conttype; + char *mountpoint_buffer = NULL; + + /* A quick check to see whether the container exists. */ + if (access (filename, R_OK)) + return gpg_error_from_syserror (); + + /* Decide whether we need to use the g13-syshelp because we can't + use lock files for them. This is most likely the case for device + files; thus we test for this. FIXME: The correct solution would + be to call g13-syshelp to match the file against the g13tab. */ + needs_syshelp = !strncmp (filename, "/dev/", 5); + + if (!needs_syshelp) + { + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto leave; + } + + /* Read the encrypted keyblob. */ + /* Fixme: Should we move this to syshelp for dm-crypt or do we + assume that the encrypted device is world readable? */ + err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen); + if (err) + goto leave; + + /* Decrypt that keyblob and store it in a tuple descriptor. */ + err = g13_keyblob_decrypt (ctrl, enckeyblob, enckeybloblen, + &keyblob, &keybloblen); + if (err) + goto leave; + xfree (enckeyblob); + enckeyblob = NULL; + + err = create_tupledesc (&tuples, keyblob, keybloblen); + if (!err) + keyblob = NULL; + else + { + if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) + log_error ("unknown keyblob version\n"); + goto leave; + } + if (opt.verbose) + dump_tupledesc (tuples); + + value = find_tuple (tuples, KEYBLOB_TAG_CONTTYPE, &n); + if (!value || n != 2) + conttype = 0; + else + conttype = (value[0] << 8 | value[1]); + if (!be_is_supported_conttype (conttype)) + { + log_error ("content type %d is not supported\n", conttype); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto leave; + } + err = be_resume_container (ctrl, conttype, filename, tuples); + + leave: + destroy_tupledesc (tuples); + xfree (keyblob); + xfree (enckeyblob); + xfree (mountpoint_buffer); + return err; +} diff --git a/g13/be-dmcrypt.h b/g13/suspend.h similarity index 58% copy from g13/be-dmcrypt.h copy to g13/suspend.h index 1521860..91702eb 100644 --- a/g13/be-dmcrypt.h +++ b/g13/suspend.h @@ -1,5 +1,5 @@ -/* be-dmcrypt.h - Public defs for the DM-Crypt based backend - * Copyright (C) 2015 Werner Koch +/* suspend.h - Suspend/Resume a crypto container. + * Copyright (C) 2016 Werner Koch * * This file is part of GnuPG. * @@ -17,16 +17,10 @@ * along with this program; if not, see . */ -#ifndef G13_BE_DMCRYPT_H -#define G13_BE_DMCRYPT_H +#ifndef G13_SUSPEND_H +#define G13_SUSPEND_H -#include "backend.h" +gpg_error_t g13_suspend_container (ctrl_t ctrl, const char *filename); +gpg_error_t g13_resume_container (ctrl_t ctrl, const char *filename); -gpg_error_t be_dmcrypt_create_container (ctrl_t ctrl); -gpg_error_t be_dmcrypt_mount_container (ctrl_t ctrl, - const char *fname, - const char *mountpoint, - tupledesc_t tuples); - - -#endif /*G13_BE_DMCRYPT_H*/ +#endif /*G13_SUSPEND_H*/ commit f26867928c451443769fecc41c3283e077e8c49f Author: Werner Koch Date: Mon Feb 22 10:56:27 2016 +0100 g13: Run mount after dmsetup. * g13/g13-syshelp.c (main): Reject userids with a slash. * g13/sh-dmcrypt.c (sh_dmcrypt_mount_container): Run mount if a mountpoint is known. Signed-off-by: Werner Koch diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index b31964e..645730f 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -512,15 +512,23 @@ main ( int argc, char **argv) ctrl.client.uid = (uid_t)myuid; } - pwd = getpwuid (ctrl.client.uid); - if (!pwd || !*pwd->pw_name) - { - log_info ("WARNING: Name for UID not found: %s\n", strerror (errno)); - ctrl.fail_all_cmds = 1; - ctrl.client.uname = xstrdup ("?"); - } - else - ctrl.client.uname = xstrdup (pwd->pw_name); + pwd = getpwuid (ctrl.client.uid); + if (!pwd || !*pwd->pw_name) + { + log_info ("WARNING: Name for UID not found: %s\n", strerror (errno)); + ctrl.fail_all_cmds = 1; + ctrl.client.uname = xstrdup ("?"); + } + else + ctrl.client.uname = xstrdup (pwd->pw_name); + + /* Check that the user name does not contain a directory + separator. */ + if (strchr (ctrl.client.uname, '/')) + { + log_info ("WARNING: Invalid user name passed\n"); + ctrl.fail_all_cmds = 1; + } } #else /*!HAVE_PWD_H || !HAVE_GETPWUID*/ log_info ("WARNING: System does not support required syscalls\n"); diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index e4d67ae..9510a81 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -532,7 +532,8 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, tupledesc_t keyblob) { gpg_error_t err; - char *targetname = NULL; + char *targetname_abs = NULL; + const char *targetname; char hexkey[16*2+1]; char *table = NULL; unsigned long long nblocks, nblocks2; @@ -615,14 +616,19 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, /* Device mapper needs a name for the device: Take it from the label or use "0". */ - targetname = strconcat ("g13-", ctrl->client.uname, "-", - ctrl->devti->label? ctrl->devti->label : "0", - NULL); - if (!targetname) + targetname_abs = strconcat ("/dev/mapper/", + "g13-", ctrl->client.uname, "-", + ctrl->devti->label? ctrl->devti->label : "0", + NULL); + if (!targetname_abs) { err = gpg_error_from_syserror (); goto leave; } + targetname = strrchr (targetname_abs, '/'); + if (!targetname) + BUG (); + targetname++; /* Get the algorithm string. */ algostr = find_tuple (keyblob, KEYBLOB_TAG_ALGOSTR, &algostrlen); @@ -675,6 +681,28 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, } if (result && *result) log_debug ("dmsetup result: %s\n", result); + xfree (result); + result = NULL; + + /* Mount if a mountpoint has been given. */ + if (ctrl->devti->mountpoint) + { + const char *argv[3]; + + argv[0] = targetname_abs; + argv[1] = ctrl->devti->mountpoint; + argv[2] = NULL; + log_debug ("now running \"mount %s %s\"\n", + targetname_abs, ctrl->devti->mountpoint); + err = gnupg_exec_tool ("/bin/mount", argv, NULL, &result, NULL); + if (err) + { + log_error ("error running mount: %s\n", gpg_strerror (err)); + goto leave; + } + if (result && *result) /* (We should not see output to stdout). */ + log_info ("WARNING: mount returned data on stdout! (%s)\n", result); + } leave: @@ -684,7 +712,7 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, wipememory (table, strlen (table)); xfree (table); } - xfree (targetname); + xfree (targetname_abs); xfree (result); return err; } ----------------------------------------------------------------------- Summary of changes: g13/Makefile.am | 3 +- g13/backend.c | 41 ++++++- g13/backend.h | 4 + g13/be-dmcrypt.c | 35 ++++++ g13/be-dmcrypt.h | 3 + g13/call-syshelp.c | 86 +++++++++++++- g13/call-syshelp.h | 3 + g13/g13-syshelp.c | 26 ++-- g13/g13-syshelp.h | 4 + g13/g13.c | 42 ++++++- g13/keyblob.c | 229 ++++++++++++++++++++++++++++++++++++ g13/keyblob.h | 9 ++ g13/mount.c | 196 +----------------------------- g13/mount.h | 2 - g13/server.c | 55 ++++++++- g13/sh-cmd.c | 117 ++++++++++++++++++ g13/sh-dmcrypt.c | 281 +++++++++++++++++++++++++++++++++++++++++--- g13/suspend.c | 143 ++++++++++++++++++++++ g13/{server.h => suspend.h} | 16 ++- 19 files changed, 1061 insertions(+), 234 deletions(-) create mode 100644 g13/keyblob.c create mode 100644 g13/suspend.c copy g13/{server.h => suspend.h} (69%) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 23 21:15:05 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 23 Feb 2016 21:15:05 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-64-gf57a91a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via f57a91afb69c58f9d8d9632801650f28c7dc1e0d (commit) via 33ac735a781325c4d47cdf6216813866ab93562e (commit) via 8066f8a3470f9d2f3682a28641a7b09eca29a105 (commit) via 903466e124841cb29f518afa6b7706d490737ac3 (commit) from f7968db30b0e0ccae038e354568accb0a05d877c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f57a91afb69c58f9d8d9632801650f28c7dc1e0d Author: Neal H. Walfield Date: Tue Feb 23 21:14:21 2016 +0100 common: Add log_assert. * common/logging.h (log_assert): New macro. -- Signed-off-by: Neal H. Walfield diff --git a/common/logging.h b/common/logging.h index c4ae5d0..d0b1597 100644 --- a/common/logging.h +++ b/common/logging.h @@ -81,6 +81,10 @@ void log_logv (int level, const char *fmt, va_list arg_ptr); void log_string (int level, const char *string); +#define log_assert(expr) \ + do \ + if (! (expr)) log_bug ("Assertion " #expr " failed.\n"); \ + while (0) 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); commit 33ac735a781325c4d47cdf6216813866ab93562e Author: Neal H. Walfield Date: Tue Feb 23 21:07:09 2016 +0100 gpg: Use higher-level functions. * g10/build-packet.c (do_symkey_enc): Use iobuf_write instead of iobuf_put in a loop. Use iobuf_copy instead of iobuf_read and iobuf_write in a loop. Move the memory wiping from here... * common/iobuf.c (iobuf_copy): ... to here. -- Signed-off-by: Neal H. Walfield diff --git a/common/iobuf.c b/common/iobuf.c index 1f2cd3f..a0d48c6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2253,6 +2253,9 @@ iobuf_copy (iobuf_t dest, iobuf_t source) break; nwrote += nread; } + + /* Burn the buffer. */ + wipememory (temp, sizeof (temp)); xfree (temp); return nwrote; diff --git a/g10/build-packet.c b/g10/build-packet.c index 4dec5b9..a6d5881 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -528,33 +528,23 @@ calc_plaintext( PKT_plaintext *pt ) static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) { - int i, rc = 0; - u32 n; - byte buf[1000]; /* this buffer has the plaintext! */ - int nbytes; + int rc = 0; + size_t nbytes; write_header(out, ctb, calc_plaintext( pt ) ); iobuf_put(out, pt->mode ); iobuf_put(out, pt->namelen ); - for(i=0; i < pt->namelen; i++ ) - iobuf_put(out, pt->name[i] ); + iobuf_write (out, pt->name, pt->namelen); rc = write_32(out, pt->timestamp ); if (rc) return rc; - n = 0; - while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) { - rc = iobuf_write (out, buf, nbytes); - if (rc) - break; - n += nbytes; - } - wipememory(buf,1000); /* burn the buffer */ + nbytes = iobuf_copy (out, pt->buf); if( (ctb&0x40) && !pt->len ) iobuf_set_partial_body_length_mode(out, 0 ); /* turn off partial */ - if( pt->len && n != pt->len ) + if( pt->len && nbytes != pt->len ) log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n", - (ulong)n, (ulong)pt->len ); + (ulong)nbytes, (ulong)pt->len ); return rc; } commit 8066f8a3470f9d2f3682a28641a7b09eca29a105 Author: Neal H. Walfield Date: Tue Feb 23 21:04:29 2016 +0100 common: Check for an error before reading. * common/iobuf.c (iobuf_copy): If DEST has a pending error, don't start copying. -- Signed-off-by: Neal H. Walfield diff --git a/common/iobuf.c b/common/iobuf.c index 6a9060a..1f2cd3f 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2237,6 +2237,9 @@ iobuf_copy (iobuf_t dest, iobuf_t source) assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP); assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP); + if (iobuf_error (dest)) + return -1; + temp = xmalloc (temp_size); while (1) { commit 903466e124841cb29f518afa6b7706d490737ac3 Author: Neal H. Walfield Date: Tue Feb 23 20:36:07 2016 +0100 common: More accurately name function. * common/iobuf.c (iobuf_set_partial_block_mode): Rename from this... (iobuf_set_partial_body_length_mode): ... to this. Update callers. -- Signed-off-by: Neal H. Walfield diff --git a/common/iobuf.c b/common/iobuf.c index f5bbfb2..6a9060a 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2513,7 +2513,7 @@ iobuf_get_fname_nonnull (iobuf_t a) * LEN is the first length byte on read, but ignored on writes. */ void -iobuf_set_partial_block_mode (iobuf_t a, size_t len) +iobuf_set_partial_body_length_mode (iobuf_t a, size_t len) { block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx); diff --git a/common/iobuf.h b/common/iobuf.h index 8ba02b3..785efdc 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -592,7 +592,7 @@ const char *iobuf_get_fname_nonnull (iobuf_t a); length headers (see Section 4.2.2.4 of RFC 4880). Concretely, it just returns / writes the data and finishes the packet with an EOF. */ -void iobuf_set_partial_block_mode (iobuf_t a, size_t len); +void iobuf_set_partial_body_length_mode (iobuf_t a, size_t len); /* If PARTIAL is set, then read from the pipeline until the first EOF is returned. diff --git a/g10/build-packet.c b/g10/build-packet.c index 4245208..4dec5b9 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -551,7 +551,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) } wipememory(buf,1000); /* burn the buffer */ if( (ctb&0x40) && !pt->len ) - iobuf_set_partial_block_mode(out, 0 ); /* turn off partial */ + iobuf_set_partial_body_length_mode(out, 0 ); /* turn off partial */ if( pt->len && n != pt->len ) log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n", (ulong)n, (ulong)pt->len ); @@ -1334,7 +1334,7 @@ write_new_header( IOBUF out, int ctb, u32 len, int hdrlen ) if( iobuf_put(out, ctb ) ) return -1; if( !len ) { - iobuf_set_partial_block_mode(out, 512 ); + iobuf_set_partial_body_length_mode(out, 512 ); } else { if( len < 192 ) { diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 38cd8c9..1be49b1 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -581,7 +581,7 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos, case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: case PKT_COMPRESSED: - iobuf_set_partial_block_mode (inp, c & 0xff); + iobuf_set_partial_body_length_mode (inp, c & 0xff); pktlen = 0; /* To indicate partial length. */ partial = 1; break; ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 8 +++++++- common/iobuf.h | 2 +- common/logging.h | 4 ++++ g10/build-packet.c | 26 ++++++++------------------ g10/parse-packet.c | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 23 21:36:10 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 23 Feb 2016 21:36:10 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-65-g14d27b2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 14d27b2cadf9b0bb413f2b8bad2d81c1d370c2e7 (commit) from f57a91afb69c58f9d8d9632801650f28c7dc1e0d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 14d27b2cadf9b0bb413f2b8bad2d81c1d370c2e7 Author: Neal H. Walfield Date: Tue Feb 23 21:28:24 2016 +0100 common: Improve a function's documentation and comments. * common/iobuf.c (iobuf_set_partial_body_length_mode): Fix documentation and comment. Add an assert. -- Signed-off-by: Neal H. Walfield diff --git a/common/iobuf.c b/common/iobuf.c index a0d48c6..9816d55 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2515,8 +2515,16 @@ iobuf_get_fname_nonnull (iobuf_t a) /**************** - * enable partial block mode as described in the OpenPGP draft. - * LEN is the first length byte on read, but ignored on writes. + * Enable or disable partial body length mode (RFC 4880 4.2.2.4). + * + * If LEN is 0, this disables partial block mode by popping the + * partial body length filter, which which must be the most recently + * added filter. + * + * If LEN is non-zero, it pushes a partial body length filter. If + * this is a read filter, LEN must be the length byte from the first + * chunk and A should be position just after this first partial body + * length header. */ void iobuf_set_partial_body_length_mode (iobuf_t a, size_t len) @@ -2525,21 +2533,17 @@ iobuf_set_partial_body_length_mode (iobuf_t a, size_t len) ctx->use = a->use; if (!len) + /* Disable partial body length mode. */ { if (a->use == IOBUF_INPUT) log_debug ("pop_filter called in set_partial_block_mode" " - please report\n"); - /* XXX: This pop_filter doesn't make sense. Since we haven't - actually added the filter to the pipeline yet, why are we - popping anything? Moreover, since we don't report an error, - the caller won't directly see an error. I think that it - would be better to push the filter and set a->error to - GPG_ERR_BAD_DATA, but Werner thinks it's impossible for len - to be 0 (but he doesn't want to remove the check just in - case). */ + + log_assert (a->filter == block_filter); pop_filter (a, block_filter, NULL); } else + /* Enabled partial body length mode. */ { ctx->partial = 1; ctx->size = 0; ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Feb 23 22:40:11 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Tue, 23 Feb 2016 22:40:11 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-66-g75861b6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 75861b663bbb37214143c2ff7b1b4d1d10ba2657 (commit) from 14d27b2cadf9b0bb413f2b8bad2d81c1d370c2e7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 75861b663bbb37214143c2ff7b1b4d1d10ba2657 Author: Neal H. Walfield Date: Tue Feb 23 22:39:58 2016 +0100 common: Reduce buffer size. * common/iobuf.c (iobuf_copy): Change buffer size from 1 MB to 32 KB. -- Change suggested by Werner based on the observation that other buffers are of a similar size. Signed-off-by: Neal H. Walfield diff --git a/common/iobuf.c b/common/iobuf.c index 9816d55..bd1c30f 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2227,8 +2227,8 @@ size_t iobuf_copy (iobuf_t dest, iobuf_t source) { char *temp; - /* Use a 1 MB buffer. */ - const size_t temp_size = 1024 * 1024; + /* Use a 32 KB buffer. */ + const size_t temp_size = 32 * 1024; size_t nread; size_t nwrote = 0; ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 24 13:43:04 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 24 Feb 2016 13:43:04 +0100 Subject: [git] GnuPG - branch, justus/scm-7, updated. gnupg-2.1.11-78-gacce61d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/scm-7 has been updated via acce61db3737c52c10c905a268a3a9ed02c8af02 (commit) from 90b70875134621f29d66392eaf14180de795fab0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit acce61db3737c52c10c905a268a3a9ed02c8af02 Author: Justus Winter Date: Wed Feb 24 13:42:43 2016 +0100 tests/gpgscm: Fix make check. diff --git a/tests/gpgscm/Makefile.am b/tests/gpgscm/Makefile.am index abedd36..1fb9647 100644 --- a/tests/gpgscm/Makefile.am +++ b/tests/gpgscm/Makefile.am @@ -53,5 +53,5 @@ $(PROGRAMS): $(common_libs) .PHONY: check check: gpgscm$(EXEEXT) t-child$(EXEEXT) - EXEEXT=$(EXEEXT) ./gpgscm$(EXEEXT) --base $(srcdir) \ - $(srcdir)/t-child.scm + EXEEXT=$(EXEEXT) GPGSCM_PATH=$(srcdir) \ + ./gpgscm$(EXEEXT) $(srcdir)/t-child.scm ----------------------------------------------------------------------- Summary of changes: tests/gpgscm/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 24 13:54:18 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 24 Feb 2016 13:54:18 +0100 Subject: [git] GnuPG - branch, justus/scm-7, updated. gnupg-2.1.11-79-gb922120 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/scm-7 has been updated via b92212032f9b72bef274e336fc3be0335d267a28 (commit) from acce61db3737c52c10c905a268a3a9ed02c8af02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b92212032f9b72bef274e336fc3be0335d267a28 Author: Justus Winter Date: Wed Feb 24 13:53:51 2016 +0100 tests/openpgp: Add missing gpgtar.scm. diff --git a/tests/openpgp/gpgtar.scm b/tests/openpgp/gpgtar.scm new file mode 100755 index 0000000..699fe23 --- /dev/null +++ b/tests/openpgp/gpgtar.scm @@ -0,0 +1,68 @@ +#!/usr/bin/env gpgscm + +(load (with-path "defs.scm")) + +(unless (= 0 (call `(,(tool 'gpgtar) --help))) + (skip "gpgtar not installed")) + +(define testfiles (append plain-files data-files)) +(define gpgargs "--always-trust --no-permission-warning") ;; xxx + +(define (do-test create-flags inspect-flags extract-flags) + (lettmp (archive) + (call-check `(,(tool 'gpgtar) --gpg ,(tool 'gpg) --gpg-args ,gpgargs + , at create-flags + --output ,archive + , at testfiles)) + (tr:do + (tr:pipe-do + (pipe:spawn `(,(tool 'gpgtar) --gpg ,(tool 'gpg) --gpg-args ,gpgargs + --list-archive , at inspect-flags + ,archive))) + (tr:call-with-content + (lambda (c) + (unless (all (lambda (f) (string-contains? c f)) testfiles) + (error "some file(s) are missing from archive"))))) + + (with-temporary-working-directory + (call-check `(,(tool 'gpgtar) --gpg ,(tool 'gpg) --gpg-args ,gpgargs + --tar-args --directory=. + --decrypt + , at extract-flags + ,archive)) + + (for-each + (lambda (f) (unless (call-with-input-file f (lambda (x) #t)) + (error (string-append "missing file: " f)))) + testfiles)))) + +(info "Checking gpgtar without encryption") +(do-test `(--skip-crypto --encrypt) '(--skip-crypto) '(--skip-crypto)) + +(info "Checking gpgtar with asymmetric encryption") +(do-test `(--encrypt --recipient ,usrname2) '() '()) + +(info "Checking gpgtar with asymmetric encryption and signature") +(do-test `(--encrypt --recipient ,usrname2 --sign --local-user ,usrname3) + '() '()) + +(info "Checking gpgtar with signature") +(do-test `(--sign --local-user ,usrname3) '() '()) + +(lettmp (passphrasefile) + (letfd ((fd (open passphrasefile (logior O_WRONLY O_CREAT O_BINARY) #o600))) + (display "streng geheimes hupsipupsi" (fdopen fd "wb"))) + + (let ((ppflags `(--gpg-args ,(string-append "--passphrase-file=" + passphrasefile)))) + (info "Checking gpgtar with symmetric encryption") + (do-test `(, at ppflags --symmetric) ppflags ppflags) + + (info "Checking gpgtar with symmetric encryption and chosen cipher") + (do-test `(, at ppflags --symmetric --gpg-args + ,(string-append "--cipher=" (car all-cipher-algos))) + ppflags ppflags) + + (info "Checking gpgtar with both symmetric and asymmetric encryption") + (do-test `(, at ppflags --symmetric --encrypt --recipient ,usrname2 + --sign --local-user ,usrname3) ppflags ppflags))) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/gpgtar.scm | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 tests/openpgp/gpgtar.scm hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Feb 24 14:48:53 2016 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 24 Feb 2016 14:48:53 +0100 Subject: [git] GnuPG - branch, justus/scm-7, updated. gnupg-2.1.11-80-g007fdfe Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, justus/scm-7 has been updated via 007fdfe0f5a615ce5e9d62b272626c0112b1b1e1 (commit) from b92212032f9b72bef274e336fc3be0335d267a28 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 007fdfe0f5a615ce5e9d62b272626c0112b1b1e1 Author: Justus Winter Date: Wed Feb 24 14:48:46 2016 +0100 tests/openpgp: Fix make check. diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 3437f1e..6f8859d 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -36,7 +36,9 @@ fake_pinentry_SOURCES = fake-pinentry.c TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO= LC_ALL=C \ EXEEXT=$(EXEEXT) \ - PATH=../gpgscm:$(PATH) GPGSCM_PATH=$(top_srcdir)/tests/gpgscm:$(top_srcdir)/tests/openpgp + PATH=../gpgscm:$(PATH) \ + objdir=$(shell readlink -f ../..) \ + GPGSCM_PATH=$(top_srcdir)/tests/gpgscm:$(top_srcdir)/tests/openpgp if SQLITE3 sqlite3_dependent_tests = tofu.test diff --git a/tests/openpgp/setup.scm b/tests/openpgp/setup.scm index ffc9c90..7976a4c 100755 --- a/tests/openpgp/setup.scm +++ b/tests/openpgp/setup.scm @@ -1,6 +1,5 @@ #!/usr/bin/env gpgscm -(echo (getenv "GPGSCM_PATH")) (load (with-path "defs.scm")) (echo "Creating test environment...") @@ -25,10 +24,10 @@ '("gpg.conf" "gpg-agent.conf")) (echo "Starting gpg-agent...") -(call `(,(tool 'gpg-connect-agent) --verbose - ,(string-append "--agent-program=" (tool 'gpg-agent) - "|--debug-quick-random") - /bye)) +(call-check `(,(tool 'gpg-connect-agent) --verbose + ,(string-append "--agent-program=" (tool 'gpg-agent) + "|--debug-quick-random") + /bye)) (for-each-p "Creating sample data files" (lambda (size) ----------------------------------------------------------------------- Summary of changes: tests/openpgp/Makefile.am | 4 +++- tests/openpgp/setup.scm | 9 ++++----- 2 files changed, 7 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 25 04:05:32 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 25 Feb 2016 04:05:32 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-335-gfdfa5bf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via fdfa5bfefdde316688a3c8021bd3528c5273b0f4 (commit) from 2b40a16333fa75f1cee85ab901a5aa9cff845a92 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fdfa5bfefdde316688a3c8021bd3528c5273b0f4 Author: NIIBE Yutaka Date: Thu Feb 25 12:01:10 2016 +0900 mpi: Normalize EXPO for mpi_powm. * mpi/mpi-pow.c (gcry_mpi_powm): Normalize EP. -- Thanks to Dan Fandrich for the report with a reproducible test case. GnuPG-bug-id: 2256 Signed-off-by: NIIBE Yutaka diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 0be153f..a780ebd 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -83,6 +83,7 @@ _gcry_mpi_powm (gcry_mpi_t res, rp = res->d; ep = expo->d; + MPN_NORMALIZE(ep, esize); if (!msize) _gcry_divide_by_zero(); @@ -429,6 +430,9 @@ _gcry_mpi_powm (gcry_mpi_t res, size = 2 * msize; msign = mod->sign; + ep = expo->d; + MPN_NORMALIZE(ep, esize); + if (esize * BITS_PER_MPI_LIMB > 512) W = 5; else if (esize * BITS_PER_MPI_LIMB > 256) @@ -445,7 +449,6 @@ _gcry_mpi_powm (gcry_mpi_t res, bsec = mpi_is_secure(base); rp = res->d; - ep = expo->d; if (!msize) _gcry_divide_by_zero(); ----------------------------------------------------------------------- Summary of changes: mpi/mpi-pow.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 25 15:20:54 2016 From: cvs at cvs.gnupg.org (by Andre Heinecke) Date: Thu, 25 Feb 2016 15:20:54 +0100 Subject: [git] GpgOL - branch, master, updated. gpgol-1.3.0-46-gf716ca6 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG extension for MS Outlook". The branch, master has been updated via f716ca623114844537924825e25e45ca12ad0b1d (commit) from 1097fe9bf5d5d5f7b43f01cbf0cc161ba1706c83 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f716ca623114844537924825e25e45ca12ad0b1d Author: Andre Heinecke Date: Thu Feb 25 15:12:22 2016 +0100 Search for uiserver more agressively This is supposed to work for both gpg4win 2.x and 3.x and the new install layout. * configure.ac (gpg4win-3-reg-keys): Remove option. * src/common.c (default_homedir): Fallback to Gpg4win 2 regkey. (get_gpg4win_dir): New. Search at multiple places. (get_data_dir): Use get_gpg4win_dir. * src/common.h (get_gpg4win_dir): Declare. (GPG4WIN_REGKEY_2, GPG4WIN_REGKEY_3): New for old and ney keys. * src/engine-assuan.c (get_uiserver_name): Rewrite to look for more names. * src/main.c (get_locale_dir): Use get_gpg4win_dir. -- This fixes gpgol for the new install layout where the uiserver executables are installed in the bin subdirectory. diff --git a/configure.ac b/configure.ac index 4e82a41..359505a 100644 --- a/configure.ac +++ b/configure.ac @@ -247,14 +247,6 @@ if test "$mime_send" != "no"; then [Sending Mime messages will be supported.]) fi -AC_ARG_ENABLE(gpg4win-3-reg-keys, - AC_HELP_STRING([--enable-gpg4win-3-reg-keys], [Use the gpg4win-3 style registry keys]), - new_keys=$enableval, new_keys=no) -if test "$new_keys" != "no"; then - AC_DEFINE(NEW_STYLE_REG_KEYS, 1, - [The registry keys of Gpg4win-3 will be used]) -fi - # # Print errors here so that they are visible all # together and the user can acquire them all together. diff --git a/src/common.c b/src/common.c index 2142a80..b7b48b0 100644 --- a/src/common.c +++ b/src/common.c @@ -710,7 +710,11 @@ default_homedir (void) { char *tmp; - tmp = read_w32_registry_string (NULL, GNUPG_REGKEY, "HomeDir"); + tmp = read_w32_registry_string (NULL, GPG4WIN_REGKEY_3, "HomeDir"); + if (!tmp) + { + tmp = read_w32_registry_string (NULL, GPG4WIN_REGKEY_2, "HomeDir"); + } if (tmp && !*tmp) { free (tmp); @@ -736,8 +740,7 @@ get_data_dir (void) char *p; char *dname; - instdir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", GNUPG_REGKEY, - "Install Directory"); + instdir = get_gpg4win_dir(); if (!instdir) return NULL; @@ -1228,3 +1231,32 @@ get_tmp_outfile (wchar_t *name, HANDLE *outHandle) return outName; } + +/** Get the Gpg4win Install directory. + * + * Looks first for the Gpg4win 3.x registry key. Then for the Gpg4win + * 2.x registry key. And checks that the directory can be read. + * + * @returns NULL if no dir could be found. Otherwise a malloced string. + */ +char * +get_gpg4win_dir() +{ + const char *g4win_keys[] = {GPG4WIN_REGKEY_3, + GPG4WIN_REGKEY_2, + NULL}; + const char *key; + for (key = *g4win_keys; *key; key++) + { + char *tmp = read_w32_registry_string (NULL, key, "Install Directory"); + if (!tmp) + { + continue; + } + if (!access(tmp, R_OK)) + { + return tmp; + } + } + return NULL; +} diff --git a/src/common.h b/src/common.h index 4316697..c5c1d68 100644 --- a/src/common.h +++ b/src/common.h @@ -36,19 +36,16 @@ extern "C" { #endif #endif -/* The Registry key used by GnuPg and closley related software. */ -#ifndef NEW_STYLE_REG_KEYS /* Gpg4win 3 changed the key */ -# ifdef WIN64 -# define GNUPG_REGKEY "Software\\Wow6432Node\\GNU\\GnuPG" -# else -# define GNUPG_REGKEY "Software\\GNU\\GnuPG" -# endif -# else -# ifdef WIN64 -# define GNUPG_REGKEY "Software\\Wow6432Node\\Gpg4win" -# else -# define GNUPG_REGKEY "Software\\Gpg4win" -# endif +/* The Registry key used by Gpg4win. */ +#ifdef WIN64 +# define GPG4WIN_REGKEY_2 "Software\\Wow6432Node\\GNU\\GnuPG" +#else +# define GPG4WIN_REGKEY_2 "Software\\GNU\\GnuPG" +#endif +#ifdef WIN64 +# define GPG4WIN_REGKEY_3 "Software\\Wow6432Node\\Gpg4win" +#else +# define GPG4WIN_REGKEY_3 "Software\\Gpg4win" #endif /* Identifiers for the protocol. We use different one than those use by gpgme. FIXME: We might want to define an unknown protocol to @@ -198,6 +195,7 @@ char *utf8_to_wincp (const char *string); const char *default_homedir (void); char *get_data_dir (void); +char *get_gpg4win_dir (void); size_t qp_decode (char *buffer, size_t length, int *r_slbrk); char *qp_encode (const char *input, size_t length, size_t* outlen); diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 988258b..f2e0b09 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -346,58 +346,72 @@ get_uiserver_name (void) { char *name = NULL; char *dir, *uiserver, *p; - int extra_arglen = 0; + int extra_arglen = 9; - dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", GNUPG_REGKEY, - "Install Directory"); - if (dir) + const char * server_names[] = {"bin\\kleopatra.exe", + "kleopatra.exe", + "bin\\gpa.exe", + "gpa.exe", + NULL}; + const char *tmp = NULL; + + dir = get_gpg4win_dir (); + if (!dir) + { + log_error ("Failed to find gpg4win dir"); + return NULL; + } + uiserver = read_w32_registry_string (NULL, GPG4WIN_REGKEY_3, + "UI Server"); + if (!uiserver) { - uiserver = read_w32_registry_string (NULL, GNUPG_REGKEY, + uiserver = read_w32_registry_string (NULL, GPG4WIN_REGKEY_2, "UI Server"); - if (!uiserver) - { - uiserver = xstrdup ("kleopatra.exe"); - extra_arglen = 9; /* Space required for " --daemon". */ - } - + } + if (uiserver) + { name = xmalloc (strlen (dir) + strlen (uiserver) + extra_arglen + 2); strcpy (stpcpy (stpcpy (name, dir), "\\"), uiserver); for (p = name; *p; p++) if (*p == '/') *p = '\\'; xfree (uiserver); - if (extra_arglen && access (name, F_OK)) + } + if (name && !access (name, F_OK)) + { + /* Set through registry and is accessible */ + xfree(dir); + return name; + } + /* Fallbacks */ + for (tmp = *server_names; *tmp; tmp++) + { + if (name) { - /* Kleopatra is not installed: Try GPA instead but if it is - also not available return the Kleopatra filename. */ - const char gpaserver[] = "gpa.exe"; - char *name2; - - name2 = xmalloc (strlen (dir) + strlen (gpaserver) + extra_arglen+2); - strcpy (stpcpy (stpcpy (name2, dir), "\\"), gpaserver); - for (p = name2; *p; p++) - if (*p == '/') - *p = '\\'; - if (access (name2, F_OK )) - xfree (name2); - else + xfree (name); + } + name = xmalloc (strlen (dir) + strlen (tmp) + extra_arglen + 2); + strcpy (stpcpy (stpcpy (name, dir), "\\"), tmp); + for (p = name; *p; p++) + if (*p == '/') + *p = '\\'; + if (!access (name, F_OK)) + { + /* Found a viable candidate */ + if (strstr (name, "kleopatra.exe")) { - xfree (name); - name = name2; + strcat (name, " --daemon"); } + xfree (dir); + return name; } - xfree (dir); - - /* Append the arg for Kleopatra. */ - if (name && extra_arglen) - strcat (name, " --daemon"); } - - return name; + xfree (dir); + log_error ("Failed to find a viable UIServer"); + return NULL; } - static gpg_error_t send_one_option (assuan_context_t ctx, const char *name, const char *value) { diff --git a/src/main.c b/src/main.c index 147bf0d..b30a68e 100644 --- a/src/main.c +++ b/src/main.c @@ -500,8 +500,7 @@ get_locale_dir (void) char *p; char *dname; - instdir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", GNUPG_REGKEY, - "Install Directory"); + instdir = get_gpg4win_dir(); if (!instdir) return NULL; ----------------------------------------------------------------------- Summary of changes: configure.ac | 8 ----- src/common.c | 38 ++++++++++++++++++++++-- src/common.h | 24 +++++++-------- src/engine-assuan.c | 84 +++++++++++++++++++++++++++++++---------------------- src/main.c | 3 +- 5 files changed, 96 insertions(+), 61 deletions(-) hooks/post-receive -- GnuPG extension for MS Outlook http://git.gnupg.org From cvs at cvs.gnupg.org Thu Feb 25 21:28:32 2016 From: cvs at cvs.gnupg.org (by Neal H. Walfield) Date: Thu, 25 Feb 2016 21:28:32 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.11-72-g87515e3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 87515e39295e4b7eaec1641c38e1ac32e8d39a91 (commit) via 960f5e26f2cda3ac6e6b30548fa808a690c39ffc (commit) via 105a5629c7e938ec7b3c9c338ebe7bdfee4cfdad (commit) via b7b4a1bdd9da28827980c64c623bcb0654736828 (commit) via c9636a1acc952eb8e1355089bc2e229dece98165 (commit) via 512bc72e1f8544341529174142273d857f45540c (commit) from 75861b663bbb37214143c2ff7b1b4d1d10ba2657 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 87515e39295e4b7eaec1641c38e1ac32e8d39a91 Author: Neal H. Walfield Date: Thu Feb 25 21:22:55 2016 +0100 gpg: Show debugging info if a sig with an unsupported sig class is used. * g10/sig-check.c (check_key_signature2): If SIG->CLASS is unsupported, show some debugging information. Don't use BUG to fail. Just return GPG_ERR_BAD_SIGNATURE. -- Signed-off-by: Neal H. Walfield diff --git a/g10/sig-check.c b/g10/sig-check.c index 4530a64..087222a 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -1086,7 +1086,12 @@ check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, } } else - BUG (); + { + log_info ("sig issued by %s with class %d (digest: %x %x) is not valid over a user id or a key id, ignoring.\n", + keystr (sig->keyid), sig->sig_class, + sig->digest_start[0], sig->digest_start[1]); + rc = gpg_error (GPG_ERR_BAD_SIGNATURE); + } cache_sig_result (sig, rc); commit 960f5e26f2cda3ac6e6b30548fa808a690c39ffc Author: Neal H. Walfield Date: Thu Feb 25 21:20:32 2016 +0100 gpg: More carefully encode a packet's length. * g10/build-packet.c (write_header2): Make sure the length bits are cleared. Fail if HDRLEN is set and the specified length can't be encoded in the available space. -- Signed-off-by: Neal H. Walfield diff --git a/g10/build-packet.c b/g10/build-packet.c index fe6234f..feb7b44 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1450,6 +1450,10 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) /* An old format packet. Refer to RFC 4880, Section 4.2.1 to understand how lengths are encoded in this case. */ + /* The length encoding is stored in the two least significant bits. + Make sure they are cleared. */ + log_assert ((ctb & 3) == 0); + log_assert (hdrlen == 0 || hdrlen == 2 || hdrlen == 3 || hdrlen == 5); if (hdrlen) @@ -1462,10 +1466,13 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) /* 01 => 2 byte length. If len < 256, this is not the most compact encoding, but it is a correct encoding. */ ctb |= 1; - else + else if (hdrlen == 5) /* 10 => 4 byte length. If len < 65536, this is not the most compact encoding, but it is a correct encoding. */ ctb |= 2; + else + log_bug ("Can't encode length=%d in a %d byte header!\n", + len, hdrlen); } else { commit 105a5629c7e938ec7b3c9c338ebe7bdfee4cfdad Author: Neal H. Walfield Date: Thu Feb 25 21:16:41 2016 +0100 gpg: Avoid directly twiddling bits. * g10/build-packet.c (do_plaintext): Use ctb_new_format_p to check the packet's format. (write_header2): Likewise. -- Signed-off-by: Neal H. Walfield diff --git a/g10/build-packet.c b/g10/build-packet.c index 5bcfae1..fe6234f 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -638,8 +638,9 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) return rc; nbytes = iobuf_copy (out, pt->buf); - if( (ctb&0x40) && !pt->len ) - iobuf_set_partial_body_length_mode(out, 0 ); /* turn off partial */ + if(ctb_new_format_p (ctb) && !pt->len) + /* Turn off partial body length mode. */ + iobuf_set_partial_body_length_mode (out, 0); if( pt->len && nbytes != pt->len ) log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n", (ulong)nbytes, (ulong)pt->len ); @@ -1443,7 +1444,7 @@ write_sign_packet_header (IOBUF out, int ctb, u32 len) static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) { - if( ctb & 0x40 ) + if (ctb_new_format_p (ctb)) return write_new_header( out, ctb, len, hdrlen ); /* An old format packet. Refer to RFC 4880, Section 4.2.1 to commit b7b4a1bdd9da28827980c64c623bcb0654736828 Author: Neal H. Walfield Date: Thu Feb 25 21:08:56 2016 +0100 gpg: Improve documentation and comments related to OpenPGP packets. -- Signed-off-by: Neal H. Walfield diff --git a/g10/build-packet.c b/g10/build-packet.c index a257e69..5bcfae1 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -310,6 +310,11 @@ write_fake_data (IOBUF out, gcry_mpi_t a) } +/* Serialize the user id (RFC 4880, Section 5.11) or the user + attribute UID (Section 5.12) and write it to OUT. + + CTB is the serialization's CTB. It specifies the header format and + the packet's type. The header length must not be set. */ static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid ) { @@ -332,12 +337,31 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid ) } +/* Serialize the key (RFC 4880, Section 5.5) described by PK and write + it to OUT. + + This function serializes both primary keys and subkeys with or + without a secret part. + + CTB is the serialization's CTB. It specifies the header format and + the packet's type. The header length must not be set. + + PK->VERSION specifies the serialization format. A value of 0 means + to use the default version. Currently, only version 4 packets are + supported. + */ static int do_key (iobuf_t out, int ctb, PKT_public_key *pk) { gpg_error_t err = 0; + /* The length of the body is stored in the packet's header, which + occurs before the body. Unfortunately, we don't know the length + of the packet's body until we've written all of the data! To + work around this, we first write the data into this temporary + buffer, then generate the header, and finally copy the contents + of this buffer to OUT. */ + iobuf_t a = iobuf_temp(); int i, nskey, npkey; - iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer. */ log_assert (pk->version == 0 || pk->version == 4); log_assert (ctb_pkttype (ctb) == PKT_PUBLIC_KEY @@ -355,7 +379,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) iobuf_put (a, pk->pubkey_algo ); /* Get number of secret and public parameters. They are held in one - array first the public ones, then the secret ones. */ + array: the public ones followed by the secret ones. */ nskey = pubkey_get_nskey (pk->pubkey_algo); npkey = pubkey_get_npkey (pk->pubkey_algo); @@ -463,7 +487,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) writing all the other stuff, so that we know the length of the packet */ write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes); - /* And finally write it out to the real stream. */ + /* And finally write it out to the real stream. */ err = iobuf_write_temp (out, a); } @@ -471,6 +495,11 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) return err; } +/* Serialize the symmetric-key encrypted session key packet (RFC 4880, + 5.3) described by ENC and write it to OUT. + + CTB is the serialization's CTB. It specifies the header format and + the packet's type. The header length must not be set. */ static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) { @@ -479,10 +508,23 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) log_assert (ctb_pkttype (ctb) == PKT_SYMKEY_ENC); + /* The only acceptable version. */ assert( enc->version == 4 ); - switch( enc->s2k.mode ) { - case 0: case 1: case 3: break; - default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode ); + + /* RFC 4880, Section 3.7. */ + switch( enc->s2k.mode ) + { + /* Simple S2K. */ + case 0: + /* Salted S2K. */ + case 1: + /* Iterated and salted S2K. */ + case 3: + /* Reasonable values. */ + break; + + default: + log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode ); } iobuf_put( a, enc->version ); iobuf_put( a, enc->cipher_algo ); @@ -504,6 +546,11 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) } +/* Serialize the public-key encrypted session key packet (RFC 4880, + 5.1) described by ENC and write it to OUT. + + CTB is the serialization's CTB. It specifies the header format and + the packet's type. The header length must not be set. */ static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) { @@ -548,6 +595,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) } +/* Calculate the length of the serialized plaintext packet PT (RFC + 4480, Section 5.9). */ static u32 calc_plaintext( PKT_plaintext *pt ) { @@ -561,6 +610,15 @@ calc_plaintext( PKT_plaintext *pt ) return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0; } +/* Serialize the plaintext packet (RFC 4880, 5.9) described by PT and + write it to OUT. + + The body of the message is stored in PT->BUF. The amount of data + to write is PT->LEN. (PT->BUF should be configured to return EOF + after this much data has been read.) If PT->LEN is 0 and CTB + indicates that this is a new format packet, then partial block mode + is assumed to have been enabled on OUT. On success, partial block + mode is disabled. */ static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) { @@ -591,6 +649,13 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) +/* Serialize the symmetrically encrypted data packet (RFC 4880, + Section 5.7) described by ED and write it to OUT. + + Note: this only writes the packets header! The call must then + follow up and write the initial random data and the body to OUT. + (If you use the encryption iobuf filter (cipher_filter), then this + is done automatically.) */ static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ) { @@ -608,6 +673,14 @@ do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ) return rc; } +/* Serialize the symmetrically encrypted integrity protected data + packet (RFC 4880, Section 5.13) described by ED and write it to + OUT. + + Note: this only writes the packet's header! The caller must then + follow up and write the initial random data, the body and the MDC + packet to OUT. (If you use the encryption iobuf filter + (cipher_filter), then this is done automatically.) */ static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ) { @@ -628,6 +701,11 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ) } +/* Serialize the compressed packet (RFC 4880, Section 5.6) described + by CD and write it to OUT. + + Note: this only writes the packet's header! The caller must then + follow up and write the body to OUT. */ static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd ) { @@ -983,6 +1061,15 @@ build_attribute_subpkt(PKT_user_id *uid,byte type, uid->attrib_len+=idx+headerlen+buflen; } +/* Turn the notation described by the string STRING into a notation. + + STRING has the form: + + - -name - Delete the notation. + - name at domain.name=value - Normal notation + - !name at domain.name=value - Notation with critical bit set. + + The caller must free the result using free_notation(). */ struct notation * string_to_notation(const char *string,int is_utf8) { @@ -1073,6 +1160,8 @@ string_to_notation(const char *string,int is_utf8) return NULL; } +/* Return all of the notations stored in the signature SIG. The + caller must free them using free_notation(). */ struct notation * sig_to_notation(PKT_signature *sig) { @@ -1081,6 +1170,15 @@ sig_to_notation(PKT_signature *sig) int seq=0,crit; struct notation *list=NULL; + /* See RFC 4880, 5.2.3.16 for the format of notation data. In + short, a notation has: + + - 4 bytes of flags + - 2 byte name length (n1) + - 2 byte value length (n2) + - n1 bytes of name data + - n2 bytes of value data + */ while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit))) { int n1,n2; @@ -1092,7 +1190,9 @@ sig_to_notation(PKT_signature *sig) continue; } + /* name length. */ n1=(p[4]<<8)|p[5]; + /* value length. */ n2=(p[6]<<8)|p[7]; if(8+n1+n2!=len) @@ -1108,12 +1208,14 @@ sig_to_notation(PKT_signature *sig) n->name[n1]='\0'; if(p[0]&0x80) + /* The value is human-readable. */ { n->value=xmalloc(n2+1); memcpy(n->value,&p[8+n1],n2); n->value[n2]='\0'; } else + /* Binary data. */ { n->bdat=xmalloc(n2); n->blen=n2; @@ -1134,6 +1236,9 @@ sig_to_notation(PKT_signature *sig) return list; } +/* Release the resources associated with the *list* of notations. To + release a single notation, make sure that notation->next is + NULL. */ void free_notation(struct notation *notation) { @@ -1150,6 +1255,8 @@ free_notation(struct notation *notation) } } +/* Serialize the signature packet (RFC 4880, Section 5.2) described by + SIG and write it to OUT. */ static int do_signature( IOBUF out, int ctb, PKT_signature *sig ) { @@ -1217,6 +1324,8 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) } +/* Serialize the one-pass signature packet (RFC 4880, Section 5.4) + described by OPS and write it to OUT. */ static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ) { @@ -1236,6 +1345,7 @@ do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ) } +/* Write a 16-bit quantity to OUT in big endian order. */ static int write_16(IOBUF out, u16 a) { @@ -1245,6 +1355,7 @@ write_16(IOBUF out, u16 a) return 0; } +/* Write a 32-bit quantity to OUT in big endian order. */ static int write_32(IOBUF out, u32 a) { @@ -1308,11 +1419,26 @@ write_sign_packet_header (IOBUF out, int ctb, u32 len) } /**************** - * If HDRLEN is > 0, try to build a header of this length. We need - * this so that we can hash packets without reading them again. If - * len is 0, write a partial or indeterminate length header, unless - * hdrlen is specified in which case write an actual zero length - * (using the specified hdrlen). + * Write a packet header to OUT. + * + * CTB is the ctb. It determines whether a new or old format packet + * header should be written. The length field is adjusted, but the + * CTB is otherwise written out as is. + * + * LEN is the length of the packet's body. + * + * If HDRLEN is set, then we don't necessarily use the most efficient + * encoding to store LEN, but the specified length. (If this is not + * possible, this is a bug.) In this case, LEN=0 means a 0 length + * packet. Note: setting HDRLEN is only supported for old format + * packets! + * + * If HDRLEN is not set, then the shortest encoding is used. In this + * case, LEN=0 means the body has an indeterminate length and a + * partial body length header (if a new format packet) or an + * indeterminate length header (if an old format packet) is written + * out. Further, if using partial body lengths, this enables partial + * body length mode on OUT. */ static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) @@ -1320,26 +1446,39 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) if( ctb & 0x40 ) return write_new_header( out, ctb, len, hdrlen ); + /* An old format packet. Refer to RFC 4880, Section 4.2.1 to + understand how lengths are encoded in this case. */ + log_assert (hdrlen == 0 || hdrlen == 2 || hdrlen == 3 || hdrlen == 5); - if( hdrlen ) + if (hdrlen) + /* Header length is given. */ { if( hdrlen == 2 && len < 256 ) + /* 00 => 1 byte length. */ ; else if( hdrlen == 3 && len < 65536 ) + /* 01 => 2 byte length. If len < 256, this is not the most + compact encoding, but it is a correct encoding. */ ctb |= 1; else + /* 10 => 4 byte length. If len < 65536, this is not the most + compact encoding, but it is a correct encoding. */ ctb |= 2; } else { if( !len ) + /* 11 => Indeterminate length. */ ctb |= 3; else if( len < 256 ) + /* 00 => 1 byte length. */ ; else if( len < 65536 ) + /* 01 => 2 byte length. */ ctb |= 1; else + /* 10 => 4 byte length. */ ctb |= 2; } @@ -1368,6 +1507,20 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) } +/* Write a new format header to OUT. + + CTB is the ctb. + + LEN is the length of the packet's body. If LEN is 0, then enables + partial body length mode (i.e., the body is of an indeterminant + length) on OUT. Note: this function cannot be used to generate a + header for a zero length packet. + + HDRLEN is the length of the packet's header. If HDRLEN is 0, the + shortest encoding is chosen based on the length of the packet's + body. Currently, values other than 0 are not supported. + + Returns 0 on success. */ static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen ) { diff --git a/g10/packet.h b/g10/packet.h index dfd3a00..1be9ec3 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -79,49 +79,91 @@ typedef struct { byte value; } prefitem_t; +/* A string-to-key specifier as defined in RFC 4880, Section 3.7. */ typedef struct { int mode; /* Must be an integer due to the GNU modes 1001 et al. */ byte hash_algo; byte salt[8]; + /* The *coded* (i.e., the serialized version) iteration count. */ u32 count; } STRING2KEY; +/* A symmetric-key encrypted session key packet as defined in RFC + 4880, Section 5.3. All fields are serialized. */ typedef struct { - byte version; - byte cipher_algo; /* cipher algorithm used */ - STRING2KEY s2k; - byte seskeylen; /* keylength in byte or 0 for no seskey */ - byte seskey[1]; + /* RFC 4880: this must be 4. */ + byte version; + /* The cipher algorithm used. */ + byte cipher_algo; + /* The string-to-key specifier. */ + STRING2KEY s2k; + /* The length of SESKEY in bytes or 0 if this packet does not + encrypt a session key. (In the latter case, the results of the + S2K function on the password is the session key. See RFC 4880, + Section 5.3.) */ + byte seskeylen; + /* The session key as encrypted by the S2K specifier. */ + byte seskey[1]; } PKT_symkey_enc; +/* A public-key encrypted session key packet as defined in RFC 4880, + Section 5.1. All fields are serialized. */ typedef struct { - u32 keyid[2]; /* 64 bit keyid */ - byte version; - byte pubkey_algo; /* algorithm used for public key scheme */ - byte throw_keyid; - gcry_mpi_t data[PUBKEY_MAX_NENC]; + /* The 64-bit keyid. */ + u32 keyid[2]; + /* The packet's version. Currently, only version 3 is defined. */ + byte version; + /* The algorithm used for the public key encryption scheme. */ + byte pubkey_algo; + /* Whether to hide the key id. This value is not directly + serialized. */ + byte throw_keyid; + /* The session key. */ + gcry_mpi_t data[PUBKEY_MAX_NENC]; } PKT_pubkey_enc; +/* A one-pass signature packet as defined in RFC 4880, Section + 5.4. All fields are serialized. */ typedef struct { - u32 keyid[2]; /* 64 bit keyid */ - byte sig_class; /* sig classification */ + u32 keyid[2]; /* The 64-bit keyid */ + /* The signature's classification (RFC 4880, Section 5.2.1). */ + byte sig_class; byte digest_algo; /* algorithm used for digest */ byte pubkey_algo; /* algorithm used for public key scheme */ - byte last; /* a stupid flag */ + /* A message can be signed by multiple keys. In this case, there + are n one-pass signature packets before the message to sign and + n signatures packets after the message. It is conceivable that + someone wants to not only sign the message, but all of the + signatures. Now we need to distinguish between signing the + message and signing the message plus the surrounding + signatures. This is the point of this flag. If set, it means: + I sign all of the data starting at the next packet. */ + byte last; } PKT_onepass_sig; +/* A v4 OpenPGP signature has a hashed and unhashed area containing + co-called signature subpackets (RFC 4880, Section 5.2.3). These + areas are described by this data structure. Use enum_sig_subpkt to + parse this area. */ typedef struct { size_t size; /* allocated */ - size_t len; /* used */ - byte data[1]; + size_t len; /* used (serialized) */ + byte data[1]; /* the serialized subpackes (serialized) */ } subpktarea_t; +/* The in-memory representation of a designated revoker signature + subpacket (RFC 4880, Section 5.2.3.15). */ struct revocation_key { + /* A bit field. 0x80 must be set. 0x40 means this information is + sensitive (and should not be uploaded to a keyserver by + default). */ byte class; + /* The public-key algorithm ID. */ byte algid; + /* The fingerprint of the authorized key. */ byte fpr[MAX_FINGERPRINT_LEN]; }; @@ -139,7 +181,11 @@ typedef struct } pka_info_t; -/* Object to keep information pertaining to a signature. */ +/* A signature packet (RFC 4880, Section 5.2). Only a subset of these + fields are directly serialized (these are marked as such); the rest + are read from the subpackets, which are not synthesized when + serializing this data structure (i.e., when using build_packet()). + Instead, the subpackets must be created by hand. */ typedef struct { struct @@ -156,14 +202,26 @@ typedef struct unsigned expired:1; unsigned pka_tried:1; /* Set if we tried to retrieve the PKA record. */ } flags; - u32 keyid[2]; /* 64 bit keyid */ - u32 timestamp; /* Signature made (seconds since Epoch). */ + /* The key that allegedly generated this signature. (Directly + serialized in v3 sigs; for v4 sigs, this must be explicitly added + as an issuer subpacket (5.2.3.5.) */ + u32 keyid[2]; + /* When the signature was made (seconds since the Epoch). (Directly + serialized in v3 sigs; for v4 sigs, this must be explicitly added + as a signature creation time subpacket (5.2.3.4).) */ + u32 timestamp; u32 expiredate; /* Expires at this date or 0 if not at all. */ + /* The serialization format used / to use. If 0, then defaults to + version 3. (Serialized.) */ byte version; - byte sig_class; /* Sig classification, append for MD calculation. */ - byte pubkey_algo; /* Algorithm used for public key scheme */ - /* (PUBKEY_ALGO_xxx) */ - byte digest_algo; /* Algorithm used for digest (DIGEST_ALGO_xxxx). */ + /* The signature type. (See RFC 4880, Section 5.2.1.) */ + byte sig_class; + /* Algorithm used for public key scheme (e.g., PUBKEY_ALGO_RSA). + (Serialized.) */ + byte pubkey_algo; + /* Algorithm used for digest (e.g., DIGEST_ALGO_SHA1). + (Serialized.) */ + byte digest_algo; byte trust_depth; byte trust_value; const byte *trust_regexp; @@ -173,7 +231,10 @@ typedef struct available. See also flags.pka_tried. */ subpktarea_t *hashed; /* All subpackets with hashed data (v4 only). */ subpktarea_t *unhashed; /* Ditto for unhashed data. */ - byte digest_start[2]; /* First 2 bytes of the digest. */ + /* First 2 bytes of the digest. (Serialized. Note: this is not + automatically filled in when serializing a signature!) */ + byte digest_start[2]; + /* The signature. (Serialized.) */ gcry_mpi_t data[PUBKEY_MAX_NSIG]; /* The message digest and its length (in bytes). Note the maximum digest length is 512 bits (64 bytes). If DIGEST_LEN is 0, then @@ -192,14 +253,21 @@ struct user_attribute { }; -/* (See also keybox-search-desc.h) */ -struct gpg_pkt_user_id_s +/* A user id (RFC 4880, Section 5.11) or a user attribute packet (RFC + 4880, Section 5.12). Only a subset of these fields are directly + serialized (these are marked as such); the rest are read from the + self-signatures in merge_keys_and_selfsig()). */ +typedef struct { int ref; /* reference counter */ - int len; /* length of the name */ + /* The length of NAME. */ + int len; struct user_attribute *attribs; int numattribs; - byte *attrib_data; /* if this is not NULL, the packet is an attribute */ + /* If this is not NULL, the packet is a user attribute rather than a + user id. (Serialized.) */ + byte *attrib_data; + /* The length of ATTRIB_DATA. */ unsigned long attrib_len; byte *namehash; int help_key_usage; @@ -220,9 +288,11 @@ struct gpg_pkt_user_id_s unsigned int ks_modify:1; unsigned int compacted:1; } flags; + /* The text contained in the user id packet, which is normally the + name and email address of the key holder (See RFC 4880 5.11). + (Serialized.) */ char name[1]; -}; -typedef struct gpg_pkt_user_id_s PKT_user_id; +} PKT_user_id; @@ -254,6 +324,14 @@ struct seckey_info /**************** + * The in-memory representation of a public key (RFC 4880, Section + * 5.5). Note: this structure contains significantly more information + * thatn is contained in an OpenPGP public key packet. This + * information is derived from the self-signed signatures (by + * merge_keys_and_selfsig()) and is ignored when serializing the + * packet. The fields that are actually written out when serializing + * this packet are marked as accordingly. + * * We assume that secret keys have the same number of parameters as * the public key and that the public parameters are the first items * in the PKEY array. Thus NPKEY is always less than NSKEY and it is @@ -268,14 +346,22 @@ struct seckey_info */ typedef struct { - u32 timestamp; /* key made */ + /* When the key was created. (Serialized.) */ + u32 timestamp; u32 expiredate; /* expires at this date or 0 if not at all */ u32 max_expiredate; /* must not expire past this date */ struct revoke_info revoked; - byte hdrbytes; /* number of header bytes */ + /* An OpenPGP packet consists of a header and a body. This is the + size of the header. If this is 0, an appropriate size is + automatically chosen based on the size of the body. + (Serialized.) */ + byte hdrbytes; + /* The serialization format. If 0, the default version (4) is used + when serializing. (Serialized.) */ byte version; byte selfsigversion; /* highest version of all of the self-sigs */ - byte pubkey_algo; /* algorithm used for public key scheme */ + /* The public key algorithm. (Serialized.) */ + byte pubkey_algo; byte pubkey_usage; /* for now only used to pass it to getkey() */ byte req_usage; /* hack to pass a request to getkey() */ u32 has_expired; /* set to the expiration date if expired */ @@ -314,9 +400,13 @@ typedef struct char *serialno; /* Malloced hex string or NULL if it is likely not on a card. See also flags.serialno_valid. */ - struct seckey_info *seckey_info; /* If not NULL this malloced - structure describes a secret - key. */ + /* If not NULL this malloced structure describes a secret key. + (Serialized.) */ + struct seckey_info *seckey_info; + /* The public key. Contains pubkey_get_npkey (pubkey_algo) + + pubkey_get_nskey (pubkey_algo) MPIs. (If pubkey_get_npkey + returns 0, then the algorithm is not understood and the PKEY + contains a single opaque MPI.) (Serialized.) */ gcry_mpi_t pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements. */ } PKT_public_key; @@ -332,20 +422,46 @@ typedef struct { char data[1]; } PKT_comment; +/* A compression packet (RFC 4880, Section 5.6). */ typedef struct { - u32 len; /* reserved */ - byte new_ctb; - byte algorithm; - iobuf_t buf; /* IOBUF reference */ + /* Not used. */ + u32 len; + /* Whether the serialized version of the packet used / should use + the new format. */ + byte new_ctb; + /* The compression algorithm. */ + byte algorithm; + /* An iobuf holding the data to be decompressed. (This is not used + for compression!) */ + iobuf_t buf; } PKT_compressed; +/* A symmetrically encrypted data packet (RFC 4880, Section 5.7) or a + symmetrically encrypted integrity protected data packet (Section + 5.13) */ typedef struct { - u32 len; /* Remaining length of encrypted data. */ - int extralen; /* This is (blocksize+2). Used by build_packet. */ - byte new_ctb; /* uses a new CTB */ - byte is_partial; /* partial length encoded */ - byte mdc_method; /* > 0: integrity protected encrypted data packet */ - iobuf_t buf; /* IOBUF reference */ + /* Remaining length of encrypted data. */ + u32 len; + /* When encrypting, the first block size bytes of data are random + data and the following 2 bytes are copies of the last two bytes + of the random data (RFC 4880, Section 5.7). This provides a + simple check that the key is correct. extralen is the size of + this extra data. This is used by build_packet when writing out + the packet's header. */ + int extralen; + /* Whether the serialized version of the packet used / should use + the new format. */ + byte new_ctb; + /* Whether the packet has an indeterminate length (old format) or + was encoded using partial body length headers (new format). + Note: this is ignored when encrypting. */ + byte is_partial; + /* If 0, MDC is disabled. Otherwise, the MDC method that was used + (currently, only DIGEST_ALGO_SHA1 is supported). */ + byte mdc_method; + /* An iobuf holding the data to be decrypted. (This is not used for + encryption!) */ + iobuf_t buf; } PKT_encrypted; typedef struct { @@ -357,15 +473,22 @@ typedef struct { unsigned int sigcache; } PKT_ring_trust; +/* A plaintext packet (see RFC 4880, 5.9). */ typedef struct { - u32 len; /* length of encrypted data */ - iobuf_t buf; /* IOBUF reference */ - byte new_ctb; - byte is_partial; /* partial length encoded */ - int mode; - u32 timestamp; - int namelen; - char name[1]; + /* The length of data in BUF or 0 if unknown. */ + u32 len; + /* A buffer containing the data stored in the packet's body. */ + iobuf_t buf; + byte new_ctb; + byte is_partial; /* partial length encoded */ + /* The data's formatting. This is either 'b', 't', 'u', 'l' or '1' + (however, the last two are deprecated). */ + int mode; + u32 timestamp; + /* The name of the file. This can be at most 255 characters long, + since namelen is just a byte in the serialized format. */ + int namelen; + char name[1]; } PKT_plaintext; typedef struct { @@ -401,18 +524,38 @@ struct packet_struct { } while(0) +/* A notation. See RFC 4880, Section 5.2.3.16. */ struct notation { + /* The notation's name. */ char *name; + /* If the notation is human readable, then the value is stored here + as a NUL-terminated string. */ char *value; + /* Sometimes we want to %-expand the value. In these cases, we save + that transformed value here. */ char *altvalue; + /* If the notation is not human readable, then the value is strored + here. */ unsigned char *bdat; + /* The amount of data stored in BDAT. + + Note: if this is 0 and BDAT is NULL, this does not necessarily + mean that the value is human readable. It could be that we have + a 0-length value. To determine whether the notation is human + readable, always check if VALUE is not NULL. This works, because + if a human-readable value has a length of 0, we will still + allocate space for the NUL byte. */ size_t blen; struct { + /* The notation is critical. */ unsigned int critical:1; + /* The notation should be deleted. */ unsigned int ignore:1; } flags; + + /* A field to facilitate creating a list of notations. */ struct notation *next; }; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 1be49b1..3407848 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1668,7 +1668,7 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype, } if (reqtype == SIGSUBPKT_TEST_CRITICAL) /* Returning NULL means we found a subpacket with the critical bit - set that we dn't grok. We've iterated over all the subpackets + set that we don't grok. We've iterated over all the subpackets and haven't found such a packet so we need to return a non-NULL value. */ return buffer; commit c9636a1acc952eb8e1355089bc2e229dece98165 Author: Neal H. Walfield Date: Thu Feb 25 15:19:04 2016 +0100 gpg: Add some asserts. * g10/build-packet.c (ctb_new_format_p): New function. (ctb_pkttype): New function. (do_user_id): Add some asserts. (do_key): Likewise. (do_symkey_enc): Likewise. (do_pubkey_enc): Likewise. (do_plaintext): Likewise. (do_encrypted): Likewise. (do_encrypted_mdc): Likewise. (do_compressed): Likewise. (do_signature): Likewise. (do_signature): Likewise. (write_header2): Likewise. -- Signed-off-by: Neal H. Walfield diff --git a/g10/build-packet.c b/g10/build-packet.c index c821ed6..a257e69 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -54,6 +54,29 @@ static int write_sign_packet_header( IOBUF out, int ctb, u32 len ); static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen ); static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen ); +/* Returns 1 if CTB is a new format ctb and 0 if CTB is an old format + ctb. */ +static int +ctb_new_format_p (int ctb) +{ + /* Bit 7 must always be set. */ + log_assert ((ctb & (1 << 7))); + /* Bit 6 indicates whether the packet is a new format packet. */ + return (ctb & (1 << 6)); +} + +/* Extract the packet type from a CTB. */ +static int +ctb_pkttype (int ctb) +{ + if (ctb_new_format_p (ctb)) + /* Bits 0 through 5 are the packet type. */ + return (ctb & ((1 << 6) - 1)); + else + /* Bits 2 through 5 are the packet type. */ + return (ctb & ((1 << 6) - 1)) >> 2; +} + /**************** * Build a packet and write it to INP * Returns: 0 := okay @@ -292,6 +315,9 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid ) { int rc; + log_assert (ctb_pkttype (ctb) == PKT_USER_ID + || ctb_pkttype (ctb) == PKT_ATTRIBUTE); + if (uid->attrib_data) { write_header(out, ctb, uid->attrib_len); @@ -313,6 +339,12 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) int i, nskey, npkey; iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer. */ + log_assert (pk->version == 0 || pk->version == 4); + log_assert (ctb_pkttype (ctb) == PKT_PUBLIC_KEY + || ctb_pkttype (ctb) == PKT_PUBLIC_SUBKEY + || ctb_pkttype (ctb) == PKT_SECRET_KEY + || ctb_pkttype (ctb) == PKT_SECRET_SUBKEY); + /* Write the version number - if none is specified, use 4 */ if ( !pk->version ) iobuf_put ( a, 4 ); @@ -335,7 +367,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) write_fake_data (a, pk->pkey[0]); goto leave; } - assert (npkey < nskey); + log_assert (npkey < nskey); for (i=0; i < npkey; i++ ) { @@ -445,6 +477,8 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc ) int rc = 0; IOBUF a = iobuf_temp(); + log_assert (ctb_pkttype (ctb) == PKT_SYMKEY_ENC); + assert( enc->version == 4 ); switch( enc->s2k.mode ) { case 0: case 1: case 3: break; @@ -477,6 +511,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) int n, i; IOBUF a = iobuf_temp(); + log_assert (ctb_pkttype (ctb) == PKT_PUBKEY_ENC); + iobuf_put (a, 3); /* Version. */ if ( enc->throw_keyid ) @@ -531,7 +567,11 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) int rc = 0; size_t nbytes; + log_assert (ctb_pkttype (ctb) == PKT_PLAINTEXT); + write_header(out, ctb, calc_plaintext( pt ) ); + log_assert (pt->mode == 'b' || pt->mode == 't' || pt->mode == 'u' + || pt->mode == 'l' || pt->mode == '1'); iobuf_put(out, pt->mode ); iobuf_put(out, pt->namelen ); iobuf_write (out, pt->name, pt->namelen); @@ -557,6 +597,9 @@ do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ) int rc = 0; u32 n; + log_assert (! ed->mdc_method); + log_assert (ctb_pkttype (ctb) == PKT_ENCRYPTED); + n = ed->len ? (ed->len + ed->extralen) : 0; write_header(out, ctb, n ); @@ -571,7 +614,8 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ) int rc = 0; u32 n; - assert( ed->mdc_method ); + log_assert (ed->mdc_method); + log_assert (ctb_pkttype (ctb) == PKT_ENCRYPTED_MDC); /* Take version number and the following MDC packet in account. */ n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0; @@ -589,6 +633,8 @@ do_compressed( IOBUF out, int ctb, PKT_compressed *cd ) { int rc = 0; + log_assert (ctb_pkttype (ctb) == PKT_COMPRESSED); + /* We must use the old convention and don't use blockmode for the sake of PGP 2 compatibility. However if the new_ctb flag was set, CTB is already formatted as new style and write_header2 @@ -1111,8 +1157,16 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) int n, i; IOBUF a = iobuf_temp(); - if ( !sig->version ) - iobuf_put( a, 3 ); + log_assert (ctb_pkttype (ctb) == PKT_SIGNATURE); + + if ( !sig->version || sig->version == 3) + { + iobuf_put( a, 3 ); + + /* Version 3 packets don't support subpackets. */ + log_assert (! sig->hashed); + log_assert (! sig->unhashed); + } else iobuf_put( a, sig->version ); if ( sig->version < 4 ) @@ -1166,6 +1220,8 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ) { + log_assert (ctb_pkttype (ctb) == PKT_ONEPASS_SIG); + write_header(out, ctb, 4 + 8 + 1); iobuf_put (out, 3); /* Version. */ @@ -1264,6 +1320,8 @@ write_header2( IOBUF out, int ctb, u32 len, int hdrlen ) if( ctb & 0x40 ) return write_new_header( out, ctb, len, hdrlen ); + log_assert (hdrlen == 0 || hdrlen == 2 || hdrlen == 3 || hdrlen == 5); + if( hdrlen ) { if( hdrlen == 2 && len < 256 ) commit 512bc72e1f8544341529174142273d857f45540c Author: Neal H. Walfield Date: Thu Feb 25 14:51:55 2016 +0100 gpg: Avoid an unnecessary copy. * g10/build-packet.c (sig_to_notation): Avoid an unnecessary copy of the data: the size of the packet is fixed. -- Signed-off-by: Neal H. Walfield diff --git a/g10/build-packet.c b/g10/build-packet.c index a6d5881..c821ed6 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1166,22 +1166,17 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ) { - int rc = 0; - IOBUF a = iobuf_temp(); + write_header(out, ctb, 4 + 8 + 1); - iobuf_put (a, 3); /* Version. */ - iobuf_put(a, ops->sig_class ); - iobuf_put(a, ops->digest_algo ); - iobuf_put(a, ops->pubkey_algo ); - write_32(a, ops->keyid[0] ); - write_32(a, ops->keyid[1] ); - iobuf_put(a, ops->last ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp( out, a ); + iobuf_put (out, 3); /* Version. */ + iobuf_put(out, ops->sig_class ); + iobuf_put(out, ops->digest_algo ); + iobuf_put(out, ops->pubkey_algo ); + write_32(out, ops->keyid[0] ); + write_32(out, ops->keyid[1] ); + iobuf_put(out, ops->last ); - iobuf_close(a); - return rc; + return 0; } ----------------------------------------------------------------------- Summary of changes: g10/build-packet.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++------- g10/packet.h | 249 +++++++++++++++++++++++++++++++++++++---------- g10/parse-packet.c | 2 +- g10/sig-check.c | 7 +- 4 files changed, 450 insertions(+), 88 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Feb 26 01:43:48 2016 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 26 Feb 2016 01:43:48 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.21-10-g49655fb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via 49655fb6ef39b307787e1b6e00c996f9c7db64f7 (commit) via 5168b97fb5e2eebdc99b40f96f9b6289647e87d2 (commit) from 1e6c5a70b3b51f81d2fc1289129f6c3e1920ebcc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 49655fb6ef39b307787e1b6e00c996f9c7db64f7 Author: NIIBE Yutaka Date: Fri Feb 26 09:43:37 2016 +0900 po: Update Japanese translation diff --git a/po/ja.po b/po/ja.po index 4f9460a..78d0b60 100644 --- a/po/ja.po +++ b/po/ja.po @@ -3,12 +3,12 @@ # This file is distributed under the same license as the libgpg-error package. # Yasuaki Taniguchi , 2010. # Takeshi Hamasaki , 2012. -# NIIBE Yutaka , 2014, 2015. +# NIIBE Yutaka , 2014, 2015, 2016. msgid "" msgstr "" "Project-Id-Version: libgpg-error 1.19\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2015-12-14 11:19+0900\n" +"PO-Revision-Date: 2016-02-26 09:42+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -728,6 +728,9 @@ msgstr "S??????16???????????" msgid "Bad octal character in S-expression" msgstr "S??????8???????????" +msgid "Database is corrupted" +msgstr "????????????????" + msgid "Server indicated a failure" msgstr "?????????????" commit 5168b97fb5e2eebdc99b40f96f9b6289647e87d2 Author: NIIBE Yutaka Date: Fri Feb 26 09:29:14 2016 +0900 Add support for Solaris, fixing HPPA. * configure.ac (HAVE_GCC_ATTRIBUTE_ALIGNED): Remove. (LIB_SCHED_YIELD): New. Check sched_yield in -lrt. * src/gen-posix-lock-obj.c (USE_16BYTE_ALIGNMENT): Remove. (USE_DOUBLE_FOR_ALIGNMENT, USE_LONG_DOUBLE_FOR_ALIGNMENT): New. * src/syscfg/lock-obj-pub.hppa-unknown-linux-gnu.h: Update. -- Signed-off-by: NIIBE Yutaka diff --git a/configure.ac b/configure.ac index 19ae9c8..9882d02 100644 --- a/configure.ac +++ b/configure.ac @@ -274,20 +274,6 @@ if test "$GCC" = yes; then fi # -# Check whether the compiler supports the GCC style aligned attribute -# -AC_CACHE_CHECK([whether the GCC style aligned attribute is supported], - [gcry_cv_gcc_attribute_aligned], - [gcry_cv_gcc_attribute_aligned=no - AC_COMPILE_IFELSE([AC_LANG_SOURCE( - [[struct { int a; } foo __attribute__ ((aligned (16)));]])], - [gcry_cv_gcc_attribute_aligned=yes])]) -if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then - AC_DEFINE(HAVE_GCC_ATTRIBUTE_ALIGNED,1, - [Defined if a GCC style "__attribute__ ((aligned (n))" is supported]) -fi - -# # Check for ELF visibility support. # AC_CACHE_CHECK(whether the visibility attribute is supported, @@ -416,6 +402,25 @@ else fi fi +# Default value for GPG_ERROR_CONFIG_LIBS +config_libs="-lgpg-error" + +# +# Check for other libraries (now only for -lrt). +# +# Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all* +# programs in the package would end up linked with that potentially-shared +# library, inducing unnecessary run-time overhead. +LIB_SCHED_YIELD= +AC_SUBST([LIB_SCHED_YIELD]) +gl_saved_libs=$LIBS +AC_SEARCH_LIBS([sched_yield], [rt posix4], + [if test "$ac_cv_search_sched_yield" != "none required"; then + LIB_SCHED_YIELD=$ac_cv_search_sched_yield + config_libs="$config_libs $LIB_SCHED_YIELD" + fi]) +LIBS=$gl_saved_libs + # # Prepare building of estream # @@ -424,7 +429,7 @@ estream_INIT # # Substitution used for gpg-error-config # -GPG_ERROR_CONFIG_LIBS="-lgpg-error" +GPG_ERROR_CONFIG_LIBS="$config_libs" if test "x$LIBTHREAD" != x; then GPG_ERROR_CONFIG_LIBS="${GPG_ERROR_CONFIG_LIBS} ${LIBTHREAD}" fi @@ -544,11 +549,3 @@ echo " Revision: mym4_revision (mym4_revision_dec) Platform: $host$tmp " -if test "$gcry_cv_gcc_attribute_aligned" != "yes" ; then -cat < This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 2de0d41219a522e01f050d475b3ddecb9173fc7d (commit) from 87515e39295e4b7eaec1641c38e1ac32e8d39a91 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2de0d41219a522e01f050d475b3ddecb9173fc7d Author: Werner Koch Date: Fri Feb 26 11:41:18 2016 +0100 gpg: Prettify a 2 octet hex output. * g10/sig-check.c (check_key_signature2): Wrap line and use %02x. Signed-off-by: Werner Koch diff --git a/g10/sig-check.c b/g10/sig-check.c index 087222a..ee0ebcb 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -1087,7 +1087,8 @@ check_key_signature2 (kbnode_t root, kbnode_t node, PKT_public_key *check_pk, } else { - log_info ("sig issued by %s with class %d (digest: %x %x) is not valid over a user id or a key id, ignoring.\n", + log_info ("sig issued by %s with class %d (digest: %02x %02x)" + " is not valid over a user id or a key id, ignoring.\n", keystr (sig->keyid), sig->sig_class, sig->digest_start[0], sig->digest_start[1]); rc = gpg_error (GPG_ERR_BAD_SIGNATURE); ----------------------------------------------------------------------- Summary of changes: g10/sig-check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org