From cvs at cvs.gnupg.org Mon Dec 3 16:02:56 2012 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Mon, 03 Dec 2012 16:02:56 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-71-gf851b9a 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 f851b9a932ee64fa5a06000d1ac763ba4349f07d (commit) via d9ec7aec1301b13a89e5c9c54d7ad52e1a29b846 (commit) via 162791bc08f4fc9b3882671e68ecdfd9e130ae59 (commit) from 9ee9e25f519696d509b1a5c1cc04ab0121e98a51 (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 f851b9a932ee64fa5a06000d1ac763ba4349f07d Author: Jussi Kivilinna Date: Thu Nov 29 21:55:34 2012 +0200 Fix building with CC="gcc -std=c90". * configure.ac: Add check for missing 'asm' keyword in C90 mode and replacement with '__asm__'. -- Signed-off-by: Jussi Kivilinna diff --git a/configure.ac b/configure.ac index a2235a8..ff07dda 100644 --- a/configure.ac +++ b/configure.ac @@ -804,6 +804,31 @@ if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then fi +# +# Check whether the compiler supports 'asm' or '__asm__' keyword for +# assembler blocks +# +AC_CACHE_CHECK([whether 'asm' assembler keyword is supported], + [gcry_cv_have_asm], + [gcry_cv_have_asm=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[void a(void) { asm("":::"memory"); }]])], + [gcry_cv_have_asm=yes])]) +AC_CACHE_CHECK([whether '__asm__' assembler keyword is supported], + [gcry_cv_have___asm__], + [gcry_cv_have___asm__=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[void a(void) { __asm__("":::"memory"); }]])], + [gcry_cv_have___asm__=yes])]) +if test "$gcry_cv_have_asm" = "no" ; then + if test "$gcry_cv_have___asm__" = "yes" ; then + AC_DEFINE(asm,__asm__, + [Define to supported assembler block keyword, if plain 'asm' was not + supported]) + fi +fi + + ####################################### #### Checks for library functions. #### ####################################### commit d9ec7aec1301b13a89e5c9c54d7ad52e1a29b846 Author: Werner Koch Date: Mon Dec 3 14:28:12 2012 +0100 Try to use inttypes.h if stdint.h is not available. * cipher/bufhelp.h [HAVE_INTTYPES_H]: Include inttypes.h -- According to the description of AC_TYPE_UINTPTR_T, this header should also be included. diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h index a3be24a..638ca1b 100644 --- a/cipher/bufhelp.h +++ b/cipher/bufhelp.h @@ -22,6 +22,8 @@ #ifdef HAVE_STDINT_H # include /* uintptr_t */ +#elif defined(HAVE_INTTYPES_H) +# include #else /* In this case, uintptr_t is provided by config.h. */ #endif commit 162791bc08f4fc9b3882671e68ecdfd9e130ae59 Author: Jussi Kivilinna Date: Thu Nov 29 21:54:57 2012 +0200 Optimize buffer xoring. * cipher/Makefile.am (libcipher_la_SOURCES): Add 'bufhelp.h'. * cipher/bufhelp.h: New. * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt) (_gcry_cipher_aeswrap_decrypt): Use 'buf_xor' for buffer xoring. * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt) (_gcry_cipher_cbc_decrypt): Use 'buf_xor' for buffer xoring and remove resulting unused variables. * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt) Use 'buf_xor_2dst' for buffer xoring and remove resulting unused variables. (_gcry_cipher_cfb_decrypt): Use 'buf_xor_n_copy' for buffer xoring and remove resulting unused variables. * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Use 'buf_xor' for buffer xoring and remove resulting unused variables. * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt) (_gcry_cipher_ofb_decrypt): Use 'buf_xor' for buffer xoring and remove resulting used variables. * cipher/rijndael.c (_gry_aes_cfb_enc): Use 'buf_xor_2dst' for buffer xoring and remove resulting unused variables. (_gry_aes_cfb_dev): Use 'buf_xor_n_copy' for buffer xoring and remove resulting unused variables. (_gry_aes_cbc_enc, _gry_aes_ctr_enc, _gry_aes_cbc_dec): Use 'buf_xor' for buffer xoring and remove resulting unused variables. -- Add faster helper functions for buffer xoring and replace byte buffer xor loops. This give following speed up. Note that CTR speed up is from refactoring code to use buf_xor() and removal of integer division/modulo operations issued per each processed byte. This removal of div/mod most likely gives even greater speed increase on CPU architechtures that do not have hardware division unit. Benchmark ratios (old-vs-new, AMD Phenom II, x86-64): ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 0.99x 1.01x 1.06x 1.02x 1.03x 1.06x 1.04x 1.02x 1.58x 1.58x 3DES 1.00x 1.00x 1.01x 1.01x 1.02x 1.02x 1.02x 1.01x 1.22x 1.23x CAST5 0.98x 1.00x 1.09x 1.03x 1.09x 1.09x 1.07x 1.07x 1.98x 1.95x BLOWFISH 1.00x 1.00x 1.18x 1.05x 1.07x 1.07x 1.05x 1.05x 1.93x 1.91x AES 1.00x 0.98x 1.18x 1.14x 1.13x 1.13x 1.14x 1.14x 1.18x 1.18x AES192 0.98x 1.00x 1.13x 1.14x 1.13x 1.10x 1.14x 1.16x 1.15x 1.15x AES256 0.97x 1.02x 1.09x 1.13x 1.13x 1.09x 1.10x 1.14x 1.11x 1.13x TWOFISH 1.00x 1.00x 1.15x 1.17x 1.18x 1.16x 1.18x 1.13x 2.37x 2.31x ARCFOUR 1.03x 0.97x DES 1.01x 1.00x 1.04x 1.04x 1.04x 1.05x 1.05x 1.02x 1.56x 1.55x TWOFISH128 0.97x 1.03x 1.18x 1.17x 1.18x 1.15x 1.15x 1.15x 2.37x 2.31x SERPENT128 1.00x 1.00x 1.10x 1.11x 1.08x 1.09x 1.08x 1.06x 1.66x 1.67x SERPENT192 1.00x 1.00x 1.07x 1.08x 1.08x 1.09x 1.08x 1.08x 1.65x 1.66x SERPENT256 1.00x 1.00x 1.09x 1.09x 1.08x 1.09x 1.08x 1.06x 1.66x 1.67x RFC2268_40 1.03x 0.99x 1.05x 1.02x 1.03x 1.03x 1.04x 1.03x 1.46x 1.46x SEED 1.00x 1.00x 1.10x 1.10x 1.09x 1.09x 1.10x 1.07x 1.80x 1.76x CAMELLIA128 1.00x 1.00x 1.23x 1.12x 1.15x 1.17x 1.15x 1.12x 2.15x 2.13x CAMELLIA192 1.05x 1.03x 1.23x 1.21x 1.21x 1.16x 1.12x 1.25x 1.90x 1.90x CAMELLIA256 1.03x 1.07x 1.10x 1.19x 1.08x 1.14x 1.12x 1.10x 1.90x 1.92x Benchmark ratios (old-vs-new, AMD Phenom II, i386): ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 1.00x 1.00x 1.04x 1.05x 1.04x 1.02x 1.02x 1.02x 1.38x 1.40x 3DES 1.01x 1.00x 1.02x 1.04x 1.03x 1.01x 1.00x 1.02x 1.20x 1.20x CAST5 1.00x 1.00x 1.03x 1.09x 1.07x 1.04x 1.13x 1.00x 1.74x 1.74x BLOWFISH 1.04x 1.08x 1.03x 1.13x 1.07x 1.12x 1.03x 1.00x 1.78x 1.74x AES 0.96x 1.00x 1.09x 1.08x 1.14x 1.13x 1.07x 1.03x 1.14x 1.09x AES192 1.00x 1.03x 1.07x 1.03x 1.07x 1.07x 1.06x 1.03x 1.08x 1.11x AES256 1.00x 1.00x 1.06x 1.06x 1.10x 1.06x 1.05x 1.03x 1.10x 1.10x TWOFISH 0.95x 1.10x 1.13x 1.23x 1.05x 1.14x 1.09x 1.13x 1.95x 1.86x ARCFOUR 1.00x 1.00x DES 1.02x 0.98x 1.04x 1.04x 1.05x 1.02x 1.04x 1.00x 1.45x 1.48x TWOFISH128 0.95x 1.10x 1.26x 1.19x 1.09x 1.14x 1.17x 1.00x 2.00x 1.91x SERPENT128 1.02x 1.00x 1.08x 1.04x 1.10x 1.06x 1.08x 1.04x 1.42x 1.42x SERPENT192 1.02x 1.02x 1.06x 1.06x 1.10x 1.08x 1.04x 1.06x 1.42x 1.42x SERPENT256 1.02x 0.98x 1.06x 1.06x 1.10x 1.06x 1.04x 1.06x 1.42x 1.40x RFC2268_40 1.00x 1.00x 1.02x 1.06x 1.04x 1.02x 1.02x 1.02x 1.35x 1.35x SEED 1.00x 0.97x 1.11x 1.05x 1.06x 1.08x 1.08x 1.05x 1.56x 1.57x CAMELLIA128 1.03x 0.97x 1.12x 1.14x 1.06x 1.10x 1.06x 1.06x 1.73x 1.59x CAMELLIA192 1.06x 1.00x 1.13x 1.10x 1.11x 1.11x 1.15x 1.08x 1.57x 1.58x CAMELLIA256 1.06x 1.03x 1.10x 1.10x 1.11x 1.11x 1.13x 1.08x 1.57x 1.62x [v2]: - include stdint.h only when it's available - use uintptr_t instead of long and intptr_t Signed-off-by: Jussi Kivilinna diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 473e3c8..e8050e3 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -40,6 +40,7 @@ cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \ pubkey.c md.c kdf.c \ hmac-tests.c \ bithelp.h \ +bufhelp.h \ primegen.c \ hash-common.c hash-common.h \ rmd.h diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h new file mode 100644 index 0000000..a3be24a --- /dev/null +++ b/cipher/bufhelp.h @@ -0,0 +1,179 @@ +/* bufhelp.h - Some buffer manipulation helpers + * Copyright ? 2012 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifndef G10_BUFHELP_H +#define G10_BUFHELP_H + +#ifdef HAVE_STDINT_H +# include /* uintptr_t */ +#else +/* In this case, uintptr_t is provided by config.h. */ +#endif + + +#if defined(__i386__) || defined(__x86_64__) +/* These architechtures are able of unaligned memory accesses and can + handle those fast. + */ +# define BUFHELP_FAST_UNALIGNED_ACCESS 1 +#endif + + +/* Optimized function for buffer xoring */ +static inline void +buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len) +{ + byte *dst = _dst; + const byte *src1 = _src1; + const byte *src2 = _src2; + uintptr_t *ldst; + const uintptr_t *lsrc1, *lsrc2; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(uintptr_t) - 1; + + /* Skip fast processing if alignment of buffers do not match. */ + if ((((uintptr_t)dst ^ (uintptr_t)src1) | + ((uintptr_t)dst ^ (uintptr_t)src2)) & longmask) + goto do_bytes; + + /* Handle unaligned head. */ + for (; len && ((uintptr_t)dst & longmask); len--) + *dst++ = *src1++ ^ *src2++; +#endif + + ldst = (uintptr_t *)dst; + lsrc1 = (const uintptr_t *)src1; + lsrc2 = (const uintptr_t *)src2; + + for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) + *ldst++ = *lsrc1++ ^ *lsrc2++; + + dst = (byte *)ldst; + src1 = (const byte *)lsrc1; + src2 = (const byte *)lsrc2; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + *dst++ = *src1++ ^ *src2++; +} + + +/* Optimized function for buffer xoring with two destination buffers. Used + mainly by CFB mode encryption. */ +static inline void +buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len) +{ + byte *dst1 = _dst1; + byte *dst2 = _dst2; + const byte *src = _src; + uintptr_t *ldst1, *ldst2; + const uintptr_t *lsrc; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(uintptr_t) - 1; + + /* Skip fast processing if alignment of buffers do not match. */ + if ((((uintptr_t)src ^ (uintptr_t)dst1) | + ((uintptr_t)src ^ (uintptr_t)dst2)) & longmask) + goto do_bytes; + + /* Handle unaligned head. */ + for (; len && ((uintptr_t)src & longmask); len--) + *dst1++ = (*dst2++ ^= *src++); +#endif + + ldst1 = (uintptr_t *)dst1; + ldst2 = (uintptr_t *)dst2; + lsrc = (const uintptr_t *)src; + + for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) + *ldst1++ = (*ldst2++ ^= *lsrc++); + + dst1 = (byte *)ldst1; + dst2 = (byte *)ldst2; + src = (const byte *)lsrc; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + *dst1++ = (*dst2++ ^= *src++); +} + + +/* Optimized function for combined buffer xoring and copying. Used by mainly + CFB mode decryption. */ +static inline void +buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len) +{ + byte *dst_xor = _dst_xor; + byte *srcdst_cpy = _srcdst_cpy; + byte temp; + const byte *src = _src; + uintptr_t *ldst_xor, *lsrcdst_cpy; + const uintptr_t *lsrc; + uintptr_t ltemp; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(uintptr_t) - 1; + + /* Skip fast processing if alignment of buffers do not match. */ + if ((((uintptr_t)src ^ (uintptr_t)dst_xor) | + ((uintptr_t)src ^ (uintptr_t)srcdst_cpy)) & longmask) + goto do_bytes; + + /* Handle unaligned head. */ + for (; len && ((uintptr_t)src & longmask); len--) + { + temp = *src++; + *dst_xor++ = *srcdst_cpy ^ temp; + *srcdst_cpy++ = temp; + } +#endif + + ldst_xor = (uintptr_t *)dst_xor; + lsrcdst_cpy = (uintptr_t *)srcdst_cpy; + lsrc = (const uintptr_t *)src; + + for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t)) + { + ltemp = *lsrc++; + *ldst_xor++ = *lsrcdst_cpy ^ ltemp; + *lsrcdst_cpy++ = ltemp; + } + + dst_xor = (byte *)ldst_xor; + srcdst_cpy = (byte *)lsrcdst_cpy; + src = (const byte *)lsrc; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + { + temp = *src++; + *dst_xor++ = *srcdst_cpy ^ temp; + *srcdst_cpy++ = temp; + } +} + +#endif /*G10_BITHELP_H*/ diff --git a/cipher/cipher-aeswrap.c b/cipher/cipher-aeswrap.c index b559e7f..8e117eb 100644 --- a/cipher/cipher-aeswrap.c +++ b/cipher/cipher-aeswrap.c @@ -26,6 +26,7 @@ #include "g10lib.h" #include "cipher.h" #include "ath.h" +#include "bufhelp.h" #include "./cipher-internal.h" @@ -95,8 +96,7 @@ _gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c, break; } /* A := MSB_64(B) ^ t */ - for (x=0; x < 8; x++) - a[x] = b[x] ^ t[x]; + buf_xor(a, b, t, 8); /* R[i] := LSB_64(B) */ memcpy (r+i*8, b+8, 8); } @@ -161,8 +161,7 @@ _gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c, for (i = n; i >= 1; i--) { /* B := AES_k^1( (A ^ t)| R[i] ) */ - for (x = 0; x < 8; x++) - b[x] = a[x] ^ t[x]; + buf_xor(b, a, t, 8); memcpy (b+8, r+(i-1)*8, 8); c->cipher->decrypt (&c->context.c, b, b); /* t := t - 1 */ diff --git a/cipher/cipher-cbc.c b/cipher/cipher-cbc.c index b852589..0d30f63 100644 --- a/cipher/cipher-cbc.c +++ b/cipher/cipher-cbc.c @@ -28,6 +28,7 @@ #include "cipher.h" #include "ath.h" #include "./cipher-internal.h" +#include "bufhelp.h" @@ -68,8 +69,7 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c, { for (n=0; n < nblocks; n++ ) { - for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - outbuf[i] = inbuf[i] ^ *ivp++; + buf_xor(outbuf, inbuf, c->u_iv.iv, blocksize); c->cipher->encrypt ( &c->context.c, outbuf, outbuf ); memcpy (c->u_iv.iv, outbuf, blocksize ); inbuf += blocksize; @@ -114,7 +114,6 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, const unsigned char *inbuf, unsigned int inbuflen) { unsigned int n; - unsigned char *ivp; int i; size_t blocksize = c->cipher->blocksize; unsigned int nblocks = inbuflen / blocksize; @@ -150,8 +149,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, * this here because it is not used otherwise. */ memcpy (c->lastiv, inbuf, blocksize); c->cipher->decrypt ( &c->context.c, outbuf, inbuf ); - for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - outbuf[i] ^= *ivp++; + buf_xor(outbuf, outbuf, c->u_iv.iv, blocksize); memcpy(c->u_iv.iv, c->lastiv, blocksize ); inbuf += c->cipher->blocksize; outbuf += c->cipher->blocksize; @@ -171,15 +169,13 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c, memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */ c->cipher->decrypt ( &c->context.c, outbuf, inbuf ); - for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ ) - outbuf[i] ^= *ivp++; + buf_xor(outbuf, outbuf, c->u_iv.iv, restbytes); memcpy(outbuf + blocksize, outbuf, restbytes); for(i=restbytes; i < blocksize; i++) c->u_iv.iv[i] = outbuf[i]; c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv); - for(ivp=c->lastiv,i=0; i < blocksize; i++ ) - outbuf[i] ^= *ivp++; + buf_xor(outbuf, outbuf, c->lastiv, blocksize); /* c->lastiv is now really lastlastiv, does this matter? */ } diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c index f4152b9..ed84b75 100644 --- a/cipher/cipher-cfb.c +++ b/cipher/cipher-cfb.c @@ -27,6 +27,7 @@ #include "g10lib.h" #include "cipher.h" #include "ath.h" +#include "bufhelp.h" #include "./cipher-internal.h" @@ -46,10 +47,9 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, { /* Short enough to be encoded by the remaining XOR mask. */ /* XOR the input with the IV and store input into IV. */ - for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused; - inbuflen; - inbuflen--, c->unused-- ) - *outbuf++ = (*ivp++ ^= *inbuf++); + ivp = c->u_iv.iv + c->cipher->blocksize - c->unused; + buf_xor_2dst(outbuf, ivp, inbuf, inbuflen); + c->unused -= inbuflen; return 0; } @@ -57,8 +57,11 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, { /* XOR the input with the IV and store input into IV */ inbuflen -= c->unused; - for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) - *outbuf++ = (*ivp++ ^= *inbuf++); + ivp = c->u_iv.iv + blocksize - c->unused; + buf_xor_2dst(outbuf, ivp, inbuf, c->unused); + outbuf += c->unused; + inbuf += c->unused; + c->unused = 0; } /* Now we can process complete blocks. We use a loop as long as we @@ -76,25 +79,25 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, { while ( inbuflen >= blocksize_x_2 ) { - int i; /* Encrypt the IV. */ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); /* XOR the input with the IV and store input into IV. */ - for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - *outbuf++ = (*ivp++ ^= *inbuf++); + buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; inbuflen -= blocksize; } } if ( inbuflen >= blocksize ) { - int i; /* Save the current IV and then encrypt the IV. */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); /* XOR the input with the IV and store input into IV */ - for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - *outbuf++ = (*ivp++ ^= *inbuf++); + buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; inbuflen -= blocksize; } if ( inbuflen ) @@ -105,8 +108,10 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c, c->unused = blocksize; /* Apply the XOR. */ c->unused -= inbuflen; - for(ivp=c->u_iv.iv; inbuflen; inbuflen-- ) - *outbuf++ = (*ivp++ ^= *inbuf++); + buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, inbuflen); + outbuf += inbuflen; + inbuf += inbuflen; + inbuflen = 0; } return 0; } @@ -118,8 +123,6 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, const unsigned char *inbuf, unsigned int inbuflen) { unsigned char *ivp; - unsigned long temp; - int i; size_t blocksize = c->cipher->blocksize; size_t blocksize_x_2 = blocksize + blocksize; @@ -130,14 +133,9 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, { /* Short enough to be encoded by the remaining XOR mask. */ /* XOR the input with the IV and store input into IV. */ - for (ivp=c->u_iv.iv+blocksize - c->unused; - inbuflen; - inbuflen--, c->unused--) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + ivp = c->u_iv.iv + blocksize - c->unused; + buf_xor_n_copy(outbuf, ivp, inbuf, inbuflen); + c->unused -= inbuflen; return 0; } @@ -145,12 +143,11 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, { /* XOR the input with the IV and store input into IV. */ inbuflen -= c->unused; - for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + ivp = c->u_iv.iv + blocksize - c->unused; + buf_xor_n_copy(outbuf, ivp, inbuf, c->unused); + outbuf += c->unused; + inbuf += c->unused; + c->unused = 0; } /* Now we can process complete blocks. We use a loop as long as we @@ -171,12 +168,9 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, /* Encrypt the IV. */ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); /* XOR the input with the IV and store input into IV. */ - for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; inbuflen -= blocksize; } } @@ -187,12 +181,9 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, memcpy ( c->lastiv, c->u_iv.iv, blocksize); c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); /* XOR the input with the IV and store input into IV */ - for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; inbuflen -= blocksize; } @@ -204,12 +195,10 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c, c->unused = blocksize; /* Apply the XOR. */ c->unused -= inbuflen; - for (ivp=c->u_iv.iv; inbuflen; inbuflen-- ) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, inbuflen); + outbuf += inbuflen; + inbuf += inbuflen; + inbuflen = 0; } return 0; } diff --git a/cipher/cipher-ctr.c b/cipher/cipher-ctr.c index a334abc..6bc6ffc 100644 --- a/cipher/cipher-ctr.c +++ b/cipher/cipher-ctr.c @@ -27,6 +27,7 @@ #include "g10lib.h" #include "cipher.h" #include "ath.h" +#include "bufhelp.h" #include "./cipher-internal.h" @@ -48,11 +49,9 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, { gcry_assert (c->unused < blocksize); i = blocksize - c->unused; - for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++) - { - /* XOR input with encrypted counter and store in output. */ - outbuf[n] = inbuf[n] ^ c->lastiv[i]; - } + n = c->unused > inbuflen ? inbuflen : c->unused; + buf_xor(outbuf, inbuf, &c->lastiv[i], n); + c->unused -= n; inbuf += n; outbuf += n; inbuflen -= n; @@ -75,27 +74,26 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c, { unsigned char tmp[MAX_BLOCKSIZE]; - for (n=0; n < inbuflen; n++) - { - if ((n % blocksize) == 0) - { - c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); + do { + c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); - for (i = blocksize; i > 0; i--) - { - c->u_ctr.ctr[i-1]++; - if (c->u_ctr.ctr[i-1] != 0) - break; - } - } + for (i = blocksize; i > 0; i--) + { + c->u_ctr.ctr[i-1]++; + if (c->u_ctr.ctr[i-1] != 0) + break; + } - /* XOR input with encrypted counter and store in output. */ - outbuf[n] = inbuf[n] ^ tmp[n % blocksize]; - } + n = blocksize < inbuflen ? blocksize : inbuflen; + buf_xor(outbuf, inbuf, tmp, n); + + inbuflen -= n; + outbuf += n; + inbuf += n; + } while (inbuflen); /* Save the unused bytes of the counter. */ - n %= blocksize; - c->unused = (blocksize - n) % blocksize; + c->unused = blocksize - n; if (c->unused) memcpy (c->lastiv+n, tmp+n, c->unused); diff --git a/cipher/cipher-ofb.c b/cipher/cipher-ofb.c index e5868cd..e194976 100644 --- a/cipher/cipher-ofb.c +++ b/cipher/cipher-ofb.c @@ -27,6 +27,7 @@ #include "g10lib.h" #include "cipher.h" #include "ath.h" +#include "bufhelp.h" #include "./cipher-internal.h" @@ -45,30 +46,31 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, { /* Short enough to be encoded by the remaining XOR mask. */ /* XOR the input with the IV */ - for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused; - inbuflen; - inbuflen--, c->unused-- ) - *outbuf++ = (*ivp++ ^ *inbuf++); + ivp = c->u_iv.iv + c->cipher->blocksize - c->unused; + buf_xor(outbuf, ivp, inbuf, inbuflen); + c->unused -= inbuflen; return 0; } if( c->unused ) { inbuflen -= c->unused; - for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) - *outbuf++ = (*ivp++ ^ *inbuf++); + ivp = c->u_iv.iv + blocksize - c->unused; + buf_xor(outbuf, ivp, inbuf, c->unused); + outbuf += c->unused; + inbuf += c->unused; + c->unused = 0; } /* Now we can process complete blocks. */ while ( inbuflen >= blocksize ) { - int i; /* Encrypt the IV (and save the current one). */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - - for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - *outbuf++ = (*ivp++ ^ *inbuf++); + buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; inbuflen -= blocksize; } if ( inbuflen ) @@ -77,8 +79,10 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c, c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); c->unused = blocksize; c->unused -= inbuflen; - for(ivp=c->u_iv.iv; inbuflen; inbuflen-- ) - *outbuf++ = (*ivp++ ^ *inbuf++); + buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen); + outbuf += inbuflen; + inbuf += inbuflen; + inbuflen = 0; } return 0; } @@ -98,27 +102,31 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, if( inbuflen <= c->unused ) { /* Short enough to be encoded by the remaining XOR mask. */ - for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--) - *outbuf++ = *ivp++ ^ *inbuf++; + ivp = c->u_iv.iv + blocksize - c->unused; + buf_xor(outbuf, ivp, inbuf, inbuflen); + c->unused -= inbuflen; return 0; } if ( c->unused ) { inbuflen -= c->unused; - for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) - *outbuf++ = *ivp++ ^ *inbuf++; + ivp = c->u_iv.iv + blocksize - c->unused; + buf_xor(outbuf, ivp, inbuf, c->unused); + outbuf += c->unused; + inbuf += c->unused; + c->unused = 0; } /* Now we can process complete blocks. */ while ( inbuflen >= blocksize ) { - int i; /* Encrypt the IV (and save the current one). */ memcpy( c->lastiv, c->u_iv.iv, blocksize ); c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) - *outbuf++ = *ivp++ ^ *inbuf++; + buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; inbuflen -= blocksize; } if ( inbuflen ) @@ -128,8 +136,10 @@ _gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c, c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); c->unused = blocksize; c->unused -= inbuflen; - for (ivp=c->u_iv.iv; inbuflen; inbuflen-- ) - *outbuf++ = *ivp++ ^ *inbuf++; + buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen); + outbuf += inbuflen; + inbuf += inbuflen; + inbuflen = 0; } return 0; } diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 6313ab2..24372d9 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -45,6 +45,7 @@ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" +#include "bufhelp.h" #define MAXKC (256/32) #define MAXROUNDS 14 @@ -1337,8 +1338,6 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned char *ivp; - int i; if (0) ; @@ -1351,8 +1350,9 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, /* Encrypt the IV. */ do_padlock (ctx, 0, iv, iv); /* XOR the input with the IV and store input into IV. */ - for (ivp=iv,i=0; i < BLOCKSIZE; i++ ) - *outbuf++ = (*ivp++ ^= *inbuf++); + buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; } } #endif /*USE_PADLOCK*/ @@ -1376,8 +1376,9 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, /* Encrypt the IV. */ do_encrypt_aligned (ctx, iv, iv); /* XOR the input with the IV and store input into IV. */ - for (ivp=iv,i=0; i < BLOCKSIZE; i++ ) - *outbuf++ = (*ivp++ ^= *inbuf++); + buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; } } @@ -1397,8 +1398,6 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned char *ivp; - int i; aesni_prepare (); for ( ;nblocks; nblocks-- ) @@ -1432,8 +1431,7 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, #endif /*USE_AESNI*/ else { - for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) - outbuf[i] = inbuf[i] ^ *ivp++; + buf_xor(outbuf, inbuf, iv, BLOCKSIZE); if (0) ; @@ -1470,7 +1468,6 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned char *p; int i; if (0) @@ -1504,8 +1501,9 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, /* Encrypt the counter. */ do_encrypt_aligned (ctx, tmp.x1, ctr); /* XOR the input with the encrypted counter and store in output. */ - for (p=tmp.x1, i=0; i < BLOCKSIZE; i++) - *outbuf++ = (*p++ ^= *inbuf++); + buf_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; /* Increment the counter. */ for (i = BLOCKSIZE; i > 0; i--) { @@ -1694,9 +1692,6 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned char *ivp; - unsigned char temp; - int i; if (0) ; @@ -1707,12 +1702,9 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, for ( ;nblocks; nblocks-- ) { do_padlock (ctx, 0, iv, iv); - for (ivp=iv,i=0; i < BLOCKSIZE; i++ ) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; } } #endif /*USE_PADLOCK*/ @@ -1734,12 +1726,9 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, for ( ;nblocks; nblocks-- ) { do_encrypt_aligned (ctx, iv, iv); - for (ivp=iv,i=0; i < BLOCKSIZE; i++ ) - { - temp = *inbuf++; - *outbuf++ = *ivp ^ temp; - *ivp++ = temp; - } + buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; } } @@ -1759,8 +1748,6 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned char *ivp; - int i; unsigned char savebuf[BLOCKSIZE]; if (0) @@ -1871,8 +1858,7 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, else do_decrypt (ctx, outbuf, inbuf); - for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) - outbuf[i] ^= *ivp++; + buf_xor(outbuf, outbuf, iv, BLOCKSIZE); memcpy (iv, savebuf, BLOCKSIZE); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; ----------------------------------------------------------------------- Summary of changes: cipher/Makefile.am | 1 + cipher/bufhelp.h | 181 +++++++++++++++++++++++++++++++++++++++++++++++ cipher/cipher-aeswrap.c | 7 +- cipher/cipher-cbc.c | 14 ++--- cipher/cipher-cfb.c | 85 ++++++++++------------- cipher/cipher-ctr.c | 42 +++++------ cipher/cipher-ofb.c | 52 ++++++++------ cipher/rijndael.c | 50 +++++-------- configure.ac | 25 +++++++ 9 files changed, 321 insertions(+), 136 deletions(-) create mode 100644 cipher/bufhelp.h hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Dec 3 22:20:47 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 03 Dec 2012 22:20:47 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-76-g7607ab8 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 7607ab81504ce44060ed0b331d309606f5da1e75 (commit) via f17e4d920c8a18007a98830dd13163ff19616202 (commit) via 76c622e24a07f7c826812be173aa173b4334776b (commit) via 75760021b511ba438606af746431223357e7a155 (commit) via c324644aa14e54fc7051983b38222db32b8ab227 (commit) from f851b9a932ee64fa5a06000d1ac763ba4349f07d (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 7607ab81504ce44060ed0b331d309606f5da1e75 Author: Werner Koch Date: Mon Dec 3 20:41:28 2012 +0100 random: Add a RNG selection interface and system RNG wrapper. * random/random-system.c: New. * random/Makefile.am (librandom_la_SOURCES): Add new module. * random/random.c (struct rng_types): New. (_gcry_set_preferred_rng_type, _gcry_get_rng_type): New. (_gcry_random_initialize, gcry_random_add_bytes, do_randomize) (_gcry_set_random_seed_file, _gcry_update_random_seed_file) (_gcry_fast_random_poll): Dispatch to the actual RNG. * src/gcrypt.h.in (GCRYCTL_SET_PREFERRED_RNG_TYPE): New. GCRYCTL_GET_CURRENT_RNG_TYPE): New. (gcry_rng_types): New. * src/global.c (print_config): Print the TNG type. (global_init, _gcry_vcontrol): Implement the new control codes. * doc/gcrypt.texi (Controlling the library): Document the new control codes. * tests/benchmark.c (main): Add options to test the RNG types. * tests/random.c (main): Add new options. (print_hex): Print to stderr. (progress_cb, rng_type): New. (check_rng_type_switching, check_early_rng_type_switching): New. (run_all_rng_tests): New. -- The purpose of this change is to allow applications with moderate random requirements to use the system's RNG (e.g. /dev/urandom). The type switching logic makes sure that existing applications won't be affected by this change. A library is in almost all cases not able to degrade the quality of the RNG. The definition of "degrade" comes from our own assertion of the quality/trustworthiness of the RNGs: The most trustworthy RNG is the CSPRNG which dates back to the early GnuPG days. It is quite conservative and often requires more seeding than might be justified. GCRY_RNG_TYPE_STANDARD is the default unless the process is in FIPS mode. The second trustworthy RNG is the FIPS recommended X9.81 AES based implementation. It is seeded by the system's RNG. GCRY_RNG_TYPE_FIPS is the only available RNG if running in FIPS mode. The third trustworthy RNG is a mere wrapper around the system's native RNG. Thus there is no extra step on top of what, for example, /dev/random provides. GCRY_RNG_TYPE_SYSTEM may be used by applications which would use /dev/random or /dev/urandom instead. diff --git a/NEWS b/NEWS index a0fd09b..45b892f 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,10 @@ Noteworthy changes in version 1.6.0 (unreleased) * The deprecated message digest debug macros have been removed. Use gcry_md_debug instead. - * Add support for the IDEA cipher algorithm. + * Added support for the IDEA cipher algorithm. + + * Added a random number generator to directly use the system's RNG. + Also added an interface to prefer the use of a specified RNG. * Interface changes relative to the 1.5.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -28,6 +31,11 @@ Noteworthy changes in version 1.6.0 (unreleased) gcry_md_start_debug REMOVED (macro). gcry_md_stop_debug REMOVED (macro). GCRYCTL_SET_ENFORCED_FIPS_FLAG NEW. + GCRYCTL_SET_PREFERRED_RNG_TYPE NEW. + GCRYCTL_GET_CURRENT_RNG_TYPE NEW. + GCRY_RNG_TYPE_STANDARD NEW. + GCRY_RNG_TYPE_FIPS NEW. + GCRY_RNG_TYPE_SYSTEM NEW. Noteworthy changes in version 1.5.0 (2011-06-29) diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 66a05d5..fa24def 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -849,6 +849,37 @@ the library such as @code{gcry_check_version}. Note that Libgcrypt will reject an attempt to switch to the enforced fips mode during or after the intialization. + at item GCRYCTL_SET_PREFERRED_RNG_TYPE; Arguments: int +These are advisory commands to select a certain random number +generator. They are only advisory because libraries may not know what +an application actually wants or vice versa. Thus Libgcrypt employs a +priority check to select the actually used RNG. If an applications +selects a lower priority RNG but a library requests a higher priority +RNG Libgcrypt will switch to the higher priority RNG. Applications +and libaries should use these control codes before + at code{gcry_check_version}. The available generators are: + at table @code + at item GCRY_RNG_TYPE_STANDARD +A conservative standard generator based on the ``Continuously Seeded +Pseudo Random Number Generator'' designed by Peter Gutmann. + at item GCRY_RNG_TYPE_FIPS +A deterministic random number generator conforming to he document +``NIST-Recommended Random Number Generator Based on ANSI X9.31 +Appendix A.2.4 Using the 3-Key Triple DES and AES Algorithms'' +(2005-01-31). This implementation uses the AES variant. + at item GCRY_RNG_TYPE_SYSTEM +A wrapper around the system's native RNG. On Unix system these are +usually the /dev/random and /dev/urandom devices. + at end table +The default is @code{GCRY_RNG_TYPE_STANDARD} unless FIPS mode as been +enabled; in which case @code{GCRY_RNG_TYPE_FIPS} is used and locked +against further changes. + + at item GCRYCTL_GETT_CURRENT_RNG_TYPE; Arguments: int * +This command stores the type of the currently used RNG as an integer +value at the provided address. + + @item GCRYCTL_SELFTEST; Arguments: none This may be used at anytime to have the library run all implemented self-tests. It works in standard and in FIPS mode. Returns 0 on diff --git a/random/Makefile.am b/random/Makefile.am index 603226d..c9d587a 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -35,6 +35,7 @@ random.c random.h \ rand-internal.h \ random-csprng.c \ random-fips.c \ +random-system.c \ rndhw.c if USE_RANDOM_DAEMON diff --git a/random/rand-internal.h b/random/rand-internal.h index a72d88c..f59a102 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -87,6 +87,14 @@ gcry_err_code_t _gcry_rngfips_run_external_test (void *context, void _gcry_rngfips_deinit_external_test (void *context); +/*-- random-system.c --*/ +void _gcry_rngsystem_initialize (int full); +void _gcry_rngsystem_dump_stats (void); +int _gcry_rngsystem_is_faked (void); +gcry_error_t _gcry_rngsystem_add_bytes (const void *buf, size_t buflen, + int quality); +void _gcry_rngsystem_randomize (void *buffer, size_t length, + enum gcry_random_level level); diff --git a/random/random-system.c b/random/random-system.c new file mode 100644 index 0000000..0ef9d24 --- /dev/null +++ b/random/random-system.c @@ -0,0 +1,243 @@ +/* random-system.c - wrapper around the system's RNG + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * 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 . + */ + +/* + This RNG is merely wrapper around the system's native RNG. For + example on Unix systems it directly uses /dev/{u,}random. + */ + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_GETTIMEOFDAY +#include +#endif + +#include "g10lib.h" +#include "random.h" +#include "rand-internal.h" +#include "ath.h" + +/* This is the lock we use to serialize access to this RNG. The extra + integer variable is only used to check the locking state; that is, + it is not meant to be thread-safe but merely as a failsafe feature + to assert proper locking. */ +static ath_mutex_t system_rng_lock; +static int system_rng_is_locked; + + +/* --- Local prototypes --- */ + + + + +/* --- Functions --- */ + +/* Basic initialization is required to initialize mutexes and + do a few checks on the implementation. */ +static void +basic_initialization (void) +{ + static int initialized; + int my_errno; + + if (initialized) + return; + initialized = 1; + + my_errno = ath_mutex_init (&system_rng_lock); + if (my_errno) + log_fatal ("failed to create the System RNG lock: %s\n", + strerror (my_errno)); + system_rng_is_locked = 0; + + /* Make sure that we are still using the values we traditionally + used for the random levels. */ + gcry_assert (GCRY_WEAK_RANDOM == 0 + && GCRY_STRONG_RANDOM == 1 + && GCRY_VERY_STRONG_RANDOM == 2); + +} + + +/* Acquire the system_rng_lock. */ +static void +lock_rng (void) +{ + int my_errno; + + my_errno = ath_mutex_lock (&system_rng_lock); + if (my_errno) + log_fatal ("failed to acquire the System RNG lock: %s\n", + strerror (my_errno)); + system_rng_is_locked = 1; +} + + +/* Release the system_rng_lock. */ +static void +unlock_rng (void) +{ + int my_errno; + + system_rng_is_locked = 0; + my_errno = ath_mutex_unlock (&system_rng_lock); + if (my_errno) + log_fatal ("failed to release the System RNG lock: %s\n", + strerror (my_errno)); +} + + +/* Helper variables for read_cb(). + + The _gcry_rnd*_gather_random interface does not allow to provide a + data pointer. Thus we need to use a global variable for + communication. However, the then required locking is anyway a good + idea because it does not make sense to have several readers of (say + /dev/random). It is easier to serve them one after the other. */ +static unsigned char *read_cb_buffer; /* The buffer. */ +static size_t read_cb_size; /* Size of the buffer. */ +static size_t read_cb_len; /* Used length. */ + + +/* Callback for _gcry_rnd*_gather_random. */ +static void +read_cb (const void *buffer, size_t length, enum random_origins origin) +{ + const unsigned char *p = buffer; + + (void)origin; + + gcry_assert (system_rng_is_locked); + gcry_assert (read_cb_buffer); + + /* Note that we need to protect against gatherers returning more + than the requested bytes (e.g. rndw32). */ + while (length-- && read_cb_len < read_cb_size) + { + read_cb_buffer[read_cb_len++] = *p++; + } +} + + +/* Fill BUFFER with LENGTH bytes of random at quality LEVEL. The + function either succeeds or terminates the process in case of a + fatal error. */ +static void +get_random (void *buffer, size_t length, int level) +{ + int rc; + + gcry_assert (buffer); + + read_cb_buffer = buffer; + read_cb_size = length; + read_cb_len = 0; + +#if USE_RNDLINUX + rc = _gcry_rndlinux_gather_random (read_cb, 0, length, level); +#elif USE_RNDUNIX + rc = _gcry_rndunix_gather_random (read_cb, 0, length, level); +#elif USE_RNDW32 + do + { + rc = _gcry_rndw32_gather_random (read_cb, 0, length, level); + } + while (rc >= 0 && read_cb_len < read_cb_size); +#else + rc = -1; +#endif + + if (rc < 0 || read_cb_len != read_cb_size) + { + log_fatal ("error reading random from system RNG (rc=%d)\n", rc); + } +} + + + +/* --- Public Functions --- */ + +/* Initialize this random subsystem. If FULL is false, this function + merely calls the basic initialization of the module and does not do + anything more. Doing this is not really required but when running + in a threaded environment we might get a race condition + otherwise. */ +void +_gcry_rngsystem_initialize (int full) +{ + basic_initialization (); + if (!full) + return; + /* Nothing more to initialize. */ + return; +} + + +/* Print some statistics about the RNG. */ +void +_gcry_rngsystem_dump_stats (void) +{ + /* Not yet implemented. */ +} + + +/* This function returns true if no real RNG is available or the + quality of the RNG has been degraded for test purposes. */ +int +_gcry_rngsystem_is_faked (void) +{ + return 0; /* Faked random is not supported. */ +} + + +/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY + should be in the range of 0..100 to indicate the goodness of the + entropy added, or -1 for goodness not known. */ +gcry_error_t +_gcry_rngsystem_add_bytes (const void *buf, size_t buflen, int quality) +{ + (void)buf; + (void)buflen; + (void)quality; + return 0; /* Not implemented. */ +} + + +/* Public function to fill the buffer with LENGTH bytes of + cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is + here mapped to GCRY_STRONG_RANDOM, GCRY_STRONG_RANDOM is strong + enough for most usage, GCRY_VERY_STRONG_RANDOM is good for key + generation stuff but may be very slow. */ +void +_gcry_rngsystem_randomize (void *buffer, size_t length, + enum gcry_random_level level) +{ + _gcry_rngsystem_initialize (1); /* Auto-initialize if needed. */ + + if (level != GCRY_VERY_STRONG_RANDOM) + level = GCRY_STRONG_RANDOM; + + lock_rng (); + get_random (buffer, length, level); + unlock_rng (); +} diff --git a/random/random.c b/random/random.c index 9a5b166..e56eb8a 100644 --- a/random/random.c +++ b/random/random.c @@ -43,6 +43,15 @@ static void (*progress_cb) (void *,const char*,int,int, int ); static void *progress_cb_data; +/* Flags indicating the requested RNG types. */ +static struct +{ + int standard; + int fips; + int system; +} rng_types; + + /* This is the lock we use to protect the buffer used by the nonce generation. */ static ath_mutex_t nonce_buffer_lock; @@ -73,6 +82,55 @@ _gcry_random_progress (const char *what, int printchar, int current, int total) } +/* Set the preferred RNG type. This may be called at any time even + before gcry_check_version. Thus we can't assume any thread system + initialization. A type of 0 is used to indicate that any Libgcrypt + initialization has been done.*/ +void +_gcry_set_preferred_rng_type (int type) +{ + static int any_init; + + if (!type) + { + any_init = 1; + } + else if (type == GCRY_RNG_TYPE_STANDARD) + { + rng_types.standard = 1; + } + else if (any_init) + { + /* After any initialization has been done we only allow to + upgrade to the standard RNG (handled above). All other + requests are ignored. The idea is that the application needs + to declare a preference for a weaker RNG as soon as possible + and before any library sets a preference. We assume that a + library which uses Libgcrypt calls an init function very + early. This way --- even if the library gets initialized + early by the application --- it is unlikely that it can + select a lower priority RNG. + + This scheme helps to ensure that existing unmodified + applications (e.g. gpg2), which don't known about the new RNG + selection system, will continue to use the standard RNG and + not be tricked by some library to use a lower priority RNG. + There are some loopholes here but at least most GnuPG stuff + should be save because it calls src_c{gcry_control + (GCRYCTL_SUSPEND_SECMEM_WARN);} quite early and thus inhibits + switching to a low priority RNG. + */ + } + else if (type == GCRY_RNG_TYPE_FIPS) + { + rng_types.fips = 1; + } + else if (type == GCRY_RNG_TYPE_SYSTEM) + { + rng_types.system = 1; + } +} + /* Initialize this random subsystem. If FULL is false, this function merely calls the basic initialization of the module and does not do @@ -96,11 +154,39 @@ _gcry_random_initialize (int full) if (fips_mode ()) _gcry_rngfips_initialize (full); + else if (rng_types.standard) + _gcry_rngcsprng_initialize (full); + else if (rng_types.fips) + _gcry_rngfips_initialize (full); + else if (rng_types.system) + _gcry_rngsystem_initialize (full); else _gcry_rngcsprng_initialize (full); } +/* Return the current RNG type. IGNORE_FIPS_MODE is a flag used to + skip the test for FIPS. This is useful, so that we are able to + return the type of the RNG even before we have setup FIPS mode + (note that FIPS mode is enabled by default until it is switched off + by the initialization). This is mostly useful for the regression + test. */ +int +_gcry_get_rng_type (int ignore_fips_mode) +{ + if (!ignore_fips_mode && fips_mode ()) + return GCRY_RNG_TYPE_FIPS; + else if (rng_types.standard) + return GCRY_RNG_TYPE_STANDARD; + else if (rng_types.fips) + return GCRY_RNG_TYPE_FIPS; + else if (rng_types.system) + return GCRY_RNG_TYPE_SYSTEM; + else + return GCRY_RNG_TYPE_STANDARD; +} + + void _gcry_random_dump_stats (void) { @@ -178,7 +264,13 @@ gcry_random_add_bytes (const void *buf, size_t buflen, int quality) { if (fips_mode ()) return 0; /* No need for this in fips mode. */ - else + else if (rng_types.standard) + return _gcry_rngcsprng_add_bytes (buf, buflen, quality); + else if (rng_types.fips) + return 0; + else if (rng_types.system) + return 0; + else /* default */ return _gcry_rngcsprng_add_bytes (buf, buflen, quality); } @@ -189,7 +281,13 @@ do_randomize (void *buffer, size_t length, enum gcry_random_level level) { if (fips_mode ()) _gcry_rngfips_randomize (buffer, length, level); - else + else if (rng_types.standard) + _gcry_rngcsprng_randomize (buffer, length, level); + else if (rng_types.fips) + _gcry_rngfips_randomize (buffer, length, level); + else if (rng_types.system) + _gcry_rngsystem_randomize (buffer, length, level); + else /* default */ _gcry_rngcsprng_randomize (buffer, length, level); } @@ -244,7 +342,13 @@ _gcry_set_random_seed_file (const char *name) { if (fips_mode ()) ; /* No need for this in fips mode. */ - else + else if (rng_types.standard) + _gcry_rngcsprng_set_seed_file (name); + else if (rng_types.fips) + ; + else if (rng_types.system) + ; + else /* default */ _gcry_rngcsprng_set_seed_file (name); } @@ -256,7 +360,13 @@ _gcry_update_random_seed_file (void) { if (fips_mode ()) ; /* No need for this in fips mode. */ - else + else if (rng_types.standard) + _gcry_rngcsprng_update_seed_file (); + else if (rng_types.fips) + ; + else if (rng_types.system) + ; + else /* default */ _gcry_rngcsprng_update_seed_file (); } @@ -274,7 +384,13 @@ _gcry_fast_random_poll (void) { if (fips_mode ()) ; /* No need for this in fips mode. */ - else + else if (rng_types.standard) + _gcry_rngcsprng_fast_poll (); + else if (rng_types.fips) + ; + else if (rng_types.system) + ; + else /* default */ _gcry_rngcsprng_fast_poll (); } diff --git a/random/random.h b/random/random.h index 5f6a42c..aae07ab 100644 --- a/random/random.h +++ b/random/random.h @@ -26,7 +26,9 @@ void _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int), void *cb_data ); +void _gcry_set_preferred_rng_type (int type); void _gcry_random_initialize (int full); +int _gcry_get_rng_type (int ignore_fips_mode); void _gcry_random_dump_stats(void); void _gcry_secure_random_alloc(void); void _gcry_enable_quick_random_gen (void); diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 4d34567..dae8d1c 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -288,7 +288,9 @@ enum gcry_ctl_cmds GCRYCTL_SELFTEST = 57, /* Note: 58 .. 62 are used internally. */ GCRYCTL_DISABLE_HWF = 63, - GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64 + GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64, + GCRYCTL_SET_PREFERRED_RNG_TYPE = 65, + GCRYCTL_GET_CURRENT_RNG_TYPE = 66 }; /* Perform various operations defined by CMD. */ @@ -1119,6 +1121,14 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, * * ************************************/ +/* The type of the random number generator. */ +enum gcry_rng_types + { + GCRY_RNG_TYPE_STANDARD = 1, /* The default CSPRNG generator. */ + GCRY_RNG_TYPE_FIPS = 2, /* The FIPS X9.31 AES generator. */ + GCRY_RNG_TYPE_SYSTEM = 3 /* The system's native generator. */ + }; + /* The possible values for the random quality. The rule of thumb is to use STRONG for session keys and VERY_STRONG for key material. WEAK is usually an alias for STRONG and should not be used anymore diff --git a/src/global.c b/src/global.c index 4ce869a..f280a7b 100644 --- a/src/global.c +++ b/src/global.c @@ -1,6 +1,7 @@ /* global.c - global control functions * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * 2004, 2005, 2006, 2008, 2011 Free Software Foundation, Inc. + * 2004, 2005, 2006, 2008, 2011, + * 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -101,6 +102,9 @@ global_init (void) return; any_init_done = 1; + /* Tell the random module that we have seen an init call. */ + _gcry_set_preferred_rng_type (0); + /* Initialize our portable thread/mutex wrapper. */ err = ath_init (); if (err) @@ -308,6 +312,21 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp) fnc (fp, "fips-mode:%c:%c:\n", fips_mode ()? 'y':'n', _gcry_enforced_fips_mode ()? 'y':'n' ); + /* The currently used RNG type. */ + { + const char *s; + + i = _gcry_get_rng_type (0); + switch (i) + { + case GCRY_RNG_TYPE_STANDARD: s = "standard"; break; + case GCRY_RNG_TYPE_FIPS: s = "fips"; break; + case GCRY_RNG_TYPE_SYSTEM: s = "system"; break; + default: BUG (); + } + fnc (fp, "rng-type:%s:%d:\n", s, i); + } + } @@ -328,6 +347,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) break; case GCRYCTL_ENABLE_QUICK_RANDOM: + _gcry_set_preferred_rng_type (0); _gcry_enable_quick_random_gen (); break; @@ -373,16 +393,19 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) break; case GCRYCTL_DISABLE_SECMEM_WARN: + _gcry_set_preferred_rng_type (0); _gcry_secmem_set_flags ((_gcry_secmem_get_flags () | GCRY_SECMEM_FLAG_NO_WARNING)); break; case GCRYCTL_SUSPEND_SECMEM_WARN: + _gcry_set_preferred_rng_type (0); _gcry_secmem_set_flags ((_gcry_secmem_get_flags () | GCRY_SECMEM_FLAG_SUSPEND_WARNING)); break; case GCRYCTL_RESUME_SECMEM_WARN: + _gcry_set_preferred_rng_type (0); _gcry_secmem_set_flags ((_gcry_secmem_get_flags () & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING)); break; @@ -393,15 +416,18 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) break; case GCRYCTL_SET_RANDOM_SEED_FILE: + _gcry_set_preferred_rng_type (0); _gcry_set_random_seed_file (va_arg (arg_ptr, const char *)); break; case GCRYCTL_UPDATE_RANDOM_SEED_FILE: + _gcry_set_preferred_rng_type (0); if ( fips_is_operational () ) _gcry_update_random_seed_file (); break; case GCRYCTL_SET_VERBOSITY: + _gcry_set_preferred_rng_type (0); _gcry_set_log_verbosity (va_arg (arg_ptr, int)); break; @@ -447,12 +473,14 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) break; case GCRYCTL_SET_THREAD_CBS: + _gcry_set_preferred_rng_type (0); err = ath_install (va_arg (arg_ptr, void *)); if (!err) global_init (); break; case GCRYCTL_FAST_POLL: + _gcry_set_preferred_rng_type (0); /* We need to do make sure that the random pool is really initialized so that the poll function is not a NOP. */ _gcry_random_initialize (1); @@ -463,6 +491,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) case GCRYCTL_SET_RNDEGD_SOCKET: #if USE_RNDEGD + _gcry_set_preferred_rng_type (0); err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *)); #else err = gpg_error (GPG_ERR_NOT_SUPPORTED); @@ -470,12 +499,14 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) break; case GCRYCTL_SET_RANDOM_DAEMON_SOCKET: + _gcry_set_preferred_rng_type (0); _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *)); break; case GCRYCTL_USE_RANDOM_DAEMON: /* We need to do make sure that the random pool is really initialized so that the poll function is not a NOP. */ + _gcry_set_preferred_rng_type (0); _gcry_random_initialize (1); _gcry_use_random_daemon (!! va_arg (arg_ptr, int)); break; @@ -487,6 +518,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) case GCRYCTL_PRINT_CONFIG: { FILE *fp = va_arg (arg_ptr, FILE *); + _gcry_set_preferred_rng_type (0); print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp); } break; @@ -494,6 +526,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) case GCRYCTL_OPERATIONAL_P: /* Returns true if the library is in an operational state. This is always true for non-fips mode. */ + _gcry_set_preferred_rng_type (0); if (_gcry_fips_test_operational ()) err = GPG_ERR_GENERAL; /* Used as TRUE value */ break; @@ -510,6 +543,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) the library has already been initialized into fips mode, a selftest is triggered. It is not possible to put the libraty into fips mode after having passed the initialization. */ + _gcry_set_preferred_rng_type (0); if (!any_init_done) { /* Not yet intialized at all. Set a flag so that we are put @@ -602,14 +636,34 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) case GCRYCTL_SET_ENFORCED_FIPS_FLAG: if (!any_init_done) { - /* Not yet intialized at all. Set the enforced fips mode flag */ + /* Not yet initialized at all. Set the enforced fips mode flag */ + _gcry_set_preferred_rng_type (0); _gcry_set_enforced_fips_mode (); } else err = GPG_ERR_GENERAL; break; + case GCRYCTL_SET_PREFERRED_RNG_TYPE: + /* This may be called before gcry_check_version. */ + { + int i = va_arg (arg_ptr, int); + /* Note that we may not pass 0 to _gcry_set_preferred_rng_type. */ + if (i > 0) + _gcry_set_preferred_rng_type (i); + } + break; + + case GCRYCTL_GET_CURRENT_RNG_TYPE: + { + int *ip = va_arg (arg_ptr, int*); + if (ip) + *ip = _gcry_get_rng_type (!any_init_done); + } + break; + default: + _gcry_set_preferred_rng_type (0); /* A call to make sure that the dummy code is linked in. */ _gcry_compat_identification (); err = GPG_ERR_INV_OP; diff --git a/tests/benchmark.c b/tests/benchmark.c index 106e01b..61badd5 100644 --- a/tests/benchmark.c +++ b/tests/benchmark.c @@ -1151,6 +1151,23 @@ main( int argc, char **argv ) use_random_daemon = 1; argc--; argv++; } + else if (!strcmp (*argv, "--prefer-standard-rng")) + { + /* This is anyway the default, but we may want to use it for + debugging. */ + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); + argc--; argv++; + } + else if (!strcmp (*argv, "--prefer-fips-rng")) + { + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); + argc--; argv++; + } + else if (!strcmp (*argv, "--prefer-system-rng")) + { + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); + argc--; argv++; + } else if (!strcmp (*argv, "--no-blinding")) { no_blinding = 1; diff --git a/tests/random.c b/tests/random.c index 3e25363..a46d754 100644 --- a/tests/random.c +++ b/tests/random.c @@ -32,7 +32,12 @@ #include "../src/gcrypt.h" +#define PGM "random" + + static int verbose; +static int debug; +static int with_progress; static void die (const char *format, ...) @@ -40,6 +45,7 @@ die (const char *format, ...) va_list arg_ptr; va_start (arg_ptr, format); + fputs ( PGM ": ", stderr); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); @@ -52,6 +58,7 @@ inf (const char *format, ...) va_list arg_ptr; va_start (arg_ptr, format); + fputs ( PGM ": ", stderr); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); } @@ -62,13 +69,25 @@ print_hex (const char *text, const void *buf, size_t n) { const unsigned char *p = buf; - fputs (text, stdout); + inf ("%s", text); for (; n; n--, p++) - printf ("%02X", *p); - putchar ('\n'); + fprintf (stderr, "%02X", *p); + putc ('\n', stderr); +} + + +static void +progress_cb (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + + inf ("progress (%s %c %d %d)\n", what, printchar, current, total); + fflush (stderr); } + static int writen (int fd, const void *buf, size_t nbytes) { @@ -251,34 +270,270 @@ check_nonce_forking (void) } +static int +rng_type (void) +{ + int rngtype; + if (gcry_control (GCRYCTL_GET_CURRENT_RNG_TYPE, &rngtype)) + die ("retrieving RNG type failed\n"); + return rngtype; +} + + +static void +check_rng_type_switching (void) +{ + int rngtype, initial; + char tmp1[4]; + + if (verbose) + inf ("checking whether RNG type switching works\n"); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + initial = rngtype; + gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); + if (debug) + print_hex (" sample: ", tmp1, sizeof tmp1); + if (rngtype != rng_type ()) + die ("RNG type unexpectedly changed\n"); + + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + if (rngtype != initial) + die ("switching to System RNG unexpectedly succeeded\n"); + gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); + if (debug) + print_hex (" sample: ", tmp1, sizeof tmp1); + if (rngtype != rng_type ()) + die ("RNG type unexpectedly changed\n"); + + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + if (rngtype != initial) + die ("switching to FIPS RNG unexpectedly succeeded\n"); + gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); + if (debug) + print_hex (" sample: ", tmp1, sizeof tmp1); + if (rngtype != rng_type ()) + die ("RNG type unexpectedly changed\n"); + + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + if (rngtype != GCRY_RNG_TYPE_STANDARD) + die ("switching to standard RNG failed\n"); + gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); + if (debug) + print_hex (" sample: ", tmp1, sizeof tmp1); + if (rngtype != rng_type ()) + die ("RNG type unexpectedly changed\n"); +} + + +static void +check_early_rng_type_switching (void) +{ + int rngtype, initial; + + if (verbose) + inf ("checking whether RNG type switching works in the early stage\n"); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + initial = rngtype; + + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + if (initial >= GCRY_RNG_TYPE_SYSTEM && rngtype != GCRY_RNG_TYPE_SYSTEM) + die ("switching to System RNG failed\n"); + + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + if (initial >= GCRY_RNG_TYPE_FIPS && rngtype != GCRY_RNG_TYPE_FIPS) + die ("switching to FIPS RNG failed\n"); + + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); + + rngtype = rng_type (); + if (debug) + inf ("rng type: %d\n", rngtype); + if (rngtype != GCRY_RNG_TYPE_STANDARD) + die ("switching to standard RNG failed\n"); +} +/* Because we want to check initialization behaviour, we need to + fork/exec this program with several command line arguments. We use + system, so that these tests work also on Windows. */ +static void +run_all_rng_tests (const char *program) +{ + static const char *options[] = { + "--early-rng-check", + "--early-rng-check --prefer-standard-rng", + "--early-rng-check --prefer-fips-rng", + "--early-rng-check --prefer-system-rng", + "--prefer-standard-rng", + "--prefer-fips-rng", + "--prefer-system-rng", + NULL + }; + int idx; + size_t len, maxlen; + char *cmdline; + + maxlen = 0; + for (idx=0; options[idx]; idx++) + { + len = strlen (options[idx]); + if (len > maxlen) + maxlen = len; + } + maxlen += strlen (program); + maxlen += strlen (" --in-recursion --verbose --debug --progress"); + maxlen++; + cmdline = malloc (maxlen + 1); + if (!cmdline) + die ("out of core\n"); + + for (idx=0; options[idx]; idx++) + { + if (verbose) + inf ("now running with options '%s'\n", options[idx]); + strcpy (cmdline, program); + strcat (cmdline, " --in-recursion"); + if (verbose) + strcat (cmdline, " --verbose"); + if (debug) + strcat (cmdline, " --debug"); + if (with_progress) + strcat (cmdline, " --progress"); + strcat (cmdline, " "); + strcat (cmdline, options[idx]); + if (system (cmdline)) + die ("running '%s' failed\n", cmdline); + } + free (cmdline); +} int main (int argc, char **argv) { - int debug = 0; + int last_argc = -1; + int early_rng = 0; + int in_recursion = 0; + const char *program = NULL; + + if (argc) + { + program = *argv; + argc--; argv++; + } + else + die ("argv[0] missing\n"); - if ((argc > 1) && (! strcmp (argv[1], "--verbose"))) - verbose = 1; - else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) - verbose = debug = 1; + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + fputs ("usage: random [options]\n", stdout); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + debug = verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--progress")) + { + argc--; argv++; + with_progress = 1; + } + else if (!strcmp (*argv, "--in-recursion")) + { + in_recursion = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--early-rng-check")) + { + early_rng = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--prefer-standard-rng")) + { + /* This is anyway the default, but we may want to use it for + debugging. */ + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); + argc--; argv++; + } + else if (!strcmp (*argv, "--prefer-fips-rng")) + { + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); + argc--; argv++; + } + else if (!strcmp (*argv, "--prefer-system-rng")) + { + gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); + argc--; argv++; + } + } #ifndef HAVE_W32_SYSTEM signal (SIGPIPE, SIG_IGN); #endif + if (early_rng) + check_early_rng_type_switching (); + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); + if (with_progress) + gcry_set_progress_handler (progress_cb, NULL); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); - check_forking (); - check_nonce_forking (); + if (!in_recursion) + { + check_forking (); + check_nonce_forking (); + } + check_rng_type_switching (); + + if (!in_recursion) + run_all_rng_tests (program); return 0; } commit f17e4d920c8a18007a98830dd13163ff19616202 Author: Werner Koch Date: Mon Dec 3 20:17:48 2012 +0100 Update the copyright years. -- diff --git a/README b/README index bbbd0db..1778951 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ !!! THIS IS A DEVELOPMENT VERSION VERSION !!! Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009, - 2011 Free Software Foundation, Inc. + 2011, 2012 Free Software Foundation, Inc. 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/compat/compat.c b/compat/compat.c index e2a0393..96889d3 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -29,7 +29,7 @@ _gcry_compat_identification (void) "\n\n" "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n" "Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,\n" - " 2010, 2011 Free Software Foundation, Inc.\n" + " 2010, 2011, 2012 Free Software Foundation, Inc.\n" "\n\n"; return blurb; } diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 3bd2686..66a05d5 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -12,7 +12,8 @@ This manual is for Libgcrypt (version @value{VERSION}, @value{UPDATED}), which is GNU's library of cryptographic building blocks. -Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. +Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, +2011, 2012 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 1e9d11d..4d34567 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1,23 +1,25 @@ /* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 - 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. - - 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 . - - File: @configure_input@ */ + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, + * 2006, 2007, 2008, 2009, 2010, 2011, + * 2012 Free Software Foundation, Inc. + * + * 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 . + * + * File: @configure_input@ + */ #ifndef _GCRYPT_H #define _GCRYPT_H commit 76c622e24a07f7c826812be173aa173b4334776b Author: Werner Koch Date: Mon Dec 3 16:18:56 2012 +0100 tests: Allow use of random.c under Windows. * tests/Makefile.am (TESTS): Always include random.c * tests/random.c [!W32]: Include sys/wait.h. (inf): New. (check_forking, check_nonce_forking): Print a notice what will be done. (main) [W32]: Do not call signal. -- This change help to run future tests under Windows. The current two tests are not applicable to Windows. diff --git a/tests/Makefile.am b/tests/Makefile.am index f1f9e6f..d337840 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -20,14 +20,9 @@ TESTS = version t-mpi-bit prime basic \ mpitests tsexp keygen pubkey hmac keygrip fips186-dsa aeswrap \ - curves t-kdf pkcs1v2 + curves t-kdf pkcs1v2 random -# random.c uses fork() thus a test for W32 does not make any sense. -if !HAVE_W32_SYSTEM -TESTS += random -endif - # The last test to run. TESTS += benchmark diff --git a/tests/random.c b/tests/random.c index a243529..3e25363 100644 --- a/tests/random.c +++ b/tests/random.c @@ -24,9 +24,11 @@ #include #include #include -#include -#include -#include +#ifndef HAVE_W32_SYSTEM +# include +# include +# include +#endif #include "../src/gcrypt.h" @@ -45,6 +47,17 @@ die (const char *format, ...) static void +inf (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + + +static void print_hex (const char *text, const void *buf, size_t n) { const unsigned char *p = buf; @@ -111,12 +124,19 @@ readn (int fd, void *buf, size_t buflen, size_t *ret_nread) static void check_forking (void) { +#ifdef HAVE_W32_SYSTEM + if (verbose) + inf ("check_forking skipped: not applicable on Windows\n"); +#else /*!HAVE_W32_SYSTEM*/ pid_t pid; int rp[2]; int i, status; size_t nread; char tmp1[16], tmp1c[16], tmp1p[16]; + if (verbose) + inf ("checking that a fork won't cause the same random output\n"); + /* We better make sure that the RNG has been initialzied. */ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); if (verbose) @@ -160,6 +180,7 @@ check_forking (void) if (!memcmp (tmp1p, tmp1c, sizeof tmp1c)) die ("parent and child got the same random number\n"); +#endif /*!HAVE_W32_SYSTEM*/ } @@ -168,12 +189,19 @@ check_forking (void) static void check_nonce_forking (void) { +#ifdef HAVE_W32_SYSTEM + if (verbose) + inf ("check_nonce_forking skipped: not applicable on Windows\n"); +#else /*!HAVE_W32_SYSTEM*/ pid_t pid; int rp[2]; int i, status; size_t nread; char nonce1[10], nonce1c[10], nonce1p[10]; + if (verbose) + inf ("checking that a fork won't cause the same nonce output\n"); + /* We won't get the same nonce back if we never initialized the nonce subsystem, thus we get one nonce here and forget about it. */ @@ -219,6 +247,7 @@ check_nonce_forking (void) if (!memcmp (nonce1p, nonce1c, sizeof nonce1c)) die ("parent and child got the same nonce\n"); +#endif /*!HAVE_W32_SYSTEM*/ } @@ -236,7 +265,9 @@ main (int argc, char **argv) else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) verbose = debug = 1; +#ifndef HAVE_W32_SYSTEM signal (SIGPIPE, SIG_IGN); +#endif gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version (GCRYPT_VERSION)) commit 75760021b511ba438606af746431223357e7a155 Author: Werner Koch Date: Mon Dec 3 15:15:49 2012 +0100 Make random-fips.c work multi-threaded. * random/random-fips.c (basic_initialization): Fix reversed logic. -- The module never initialized the mutex at all. Probably this was never an issue before commit 38fcd59 which removed static lock init. diff --git a/random/random-fips.c b/random/random-fips.c index e0ae968..7f205d2 100644 --- a/random/random-fips.c +++ b/random/random-fips.c @@ -192,7 +192,7 @@ basic_initialization (void) static int initialized; int my_errno; - if (!initialized) + if (initialized) return; initialized = 1; commit c324644aa14e54fc7051983b38222db32b8ab227 Author: Werner Koch Date: Fri Nov 30 18:16:34 2012 +0100 Move nonce creation from csprng backend to random main module. * random/random-csprng.c (_gcry_rngcsprng_create_nonce): Remove. (nonce_buffer_lock): Remove. (initialize_basics): Remove init of nonce_buffer_lock. * random/random.c: Add a few header files. (nonce_buffer_lock): New. (_gcry_random_initialize): Init nonce_buffer_lock. (gcry_create_nonce): Add code from _gcry_rngcsprng_create_nonce. * random/random-daemon.c (_gcry_daemon_create_nonce): Remove. -- The nonce generation code is useful for all RNG types and thus it should be in random.c. The only exception is the fips-mode, which requires the use of the fips nonce generator. diff --git a/random/rand-internal.h b/random/rand-internal.h index a04a2d4..a72d88c 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -61,18 +61,13 @@ void _gcry_rngcsprng_randomize (void *buffer, size_t length, void _gcry_rngcsprng_set_seed_file (const char *name); void _gcry_rngcsprng_update_seed_file (void); void _gcry_rngcsprng_fast_poll (void); -void _gcry_rngcsprng_create_nonce (void *buffer, size_t length); -/*-- random-rngcsprng.c --*/ +/*-- random-fips.c --*/ void _gcry_rngfips_initialize (int full); 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_get_bytes (size_t nbytes, - enum gcry_random_level level); -void *_gcry_rngfips_get_bytes_secure (size_t nbytes, - enum gcry_random_level level); void _gcry_rngfips_randomize (void *buffer, size_t length, enum gcry_random_level level); void _gcry_rngfips_create_nonce (void *buffer, size_t length); diff --git a/random/random-csprng.c b/random/random-csprng.c index 50357d1..9921c4f 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -1,6 +1,6 @@ /* random-csprng.c - CSPRNG style random number generator (libgcrypt classic) * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2010 Free Software Foundation, Inc. + * 2007, 2008, 2010, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -189,10 +189,6 @@ static ath_mutex_t pool_lock; test suite. */ static int pool_is_locked; -/* This is the lock we use to protect the buffer used by the nonce - generation. */ -static ath_mutex_t nonce_buffer_lock; - /* We keep some counters in this structure for the sake of the _gcry_random_dump_stats () function. */ @@ -272,11 +268,6 @@ initialize_basics(void) if (err) log_fatal ("failed to create the pool lock: %s\n", strerror (err) ); - err = ath_mutex_init (&nonce_buffer_lock); - if (err) - log_fatal ("failed to create the nonce buffer lock: %s\n", - strerror (err) ); - #ifdef USE_RANDOM_DAEMON _gcry_daemon_initialize_basics (); #endif /*USE_RANDOM_DAEMON*/ @@ -1320,89 +1311,3 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins), gcry_free (buffer); return 0; /* okay */ } - - -/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ -void -_gcry_rngcsprng_create_nonce (void *buffer, size_t length) -{ - static unsigned char nonce_buffer[20+8]; - static int nonce_buffer_initialized = 0; - static volatile pid_t my_pid; /* The volatile is there to make sure the - compiler does not optimize the code away - in case the getpid function is badly - attributed. */ - volatile pid_t apid; - unsigned char *p; - size_t n; - int err; - - /* Make sure we are initialized. */ - initialize (); - -#ifdef USE_RANDOM_DAEMON - if (allow_daemon - && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length)) - return; /* The daemon succeeded. */ - allow_daemon = 0; /* Daemon failed - switch off. */ -#endif /*USE_RANDOM_DAEMON*/ - - /* Acquire the nonce buffer lock. */ - err = ath_mutex_lock (&nonce_buffer_lock); - if (err) - log_fatal ("failed to acquire the nonce buffer lock: %s\n", - strerror (err)); - - apid = getpid (); - /* The first time initialize our buffer. */ - if (!nonce_buffer_initialized) - { - time_t atime = time (NULL); - pid_t xpid = apid; - - my_pid = apid; - - if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) - BUG (); - - /* Initialize the first 20 bytes with a reasonable value so that - a failure of gcry_randomize won't affect us too much. Don't - care about the uninitialized remaining bytes. */ - p = nonce_buffer; - memcpy (p, &xpid, sizeof xpid); - p += sizeof xpid; - memcpy (p, &atime, sizeof atime); - - /* Initialize the never changing private part of 64 bits. */ - gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); - - nonce_buffer_initialized = 1; - } - else if ( my_pid != apid ) - { - /* We forked. Need to reseed the buffer - doing this for the - private part should be sufficient. */ - gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); - /* Update the pid so that we won't run into here again and - again. */ - my_pid = apid; - } - - /* Create the nonce by hashing the entire buffer, returning the hash - and updating the first 20 bytes of the buffer with this hash. */ - for (p = buffer; length > 0; length -= n, p += n) - { - _gcry_sha1_hash_buffer (nonce_buffer, - nonce_buffer, sizeof nonce_buffer); - n = length > 20? 20 : length; - memcpy (p, nonce_buffer, n); - } - - - /* Release the nonce buffer lock. */ - err = ath_mutex_unlock (&nonce_buffer_lock); - if (err) - log_fatal ("failed to release the nonce buffer lock: %s\n", - strerror (err)); - -} diff --git a/random/random-daemon.c b/random/random-daemon.c index 9422e85..26d77f8 100644 --- a/random/random-daemon.c +++ b/random/random-daemon.c @@ -345,17 +345,4 @@ _gcry_daemon_randomize (const char *socketname, return err ? -1 : 0; } - -/* Internal function to fill BUFFER with NBYTES of data usable for a - nonce. Returns 0 on success. */ -int -_gcry_daemon_create_nonce (const char *socketname, void *buffer, size_t length) -{ - gcry_error_t err; - - err = call_daemon (socketname, buffer, length, 1, 0); - - return err ? -1 : 0; -} - /* END */ diff --git a/random/random.c b/random/random.c index 40661ab..9a5b166 100644 --- a/random/random.c +++ b/random/random.c @@ -1,5 +1,5 @@ /* random.c - Random number switch - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2003, 2006, 2008, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -26,10 +26,14 @@ #include #include #include +#include +#include +#include #include "g10lib.h" #include "random.h" #include "rand-internal.h" +#include "cipher.h" /* For _gcry_sha1_hash_buffer(). */ #include "ath.h" @@ -39,6 +43,9 @@ static void (*progress_cb) (void *,const char*,int,int, int ); static void *progress_cb_data; +/* This is the lock we use to protect the buffer used by the nonce + generation. */ +static ath_mutex_t nonce_buffer_lock; @@ -75,6 +82,18 @@ _gcry_random_progress (const char *what, int printchar, int current, int total) void _gcry_random_initialize (int full) { + static int nonce_initialized; + int err; + + if (!nonce_initialized) + { + nonce_initialized = 1; + err = ath_mutex_init (&nonce_buffer_lock); + if (err) + log_fatal ("failed to create the nonce buffer lock: %s\n", + strerror (err) ); + } + if (fips_mode ()) _gcry_rngfips_initialize (full); else @@ -265,10 +284,90 @@ _gcry_fast_random_poll (void) void gcry_create_nonce (void *buffer, size_t length) { + static unsigned char nonce_buffer[20+8]; + static int nonce_buffer_initialized = 0; + static volatile pid_t my_pid; /* The volatile is there to make sure the + compiler does not optimize the code away + in case the getpid function is badly + attributed. */ + volatile pid_t apid; + unsigned char *p; + size_t n; + int err; + + /* First check whether we shall use the FIPS nonce generator. This + is only done in FIPS mode, in all other modes, we use our own + nonce generator which is seeded by the RNG actual in use. */ if (fips_mode ()) - _gcry_rngfips_create_nonce (buffer, length); - else - _gcry_rngcsprng_create_nonce (buffer, length); + { + _gcry_rngfips_create_nonce (buffer, length); + return; + } + + /* This is the nonce generator, which formerly lived in + random-csprng.c. It is now used by all RNG types except when in + FIPS mode (not that this means it is also used if the FIPS RNG + has been selected but we are not in fips mode). */ + + /* Make sure we are initialized. */ + _gcry_random_initialize (1); + + /* Acquire the nonce buffer lock. */ + err = ath_mutex_lock (&nonce_buffer_lock); + if (err) + log_fatal ("failed to acquire the nonce buffer lock: %s\n", + strerror (err)); + + apid = getpid (); + /* The first time initialize our buffer. */ + if (!nonce_buffer_initialized) + { + time_t atime = time (NULL); + pid_t xpid = apid; + + my_pid = apid; + + if ((sizeof apid + sizeof atime) > sizeof nonce_buffer) + BUG (); + + /* Initialize the first 20 bytes with a reasonable value so that + a failure of gcry_randomize won't affect us too much. Don't + care about the uninitialized remaining bytes. */ + p = nonce_buffer; + memcpy (p, &xpid, sizeof xpid); + p += sizeof xpid; + memcpy (p, &atime, sizeof atime); + + /* Initialize the never changing private part of 64 bits. */ + gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); + + nonce_buffer_initialized = 1; + } + else if ( my_pid != apid ) + { + /* We forked. Need to reseed the buffer - doing this for the + private part should be sufficient. */ + do_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM); + /* Update the pid so that we won't run into here again and + again. */ + my_pid = apid; + } + + /* Create the nonce by hashing the entire buffer, returning the hash + and updating the first 20 bytes of the buffer with this hash. */ + for (p = buffer; length > 0; length -= n, p += n) + { + _gcry_sha1_hash_buffer (nonce_buffer, + nonce_buffer, sizeof nonce_buffer); + n = length > 20? 20 : length; + memcpy (p, nonce_buffer, n); + } + + /* Release the nonce buffer lock. */ + err = ath_mutex_unlock (&nonce_buffer_lock); + if (err) + log_fatal ("failed to release the nonce buffer lock: %s\n", + strerror (err)); } diff --git a/random/random.h b/random/random.h index 7a9585c..5f6a42c 100644 --- a/random/random.h +++ b/random/random.h @@ -61,8 +61,6 @@ void _gcry_daemon_initialize_basics (void); int _gcry_daemon_randomize (const char *socketname, void *buffer, size_t length, enum gcry_random_level level); -int _gcry_daemon_create_nonce (const char *socketname, - void *buffer, size_t length); #endif /*USE_RANDOM_DAEMON*/ #endif /*G10_RANDOM_H*/ ----------------------------------------------------------------------- Summary of changes: NEWS | 10 ++- README | 2 +- compat/compat.c | 2 +- doc/gcrypt.texi | 34 +++++- random/Makefile.am | 1 + random/rand-internal.h | 15 ++- random/random-csprng.c | 97 +--------------- random/random-daemon.c | 13 -- random/random-fips.c | 2 +- random/random-system.c | 243 +++++++++++++++++++++++++++++++++++++ random/random.c | 233 ++++++++++++++++++++++++++++++++++-- random/random.h | 4 +- src/gcrypt.h.in | 52 +++++--- src/global.c | 58 +++++++++- tests/Makefile.am | 7 +- tests/benchmark.c | 17 +++ tests/random.c | 312 ++++++++++++++++++++++++++++++++++++++++++++++-- 17 files changed, 930 insertions(+), 172 deletions(-) create mode 100644 random/random-system.c hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 4 12:19:35 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 04 Dec 2012 12:19:35 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-106-g1e1326a 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 1e1326aeb8923782138e133f091afec41d969c40 (commit) via baf7b09e124f9eb4ca4b8ee02474ee7710a95a40 (commit) from b8eb2ab56971a309353ae2682bc6ef1357e9ac53 (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 1e1326aeb8923782138e133f091afec41d969c40 Author: NIIBE Yutaka Date: Tue Dec 4 14:37:56 2012 +0900 Revert SCD changes of 2010-05-03. * scd/apdu.c (pcsc_no_service): Remove. (open_pcsc_reader_direct, open_pcsc_reader_wrapped): Remove pcsc_no_service support. (apdu_open_reader): Remove R_NO_SERVICE. * scd/apdu.h (apdu_open_reader): Remove R_NO_SERVICE. * scd/command.c (reader_disabled): Remove. (get_current_reader): Follow the change of R_NO_SERVICE. (open_card, cmd_serialno, scd_command_handler): Remove reader_disabled support. * scd/sc-copykeys.c (main): Follow the change of R_NO_SERVICE. -- Daemon should handle all possible cases. Even if such a difficult case like reader_disabled, it should not exit. diff --git a/scd/apdu.c b/scd/apdu.c index 43c807e..68d4e99 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -323,9 +323,6 @@ long (* DLSTDCALL pcsc_control) (unsigned long card, unsigned long recv_len, unsigned long *bytes_returned); -/* Flag set if PC/SC returned the no-service error. */ -static int pcsc_no_service; - /* Prototypes. */ static int pcsc_get_status (int slot, unsigned int *status); @@ -1693,11 +1690,8 @@ open_pcsc_reader_direct (const char *portstr) log_error ("pcsc_establish_context failed: %s (0x%lx)\n", pcsc_error_string (err), err); reader_table[slot].used = 0; - if (err == PCSC_E_NO_SERVICE) - pcsc_no_service = 1; return -1; } - pcsc_no_service = 0; err = pcsc_list_readers (reader_table[slot].pcsc.context, NULL, NULL, &nreader); @@ -1796,7 +1790,6 @@ open_pcsc_reader_wrapped (const char *portstr) { log_error ("can't run PC/SC access module '%s': %s\n", wrapperpgm, strerror (errno)); - pcsc_no_service = 1; return -1; } @@ -1893,8 +1886,6 @@ open_pcsc_reader_wrapped (const char *portstr) ; #undef WAIT - pcsc_no_service = 1; - /* Now send the open request. */ msgbuf[0] = 0x01; /* OPEN command. */ len = portstr? strlen (portstr):0; @@ -1927,15 +1918,11 @@ open_pcsc_reader_wrapped (const char *portstr) { log_error ("PC/SC returned a too large ATR (len=%lx)\n", (unsigned long)len); - pcsc_no_service = 0; goto command_failed; } err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]); - if (err != PCSC_E_NO_SERVICE) - pcsc_no_service = 0; - if (err) { log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); @@ -2817,7 +2804,7 @@ unlock_slot (int slot) error. If PORTSTR is NULL we default to a suitable port (for ctAPI: the first USB reader. For PC/SC the first listed reader). */ int -apdu_open_reader (const char *portstr, int *r_no_service) +apdu_open_reader (const char *portstr) { static int pcsc_api_loaded, ct_api_loaded; int slot; @@ -2825,9 +2812,6 @@ apdu_open_reader (const char *portstr, int *r_no_service) if (DBG_READER) log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr); - if (r_no_service) - *r_no_service = 0; - #ifdef HAVE_LIBUSB if (!opt.disable_ccid) { @@ -2988,8 +2972,6 @@ apdu_open_reader (const char *portstr, int *r_no_service) } slot = open_pcsc_reader (portstr); - if (slot == -1 && r_no_service && pcsc_no_service) - *r_no_service = 1; if (DBG_READER) log_debug ("leave: apdu_open_reader => slot=%d [pc/sc]\n", slot); diff --git a/scd/apdu.h b/scd/apdu.h index 7502546..bf55346 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -84,7 +84,7 @@ enum { /* Note, that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (const char *portstr, int *r_no_service); +int apdu_open_reader (const char *portstr); int apdu_open_remote_reader (const char *portstr, const unsigned char *cookie, size_t length, int (*readfnc) (void *opaque, diff --git a/scd/command.c b/scd/command.c index 932db6c..40e61a4 100644 --- a/scd/command.c +++ b/scd/command.c @@ -79,10 +79,6 @@ == locked_session->ctrl_backlink->server_local->vreader_idx)) -/* Flag indicating that the reader has been disabled. */ -static int reader_disabled; - - /* This structure is used to keep track of user readers. To eventually accommodate this structure for RFID cards, where more than one card is used per reader, we name it virtual reader. */ @@ -444,9 +440,7 @@ get_current_reader (void) /* Try to open the reader. */ if (vr->slot == -1) { - int no_service_flag; - - vr->slot = apdu_open_reader (opt.reader_port, &no_service_flag); + vr->slot = apdu_open_reader (opt.reader_port); /* If we still don't have a slot, we have no readers. Invalidate for now until a reader is attached. */ @@ -454,12 +448,6 @@ get_current_reader (void) { vr->valid = 0; } - - if (no_service_flag) - { - log_info ("no card services - disabling scdaemon\n"); - reader_disabled = 1; - } } /* Return the vreader index or -1. */ @@ -474,9 +462,6 @@ open_card (ctrl_t ctrl, const char *apptype) gpg_error_t err; int vrdr; - if (reader_disabled) - return gpg_error (GPG_ERR_NOT_OPERATIONAL); - /* If we ever got a card not present error code, return that. Only the SERIALNO command and a reset are able to clear from that state. */ @@ -512,7 +497,7 @@ open_card (ctrl_t ctrl, const char *apptype) vrdr = get_current_reader (); ctrl->server_local->vreader_idx = vrdr; if (vrdr == -1) - err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD); + err = gpg_error (GPG_ERR_CARD); else { /* Fixme: We should move the apdu_connect call to @@ -570,7 +555,7 @@ cmd_serialno (assuan_context_t ctx, char *line) /* Clear the remove flag so that the open_card is able to reread it. */ retry: - if (!reader_disabled && ctrl->server_local->card_removed) + if (ctrl->server_local->card_removed) { if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); @@ -2122,7 +2107,7 @@ scd_command_handler (ctrl_t ctrl, int fd) BUG (); sl->next_session = ctrl->server_local->next_session; } - stopme = ctrl->server_local->stopme || reader_disabled; + stopme = ctrl->server_local->stopme; xfree (ctrl->server_local); ctrl->server_local = NULL; diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c index 0056dd7..3f34d69 100644 --- a/scd/sc-copykeys.c +++ b/scd/sc-copykeys.c @@ -139,7 +139,7 @@ main (int argc, char **argv ) if (argc != 1) usage (1); - slot = apdu_open_reader (reader_port, NULL); + slot = apdu_open_reader (reader_port); if (slot == -1) exit (1); if (apdu_connect (slot)) commit baf7b09e124f9eb4ca4b8ee02474ee7710a95a40 Author: NIIBE Yutaka Date: Thu Nov 22 16:04:51 2012 +0900 Don't keep opening unavailable card reader. * scd/command.c (update_reader_status_file): Don't call get_current_reader. -- This fix has a impact that the insertion of a card reader will not be detected upon the insertion, but will be deferred until user tries to access his card. diff --git a/scd/command.c b/scd/command.c index 17da5b7..932db6c 100644 --- a/scd/command.c +++ b/scd/command.c @@ -2282,11 +2282,6 @@ update_reader_status_file (int set_card_removed_flag) int idx; unsigned int status, changed; - /* Make sure that a reader has been opened. Like get_current_reader, - this part of the code assumes that there is only one reader. */ - if (!vreader_table[0].valid) - (void)get_current_reader (); - /* Note, that we only try to get the status, because it does not make sense to wait here for a operation to complete. If we are busy working with a card, delays in the status file update should ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 20 +------------------- scd/apdu.h | 2 +- scd/command.c | 28 ++++------------------------ scd/sc-copykeys.c | 2 +- 4 files changed, 7 insertions(+), 45 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 5 14:30:32 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 05 Dec 2012 14:30:32 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-77-g6d20c1f 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 6d20c1fab7f6005b34103de40c9707411b047f07 (commit) from 7607ab81504ce44060ed0b331d309606f5da1e75 (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 6d20c1fab7f6005b34103de40c9707411b047f07 Author: Werner Koch Date: Wed Dec 5 12:59:45 2012 +0100 Update AUTHORS file. -- diff --git a/AUTHORS b/AUTHORS index 3aa54f9..8f385f8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,13 +10,14 @@ Libgcrypt used to be part of GnuPG but has been taken out into its own package on 2000-12-21. -Authors of Libgcrypt -==================== +Authors with a FSF copyright assignment +======================================= -GNUPG Werner Koch 1998-02-23 -Assigns GNU Privacy Guard and future changes. +LIBGCRYPT Werner Koch 2001-06-07 +Assigns past and future changes. +Assignment for future changes terminated on 2012-12-04. wk at gnupg.org -Designed and implemented GnuPG. +Designed and implemented Libgcrypt. GNUPG Matthew Skala 1998-08-10 Disclaims changes. @@ -43,6 +44,7 @@ g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c) rguyom at mail.dotcom.fr ANY g10 Code GmbH 2001-06-07 +Assignment for future changes terminated on 2012-12-04. Code marked with ChangeLog entries of g10 Code employees. LIBGCRYPT Timo Schulz 2001-08-31 @@ -108,6 +110,7 @@ Authors with a DCO DCO:2012-04-16:Tom?? Mr?z DCO:2012-04-20:Rafa?l Carr? DCO:2012-11-14:Jussi Kivilinna +DCO:2012-12-05:Werner Koch More credits ----------------------------------------------------------------------- Summary of changes: AUTHORS | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Dec 7 03:26:28 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 07 Dec 2012 03:26:28 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-44-g0d7cf7b 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 0d7cf7bb0669ca280e6259a9c34612a8ff56acda (commit) via 9afd2bb7fb9067eb8c753a5e5f672a36e93b2474 (commit) from 2ee9fe4bc25df7966df759895b996206d3cf7a02 (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 0d7cf7bb0669ca280e6259a9c34612a8ff56acda Author: NIIBE Yutaka Date: Fri Dec 7 10:31:37 2012 +0900 Revert SCD changes of 2010-05-03 (scd/ChangeLog 2010-03-17). * scd/apdu.c (pcsc_no_service): Remove. (open_pcsc_reader_direct, open_pcsc_reader_wrapped): Remove pcsc_no_service support. (apdu_open_reader): Remove R_NO_SERVICE. * scd/apdu.h (apdu_open_reader): Remove R_NO_SERVICE. * scd/command.c (reader_disabled): Remove. (get_reader_slot): Follow the change of R_NO_SERVICE. (open_card, cmd_serialno, scd_command_handler): Remove reader_disabled support. * scd/sc-copykeys.c (main): Follow the change of R_NO_SERVICE. -- Daemon should handle all possible cases. Even if such a difficult case like reader_disabled, it should not exit. diff --git a/scd/apdu.c b/scd/apdu.c index b369a26..962eb71 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -305,9 +305,6 @@ long (* DLSTDCALL pcsc_control) (unsigned long card, unsigned long recv_len, unsigned long *bytes_returned); -/* Flag set if PC/SC returned the no-service error. */ -static int pcsc_no_service; - /* Prototypes. */ static int pcsc_get_status (int slot, unsigned int *status); @@ -1712,11 +1709,8 @@ open_pcsc_reader_direct (const char *portstr) pcsc_error_string (err), err); reader_table[slot].used = 0; unlock_slot (slot); - if (err == PCSC_E_NO_SERVICE) - pcsc_no_service = 1; return -1; } - pcsc_no_service = 0; err = pcsc_list_readers (reader_table[slot].pcsc.context, NULL, NULL, &nreader); @@ -1820,7 +1814,6 @@ open_pcsc_reader_wrapped (const char *portstr) { log_error ("can't run PC/SC access module `%s': %s\n", wrapperpgm, strerror (errno)); - pcsc_no_service = 1; return -1; } @@ -1920,8 +1913,6 @@ open_pcsc_reader_wrapped (const char *portstr) ; #undef WAIT - pcsc_no_service = 1; - /* Now send the open request. */ msgbuf[0] = 0x01; /* OPEN command. */ len = portstr? strlen (portstr):0; @@ -1954,15 +1945,11 @@ open_pcsc_reader_wrapped (const char *portstr) { log_error ("PC/SC returned a too large ATR (len=%lx)\n", (unsigned long)len); - pcsc_no_service = 0; goto command_failed; } err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]); - if (err != PCSC_E_NO_SERVICE) - pcsc_no_service = 0; - if (err) { log_error ("PC/SC OPEN failed: %s (0x%08x)\n", @@ -2803,18 +2790,14 @@ open_rapdu_reader (int portno, error. If PORTSTR is NULL we default to a suitable port (for ctAPI: the first USB reader. For PC/SC the first listed reader). */ int -apdu_open_reader (const char *portstr, int *r_no_service) +apdu_open_reader (const char *portstr) { static int pcsc_api_loaded, ct_api_loaded; - int slot; - - if (r_no_service) - *r_no_service = 0; #ifdef HAVE_LIBUSB if (!opt.disable_ccid) { - int i; + int slot, i; const char *s; slot = open_ccid_reader (portstr); @@ -2947,11 +2930,7 @@ apdu_open_reader (const char *portstr, int *r_no_service) pcsc_api_loaded = 1; } - slot = open_pcsc_reader (portstr); - if (slot == -1 && r_no_service && pcsc_no_service) - *r_no_service = 1; - - return slot; + return open_pcsc_reader (portstr); } diff --git a/scd/apdu.h b/scd/apdu.h index 94d7449..61501c4 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -81,7 +81,7 @@ enum { /* Note, that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (const char *portstr, int *r_no_service); +int apdu_open_reader (const char *portstr); int apdu_open_remote_reader (const char *portstr, const unsigned char *cookie, size_t length, int (*readfnc) (void *opaque, diff --git a/scd/command.c b/scd/command.c index da11e88..2123b9d 100644 --- a/scd/command.c +++ b/scd/command.c @@ -74,10 +74,6 @@ && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot) -/* Flag indicating that the reader has been disabled. */ -static int reader_disabled; - - /* This structure is used to keep track of open readers (slots). */ struct slot_status_s { @@ -414,14 +410,7 @@ get_reader_slot (void) /* Try to open the reader. */ if (ss->slot == -1) { - int no_service_flag; - ss->slot = apdu_open_reader (opt.reader_port, &no_service_flag); - - if (no_service_flag) - { - log_info ("no card services - disabling scdaemon\n"); - reader_disabled = 1; - } + ss->slot = apdu_open_reader (opt.reader_port); /* If we still don't have a slot, we have no readers. Invalidate for now until a reader is attached. */ @@ -444,9 +433,6 @@ open_card (ctrl_t ctrl, const char *apptype) gpg_error_t err; int slot; - if (reader_disabled) - return gpg_error (GPG_ERR_NOT_OPERATIONAL); - /* If we ever got a card not present error code, return that. Only the SERIALNO command and a reset are able to clear from that state. */ @@ -479,7 +465,7 @@ open_card (ctrl_t ctrl, const char *apptype) slot = get_reader_slot (); ctrl->reader_slot = slot; if (slot == -1) - err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD); + err = gpg_error (GPG_ERR_CARD); else { /* Fixme: We should move the apdu_connect call to @@ -537,7 +523,7 @@ cmd_serialno (assuan_context_t ctx, char *line) /* Clear the remove flag so that the open_card is able to reread it. */ retry: - if (!reader_disabled && ctrl->server_local->card_removed) + if (ctrl->server_local->card_removed) { if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); @@ -2066,7 +2052,7 @@ scd_command_handler (ctrl_t ctrl, int fd) BUG (); sl->next_session = ctrl->server_local->next_session; } - stopme = ctrl->server_local->stopme || reader_disabled; + stopme = ctrl->server_local->stopme; xfree (ctrl->server_local); ctrl->server_local = NULL; diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c index b863b01..615e4b2 100644 --- a/scd/sc-copykeys.c +++ b/scd/sc-copykeys.c @@ -139,7 +139,7 @@ main (int argc, char **argv ) if (argc != 1) usage (1); - slot = apdu_open_reader (reader_port, NULL); + slot = apdu_open_reader (reader_port); if (slot == -1) exit (1); if (apdu_connect (slot)) commit 9afd2bb7fb9067eb8c753a5e5f672a36e93b2474 Author: NIIBE Yutaka Date: Thu Nov 22 16:04:51 2012 +0900 Don't keep opening unavailable card reader. * scd/command.c (update_reader_status_file): Don't call get_reader_slot. -- This fix has a impact that the insertion of a card reader will not be detected upon the insertion, but will be deferred until user tries to access his card. diff --git a/scd/command.c b/scd/command.c index 3ce4a57..da11e88 100644 --- a/scd/command.c +++ b/scd/command.c @@ -2226,11 +2226,6 @@ update_reader_status_file (int set_card_removed_flag) int idx; unsigned int status, changed; - /* Make sure that the reader has been opened. Like get_reader_slot, - this part of the code assumes that there is only one reader. */ - if (!slot_table[0].valid) - (void)get_reader_slot (); - /* Note, that we only try to get the status, because it does not make sense to wait here for a operation to complete. If we are busy working with a card, delays in the status file update should ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 27 +++------------------------ scd/apdu.h | 2 +- scd/command.c | 27 ++++----------------------- scd/sc-copykeys.c | 2 +- 4 files changed, 9 insertions(+), 49 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Dec 10 18:32:17 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 10 Dec 2012 18:32:17 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-110-gd2777f8 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 d2777f84be0ded5906a9bec3bc23cfed0a9be02f (commit) via 25fb53ab4ae7e1c098500229c776d29b82713a20 (commit) via 36ba7845995dd3caf8faeec3e09b3ffb879fc29b (commit) via ceab60b59d907354d323ace09d7b3f2d36d330fb (commit) from 1e1326aeb8923782138e133f091afec41d969c40 (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 d2777f84be0ded5906a9bec3bc23cfed0a9be02f Author: Werner Koch Date: Mon Dec 10 18:27:23 2012 +0100 ssh: Improve key lookup for many keys. * agent/command-ssh.c: Remove dirent.h. (control_file_s): Add struct item. (rewind_control_file): New. (search_control_file): Factor code out to ... (read_control_file_item): New. (ssh_handler_request_identities): Change to iterate over entries in sshcontrol. -- Formerly we scanned the private key directory for matches of entries in sshcontrol. This patch changes it to scan the sshcontrol file and thus considers only keys configured there. The rationale for this is that it is common to have only a few ssh keys but many private keys. Even if that assumption does not hold true, the scanning of the sshcontrol file is faster than reading the directory and only then scanning the ssh control for each directory entry. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 435177d..533793c 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "agent.h" @@ -168,6 +167,14 @@ struct control_file_s { char *fname; /* Name of the file. */ FILE *fp; /* This is never NULL. */ + int lnr; /* The current line number. */ + struct { + int valid; /* True if the data of this structure is valid. */ + int disabled; /* The item is disabled. */ + int ttl; /* The TTL of the item. */ + int confirm; /* The confirm flag is set. */ + char hexgrip[40+1]; /* The hexgrip of the item (uppercase). */ + } item; }; typedef struct control_file_s *control_file_t; @@ -741,6 +748,15 @@ open_control_file (control_file_t *r_cf, int append) static void +rewind_control_file (control_file_t cf) +{ + fseek (cf->fp, 0, SEEK_SET); + cf->lnr = 0; + clearerr (cf->fp); +} + + +static void close_control_file (control_file_t cf) { if (!cf) @@ -751,29 +767,19 @@ close_control_file (control_file_t cf) } -/* Search the control file CF from the beginning until a matching - HEXGRIP is found; return success in this case and store true at - DISABLED if the found key has been disabled. If R_TTL is not NULL - a specified TTL for that key is stored there. If R_CONFIRM is not - NULL it is set to 1 if the key has the confirm flag set. */ + +/* Read the next line from the control file and store the data in CF. + Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */ static gpg_error_t -search_control_file (control_file_t cf, const char *hexgrip, - int *r_disabled, int *r_ttl, int *r_confirm) +read_control_file_item (control_file_t cf) { int c, i, n; char *p, *pend, line[256]; - long ttl; - int lnr = 0; + long ttl = 0; - assert (strlen (hexgrip) == 40 ); - - if (r_confirm) - *r_confirm = 0; - - fseek (cf->fp, 0, SEEK_SET); + cf->item.valid = 0; clearerr (cf->fp); - *r_disabled = 0; - next_line: + do { if (!fgets (line, DIM(line)-1, cf->fp) ) @@ -782,7 +788,7 @@ search_control_file (control_file_t cf, const char *hexgrip, return gpg_error (GPG_ERR_EOF); return gpg_error_from_syserror (); } - lnr++; + cf->lnr++; if (!*line || line[strlen(line)-1] != '\n') { @@ -799,35 +805,34 @@ search_control_file (control_file_t cf, const char *hexgrip, } while (!*p || *p == '\n' || *p == '#'); - *r_disabled = 0; + cf->item.disabled = 0; if (*p == '!') { - *r_disabled = 1; + cf->item.disabled = 1; for (p++; spacep (p); p++) ; } for (i=0; hexdigitp (p) && i < 40; p++, i++) - if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p)) - goto next_line; + cf->item.hexgrip[i] = (*p >= 'a'? (*p & 0xdf): *p); + cf->item.hexgrip[i] = 0; if (i != 40 || !(spacep (p) || *p == '\n')) { - log_error ("invalid formatted line in `%s', line %d\n", cf->fname, lnr); + log_error ("%s:%d: invalid formatted line\n", cf->fname, cf->lnr); return gpg_error (GPG_ERR_BAD_DATA); } ttl = strtol (p, &pend, 10); p = pend; - if (!(spacep (p) || *p == '\n') || ttl < -1) + if (!(spacep (p) || *p == '\n') || (int)ttl < -1) { - log_error ("invalid TTL value in `%s', line %d; assuming 0\n", - cf->fname, lnr); - ttl = 0; + log_error ("%s:%d: invalid TTL value; assuming 0\n", cf->fname, cf->lnr); + cf->item.ttl = 0; } - if (r_ttl) - *r_ttl = ttl; + cf->item.ttl = ttl; /* Now check for key-value pairs of the form NAME[=VALUE]. */ + cf->item.confirm = 0; while (*p) { for (; spacep (p) && *p != '\n'; p++) @@ -837,22 +842,68 @@ search_control_file (control_file_t cf, const char *hexgrip, n = strcspn (p, "= \t\n"); if (p[n] == '=') { - log_error ("assigning a value to a flag is not yet supported; " - "in `%s', line %d; flag ignored\n", cf->fname, lnr); + log_error ("%s:%d: assigning a value to a flag is not yet supported; " + "flag ignored\n", cf->fname, cf->lnr); p++; } else if (n == 7 && !memcmp (p, "confirm", 7)) { - if (r_confirm) - *r_confirm = 1; + cf->item.confirm = 1; } else - log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n", - n, p, cf->fname, lnr); + log_error ("%s:%d: invalid flag '%.*s'; ignored\n", + cf->fname, cf->lnr, n, p); p += n; } - return 0; /* Okay: found it. */ + /* log_debug ("%s:%d: grip=%s ttl=%d%s%s\n", */ + /* cf->fname, cf->lnr, */ + /* cf->item.hexgrip, cf->item.ttl, */ + /* cf->item.disabled? " disabled":"", */ + /* cf->item.confirm? " confirm":""); */ + + cf->item.valid = 1; + return 0; /* Okay: valid entry found. */ +} + + + +/* Search the control file CF from the beginning until a matching + HEXGRIP is found; return success in this case and store true at + DISABLED if the found key has been disabled. If R_TTL is not NULL + a specified TTL for that key is stored there. If R_CONFIRM is not + NULL it is set to 1 if the key has the confirm flag set. */ +static gpg_error_t +search_control_file (control_file_t cf, const char *hexgrip, + int *r_disabled, int *r_ttl, int *r_confirm) +{ + gpg_error_t err; + + assert (strlen (hexgrip) == 40 ); + + *r_disabled = 0; + if (r_ttl) + *r_ttl = 0; + if (r_confirm) + *r_confirm = 0; + + rewind_control_file (cf); + while (!(err=read_control_file_item (cf))) + { + if (!cf->item.valid) + continue; /* Should not happen. */ + if (!strcmp (hexgrip, cf->item.hexgrip)) + break; + } + if (!err) + { + *r_disabled = cf->item.disabled; + if (r_ttl) + *r_ttl = cf->item.ttl; + if (r_confirm) + *r_confirm = cf->item.confirm; + } + return err; } @@ -1896,19 +1947,13 @@ static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, estream_t request, estream_t response) { - char *key_type; ssh_key_type_spec_t spec; - struct dirent *dir_entry; - char *key_directory; - size_t key_directory_n; - char *key_path; - unsigned char *buffer; - size_t buffer_n; + char *key_fname = NULL; + char *fnameptr; u32 key_counter; estream_t key_blobs; gcry_sexp_t key_secret; gcry_sexp_t key_public; - DIR *dir; gpg_error_t err; int ret; control_file_t cf = NULL; @@ -1919,14 +1964,9 @@ ssh_handler_request_identities (ctrl_t ctrl, /* Prepare buffer stream. */ - key_directory = NULL; key_secret = NULL; key_public = NULL; - key_type = NULL; - key_path = NULL; key_counter = 0; - buffer = NULL; - dir = NULL; err = 0; key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); @@ -1936,34 +1976,6 @@ ssh_handler_request_identities (ctrl_t ctrl, goto out; } - /* Open key directory. */ - key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL); - if (! key_directory) - { - err = gpg_err_code_from_errno (errno); - goto out; - } - key_directory_n = strlen (key_directory); - - key_path = xtrymalloc (key_directory_n + 46); - if (! key_path) - { - err = gpg_err_code_from_errno (errno); - goto out; - } - - sprintf (key_path, "%s/", key_directory); - sprintf (key_path + key_directory_n + 41, ".key"); - - dir = opendir (key_directory); - if (! dir) - { - err = gpg_err_code_from_errno (errno); - goto out; - } - - - /* First check whether a key is currently available in the card reader - this should be allowed even without being listed in sshcontrol. */ @@ -1982,77 +1994,93 @@ ssh_handler_request_identities (ctrl_t ctrl, } - /* Then look at all the registered an allowed keys. */ + /* Prepare buffer for key name construction. */ + { + char *dname; + dname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL); + if (!dname) + { + err = gpg_err_code_from_syserror (); + goto out; + } - /* Fixme: We should better iterate over the control file and check - whether the key file is there. This is better in respect to - performance if there are a lot of keys in our key storage. */ - /* FIXME: make sure that buffer gets deallocated properly. */ + key_fname = xtrymalloc (strlen (dname) + 1 + 40 + 4 + 1); + if (!key_fname) + { + err = gpg_err_code_from_syserror (); + xfree (dname); + goto out; + } + fnameptr = stpcpy (stpcpy (key_fname, dname), "/"); + xfree (dname); + } + + /* Then look at all the registered and non-disabled keys. */ err = open_control_file (&cf, 0); if (err) goto out; - while ( (dir_entry = readdir (dir)) ) + while (!read_control_file_item (cf)) { - if ((strlen (dir_entry->d_name) == 44) - && (! strncmp (dir_entry->d_name + 40, ".key", 4))) - { - char hexgrip[41]; - int disabled; - - /* We do only want to return keys listed in our control - file. */ - strncpy (hexgrip, dir_entry->d_name, 40); - hexgrip[40] = 0; - if ( strlen (hexgrip) != 40 ) - continue; - if (search_control_file (cf, hexgrip, &disabled, NULL, NULL) - || disabled) - continue; - - strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); + if (!cf->item.valid) + continue; /* Should not happen. */ + if (cf->item.disabled) + continue; + assert (strlen (cf->item.hexgrip) == 40); - /* Read file content. */ - err = file_to_buffer (key_path, &buffer, &buffer_n); - if (err) - goto out; + stpcpy (stpcpy (fnameptr, cf->item.hexgrip), ".key"); - err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n); - if (err) - goto out; + /* Read file content. */ + { + unsigned char *buffer; + size_t buffer_n; + + err = file_to_buffer (key_fname, &buffer, &buffer_n); + if (err) + { + log_error ("%s:%d: key '%s' skipped: %s\n", + cf->fname, cf->lnr, cf->item.hexgrip, + gpg_strerror (err)); + continue; + } - xfree (buffer); - buffer = NULL; + err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n); + xfree (buffer); + if (err) + goto out; + } - err = sexp_extract_identifier (key_secret, &key_type); - if (err) - goto out; + { + char *key_type = NULL; - err = ssh_key_type_lookup (NULL, key_type, &spec); - if (err) - goto out; + err = sexp_extract_identifier (key_secret, &key_type); + if (err) + goto out; - xfree (key_type); - key_type = NULL; + err = ssh_key_type_lookup (NULL, key_type, &spec); + xfree (key_type); + if (err) + goto out; + } - err = key_secret_to_public (&key_public, spec, key_secret); - if (err) - goto out; + err = key_secret_to_public (&key_public, spec, key_secret); + if (err) + goto out; - gcry_sexp_release (key_secret); - key_secret = NULL; + gcry_sexp_release (key_secret); + key_secret = NULL; - err = ssh_send_key_public (key_blobs, key_public, NULL); - if (err) - goto out; + err = ssh_send_key_public (key_blobs, key_public, NULL); + if (err) + goto out; - gcry_sexp_release (key_public); - key_public = NULL; + gcry_sexp_release (key_public); + key_public = NULL; - key_counter++; - } + key_counter++; } + err = 0; ret = es_fseek (key_blobs, 0, SEEK_SET); if (ret) @@ -2062,43 +2090,27 @@ ssh_handler_request_identities (ctrl_t ctrl, } out: - /* Send response. */ gcry_sexp_release (key_secret); gcry_sexp_release (key_public); - if (! err) + if (!err) { ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); - if (ret_err) - goto leave; - ret_err = stream_write_uint32 (response, key_counter); - if (ret_err) - goto leave; - ret_err = stream_copy (response, key_blobs); - if (ret_err) - goto leave; + if (!ret_err) + ret_err = stream_write_uint32 (response, key_counter); + if (!ret_err) + ret_err = stream_copy (response, key_blobs); } else { ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); - goto leave; - }; - - leave: - - if (key_blobs) - es_fclose (key_blobs); - if (dir) - closedir (dir); + } + es_fclose (key_blobs); close_control_file (cf); - - xfree (key_directory); - xfree (key_path); - xfree (buffer); - xfree (key_type); + xfree (key_fname); return ret_err; } commit 25fb53ab4ae7e1c098500229c776d29b82713a20 Author: Werner Koch Date: Mon Dec 10 16:39:12 2012 +0100 ssh: Cleanup sshcontrol file access code. * agent/command-ssh.c (SSH_CONTROL_FILE_NAME): New macro to replace the direct use of the string. (struct control_file_s, control_file_t): New. (open_control_file, close_control_file): New. Use them instead of using fopen/fclose directly. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index ddf8e2c..435177d 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1,5 +1,5 @@ /* command-ssh.c - gpg-agent's ssh-agent emulation layer - * Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc. + * Copyright (C) 2004, 2005, 2006, 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -63,6 +63,8 @@ #define SSH_DSA_SIGNATURE_ELEMS 2 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0) +/* The name of the control file. */ +#define SSH_CONTROL_FILE_NAME "sshcontrol" /* The blurb we put into the header of a newly created control file. */ static const char sshcontrolblurb[] = @@ -79,7 +81,6 @@ static const char sshcontrolblurb[] = "\n"; - /* Macros. */ /* Return a new uint32 with b0 being the most significant byte and b3 @@ -162,6 +163,16 @@ typedef struct ssh_key_type_spec } ssh_key_type_spec_t; +/* An object used to access the sshcontrol file. */ +struct control_file_s +{ + char *fname; /* Name of the file. */ + FILE *fp; /* This is never NULL. */ +}; +typedef struct control_file_s *control_file_t; + + + /* Prototypes. */ static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, estream_t request, @@ -659,92 +670,124 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) -/* Open the ssh control file and create it if not available. With +/* Open the ssh control file and create it if not available. With APPEND passed as true the file will be opened in append mode, - otherwise in read only mode. On success a file pointer is stored - at the address of R_FP. */ + otherwise in read only mode. On success 0 is returned and a new + control file object stored at R_CF. On error an error code is + returned and NULL is stored at R_CF. */ static gpg_error_t -open_control_file (FILE **r_fp, int append) +open_control_file (control_file_t *r_cf, int append) { gpg_error_t err; - char *fname; - FILE *fp; + control_file_t cf; + + cf = xtrycalloc (1, sizeof *cf); + if (!cf) + { + err = gpg_error_from_syserror (); + goto leave; + } /* Note: As soon as we start to use non blocking functions here (i.e. where Pth might switch threads) we need to employ a mutex. */ - *r_fp = NULL; - fname = make_filename (opt.homedir, "sshcontrol", NULL); + cf->fname = make_filename_try (opt.homedir, SSH_CONTROL_FILE_NAME, NULL); + if (!cf->fname) + { + err = gpg_error_from_syserror (); + goto leave; + } /* FIXME: With "a+" we are not able to check whether this will will be created and thus the blurb needs to be written first. */ - fp = fopen (fname, append? "a+":"r"); - if (!fp && errno == ENOENT) + cf->fp = fopen (cf->fname, append? "a+":"r"); + if (!cf->fp && errno == ENOENT) { - estream_t stream = es_fopen (fname, "wx,mode=-rw-r"); + estream_t stream = es_fopen (cf->fname, "wx,mode=-rw-r"); if (!stream) { err = gpg_error_from_syserror (); - log_error (_("can't create '%s': %s\n"), fname, gpg_strerror (err)); - xfree (fname); - return err; + log_error (_("can't create `%s': %s\n"), + cf->fname, gpg_strerror (err)); + goto leave; } es_fputs (sshcontrolblurb, stream); es_fclose (stream); - fp = fopen (fname, append? "a+":"r"); + cf->fp = fopen (cf->fname, append? "a+":"r"); } - if (!fp) + if (!cf->fp) { - err = gpg_error (gpg_err_code_from_errno (errno)); - log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); - xfree (fname); - return err; + err = gpg_error_from_syserror (); + log_error (_("can't open `%s': %s\n"), + cf->fname, gpg_strerror (err)); + goto leave; } - *r_fp = fp; + err = 0; - return 0; + leave: + if (err && cf) + { + if (cf->fp) + fclose (cf->fp); + xfree (cf->fname); + xfree (cf); + } + else + *r_cf = cf; + + return err; +} + + +static void +close_control_file (control_file_t cf) +{ + if (!cf) + return; + fclose (cf->fp); + xfree (cf->fname); + xfree (cf); } -/* Search the file at stream FP from the beginning until a matching +/* Search the control file CF from the beginning until a matching HEXGRIP is found; return success in this case and store true at DISABLED if the found key has been disabled. If R_TTL is not NULL a specified TTL for that key is stored there. If R_CONFIRM is not NULL it is set to 1 if the key has the confirm flag set. */ static gpg_error_t -search_control_file (FILE *fp, const char *hexgrip, +search_control_file (control_file_t cf, const char *hexgrip, int *r_disabled, int *r_ttl, int *r_confirm) { int c, i, n; char *p, *pend, line[256]; long ttl; int lnr = 0; - const char fname[] = "sshcontrol"; assert (strlen (hexgrip) == 40 ); if (r_confirm) *r_confirm = 0; - fseek (fp, 0, SEEK_SET); - clearerr (fp); + fseek (cf->fp, 0, SEEK_SET); + clearerr (cf->fp); *r_disabled = 0; next_line: do { - if (!fgets (line, DIM(line)-1, fp) ) + if (!fgets (line, DIM(line)-1, cf->fp) ) { - if (feof (fp)) + if (feof (cf->fp)) return gpg_error (GPG_ERR_EOF); - return gpg_error (gpg_err_code_from_errno (errno)); + return gpg_error_from_syserror (); } lnr++; if (!*line || line[strlen(line)-1] != '\n') { /* Eat until end of line */ - while ( (c=getc (fp)) != EOF && c != '\n') + while ( (c=getc (cf->fp)) != EOF && c != '\n') ; return gpg_error (*line? GPG_ERR_LINE_TOO_LONG : GPG_ERR_INCOMPLETE_LINE); @@ -769,7 +812,7 @@ search_control_file (FILE *fp, const char *hexgrip, goto next_line; if (i != 40 || !(spacep (p) || *p == '\n')) { - log_error ("invalid formatted line in '%s', line %d\n", fname, lnr); + log_error ("invalid formatted line in `%s', line %d\n", cf->fname, lnr); return gpg_error (GPG_ERR_BAD_DATA); } @@ -777,8 +820,8 @@ search_control_file (FILE *fp, const char *hexgrip, p = pend; if (!(spacep (p) || *p == '\n') || ttl < -1) { - log_error ("invalid TTL value in '%s', line %d; assuming 0\n", - fname, lnr); + log_error ("invalid TTL value in `%s', line %d; assuming 0\n", + cf->fname, lnr); ttl = 0; } if (r_ttl) @@ -795,7 +838,7 @@ search_control_file (FILE *fp, const char *hexgrip, if (p[n] == '=') { log_error ("assigning a value to a flag is not yet supported; " - "in '%s', line %d; flag ignored\n", fname, lnr); + "in `%s', line %d; flag ignored\n", cf->fname, lnr); p++; } else if (n == 7 && !memcmp (p, "confirm", 7)) @@ -804,8 +847,8 @@ search_control_file (FILE *fp, const char *hexgrip, *r_confirm = 1; } else - log_error ("invalid flag '%.*s' in '%s', line %d; ignored\n", - n, p, fname, lnr); + log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n", + n, p, cf->fname, lnr); p += n; } @@ -824,16 +867,16 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr, int ttl, int confirm) { gpg_error_t err; - FILE *fp; + control_file_t cf; int disabled; (void)ctrl; - err = open_control_file (&fp, 1); + err = open_control_file (&cf, 1); if (err) return err; - err = search_control_file (fp, hexgrip, &disabled, NULL, NULL); + err = search_control_file (cf, hexgrip, &disabled, NULL, NULL); if (err && gpg_err_code(err) == GPG_ERR_EOF) { struct tm *tp; @@ -842,15 +885,16 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr, /* Not yet in the file - add it. Because the file has been opened in append mode, we simply need to write to it. */ tp = localtime (&atime); - fprintf (fp, ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n" - "# Fingerprint: %s\n" - "%s %d%s\n"), + fprintf (cf->fp, + ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n" + "# Fingerprint: %s\n" + "%s %d%s\n"), 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec, fmtfpr, hexgrip, ttl, confirm? " confirm":""); } - fclose (fp); + close_control_file (cf); return 0; } @@ -859,20 +903,20 @@ add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr, static int ttl_from_sshcontrol (const char *hexgrip) { - FILE *fp; + control_file_t cf; int disabled, ttl; if (!hexgrip || strlen (hexgrip) != 40) return 0; /* Wrong input: Use global default. */ - if (open_control_file (&fp, 0)) + if (open_control_file (&cf, 0)) return 0; /* Error: Use the global default TTL. */ - if (search_control_file (fp, hexgrip, &disabled, &ttl, NULL) + if (search_control_file (cf, hexgrip, &disabled, &ttl, NULL) || disabled) ttl = 0; /* Use the global default if not found or disabled. */ - fclose (fp); + close_control_file (cf); return ttl; } @@ -882,21 +926,21 @@ ttl_from_sshcontrol (const char *hexgrip) static int confirm_flag_from_sshcontrol (const char *hexgrip) { - FILE *fp; + control_file_t cf; int disabled, confirm; if (!hexgrip || strlen (hexgrip) != 40) return 1; /* Wrong input: Better ask for confirmation. */ - if (open_control_file (&fp, 0)) + if (open_control_file (&cf, 0)) return 1; /* Error: Better ask for confirmation. */ - if (search_control_file (fp, hexgrip, &disabled, NULL, &confirm) + if (search_control_file (cf, hexgrip, &disabled, NULL, &confirm) || disabled) confirm = 0; /* If not found or disabled, there is no reason to ask for confirmation. */ - fclose (fp); + close_control_file (cf); return confirm; } @@ -1867,7 +1911,7 @@ ssh_handler_request_identities (ctrl_t ctrl, DIR *dir; gpg_error_t err; int ret; - FILE *ctrl_fp = NULL; + control_file_t cf = NULL; char *cardsn; gpg_error_t ret_err; @@ -1942,10 +1986,10 @@ ssh_handler_request_identities (ctrl_t ctrl, /* Fixme: We should better iterate over the control file and check - whether the key file is there. This is better in resepct to - performance if tehre are a lot of key sin our key storage. */ + whether the key file is there. This is better in respect to + performance if there are a lot of keys in our key storage. */ /* FIXME: make sure that buffer gets deallocated properly. */ - err = open_control_file (&ctrl_fp, 0); + err = open_control_file (&cf, 0); if (err) goto out; @@ -1963,7 +2007,7 @@ ssh_handler_request_identities (ctrl_t ctrl, hexgrip[40] = 0; if ( strlen (hexgrip) != 40 ) continue; - if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL) + if (search_control_file (cf, hexgrip, &disabled, NULL, NULL) || disabled) continue; @@ -2049,8 +2093,7 @@ ssh_handler_request_identities (ctrl_t ctrl, if (dir) closedir (dir); - if (ctrl_fp) - fclose (ctrl_fp); + close_control_file (cf); xfree (key_directory); xfree (key_path); commit 36ba7845995dd3caf8faeec3e09b3ffb879fc29b Author: Werner Koch Date: Mon Dec 10 14:45:26 2012 +0100 agent: Add envvar "gnupg_SSH_AUTH_SOCK_by" * agent/gpg-agent.c (main): Pass new envar gnupg_SSH_AUTH_SOCK_by to an invoked process. -- This environment variable is useful for debugging if --use-standard-socket is used (which is the default since 2.1). Commonly you should have this in your init script (e.g. ~/.bashrc): unset GPG_AGENT_INFO unset SSH_AGENT_PID SSH_AUTH_SOCK="${HOME}/.gnupg/S.gpg-agent.ssh" export SSH_AUTH_SOCK The problem is that gpg-agent won't be able to override the SSH_AUTH_SOCK envvar if gpg-agent has been invoked as gpg-agent --enable-ssh-support --daemon /bin/bash To fix this you should instead use this code in the init script: unset GPG_AGENT_INFO unset SSH_AGENT_PID if [ ${gnupg_SSH_AUTH_SOCK_by:-0} -ne $$ ]; then export SSH_AUTH_SOCK="${HOME}/.gnupg/S.gpg-agent.ssh" fi This will work in all cases and thus allows to start gpg-agent for testing purposes with a different homedir and use this gpg-agent as an ssh-agent. Example: GNUPGHOME=$(pwd) gpg-agent --enable-ssh-support --daemon /bin/bash gnupg_SSH_AUTH_SOCK_by is set to the PID of the exec-ed process and thus will work safely if called recursively. diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 32da578..4690114 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1067,7 +1067,7 @@ main (int argc, char **argv ) } else if (pid) { /* We are the parent */ - char *infostr, *infostr_ssh_sock; + char *infostr, *infostr_ssh_sock, *infostr_ssh_valid; /* Close the socket FD. */ close (fd); @@ -1104,6 +1104,13 @@ main (int argc, char **argv ) kill (pid, SIGTERM); exit (1); } + if (asprintf (&infostr_ssh_valid, "gnupg_SSH_AUTH_SOCK_by=%lu", + (unsigned long)getpid()) < 0) + { + log_error ("out of core\n"); + kill (pid, SIGTERM); + exit (1); + } } *socket_name = 0; /* Don't let cleanup() remove the socket - @@ -1142,7 +1149,8 @@ main (int argc, char **argv ) kill (pid, SIGTERM ); exit (1); } - if (opt.ssh_support && putenv (infostr_ssh_sock)) + if (opt.ssh_support && (putenv (infostr_ssh_sock) + || putenv (infostr_ssh_valid))) { log_error ("failed to set environment: %s\n", strerror (errno) ); @@ -1189,6 +1197,7 @@ main (int argc, char **argv ) if (opt.ssh_support) { xfree (infostr_ssh_sock); + xfree (infostr_ssh_valid); } exit (0); } commit ceab60b59d907354d323ace09d7b3f2d36d330fb Author: Werner Koch Date: Mon Dec 10 09:40:40 2012 +0100 config: Update npth.m4. * m4/npth.m4: Take from current npth master. diff --git a/m4/npth.m4 b/m4/npth.m4 index 5b60e2c..17c2644 100644 --- a/m4/npth.m4 +++ b/m4/npth.m4 @@ -34,12 +34,12 @@ dnl Test for libnpth and define NPTH_CFLAGS and NPTH_LIBS. dnl AC_DEFUN([AM_PATH_NPTH], [ AC_REQUIRE([_AM_PATH_NPTH_CONFIG])dnl - tmp=ifelse([$1], ,1:0.0,$1) + tmp=ifelse([$1], ,1:0.91,$1) if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then req_npth_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` min_npth_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` else - req_npth_api=0 + req_npth_api=1 min_npth_version="$tmp" fi @@ -47,28 +47,40 @@ AC_DEFUN([AM_PATH_NPTH], ok=no if test "$NPTH_CONFIG" != "no" ; then req_major=`echo $min_npth_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` req_minor=`echo $min_npth_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` if test "$npth_version_major" -gt "$req_major"; then ok=yes else if test "$npth_version_major" -eq "$req_major"; then - if test "$npth_version_minor" -ge "$req_minor"; then + if test "$npth_version_minor" -gt "$req_minor"; then ok=yes + else + if test "$npth_version_minor" -eq "$req_minor"; then + ok=yes + fi fi fi fi fi if test $ok = yes; then + AC_MSG_RESULT([yes ($npth_version)]) + else + AC_MSG_RESULT(no) + fi + if test $ok = yes; then # If we have a recent NPTH, we should also check that the # API is compatible. if test "$req_npth_api" -gt 0 ; then tmp=`$NPTH_CONFIG --api-version 2>/dev/null || echo 0` if test "$tmp" -gt 0 ; then - if test "$req_npth_api" -ne "$tmp" ; then + AC_MSG_CHECKING([NPTH API version]) + if test "$req_npth_api" -eq "$tmp" ; then + AC_MSG_RESULT([okay]) + else ok=no + AC_MSG_RESULT([does not match. want=$req_npth_api got=$tmp]) fi fi fi @@ -76,12 +88,23 @@ AC_DEFUN([AM_PATH_NPTH], if test $ok = yes; then NPTH_CFLAGS=`$NPTH_CONFIG --cflags` NPTH_LIBS=`$NPTH_CONFIG --libs` - AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) + npth_config_host=`$NPTH_CONFIG --host 2>/dev/null || echo none` + if test x"$npth_config_host" != xnone ; then + if test x"$npth_config_host" != x"$host" ; then + AC_MSG_WARN([[ +*** +*** The config script $NPTH_CONFIG was +*** built for $npth_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-npth-prefix +*** to specify a matching config script. +***]]) + fi + fi else NPTH_CFLAGS="" NPTH_LIBS="" - AC_MSG_RESULT(no) ifelse([$3], , :, [$3]) fi AC_SUBST(NPTH_CFLAGS) ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 457 ++++++++++++++++++++++++++++---------------------- agent/gpg-agent.c | 13 ++- m4/npth.m4 | 41 ++++- 3 files changed, 299 insertions(+), 212 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 12 18:52:33 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 12 Dec 2012 18:52:33 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-112-g649b31c 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 649b31c663b8674bc874b4ef283d714a13dc8cfe (commit) via f76a0312c3794afd81fe1e172df15eb0612deae0 (commit) from d2777f84be0ded5906a9bec3bc23cfed0a9be02f (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 649b31c663b8674bc874b4ef283d714a13dc8cfe Author: Werner Koch Date: Wed Dec 12 18:47:21 2012 +0100 ssh: Support ECDSA keys. * agent/command-ssh.c (SPEC_FLAG_IS_ECDSA): New. (struct ssh_key_type_spec): Add fields CURVE_NAME and HASH_ALGO. (ssh_key_types): Add types ecdsa-sha2-nistp{256,384,521}. (ssh_signature_encoder_t): Add arg spec and adjust all callers. (ssh_signature_encoder_ecdsa): New. (sexp_key_construct, sexp_key_extract, ssh_receive_key) (ssh_convert_key_to_blob): Support ecdsa. (ssh_identifier_from_curve_name): New. (ssh_send_key_public): Retrieve and pass the curve_name. (key_secret_to_public): Ditto. (data_sign): Add arg SPEC and change callers to pass it. (ssh_handler_sign_request): Get the hash algo from SPEC. * common/ssh-utils.c (get_fingerprint): Support ecdsa. * agent/protect.c (protect_info): Add flag ECC_HACK. (agent_protect): Allow the use of the "curve" parameter. * agent/t-protect.c (test_agent_protect): Add a test case for ecdsa. * agent/command-ssh.c (ssh_key_grip): Print a better error code. -- The 3 standard curves are now supported in gpg-agent's ssh-agent protocol implementation. I tested this with all 3 curves and keys generated by OpenSSH 5.9p1. Using existing non-ssh generated keys will likely fail for now. To fix this, the code should first undergo some more cleanup; then the fixes are pretty straightforward. And yes, the data structures are way too complicated. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 31195c4..c0b608a 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -17,7 +17,18 @@ * along with this program; if not, see . */ -/* Only v2 of the ssh-agent protocol is implemented. */ +/* Only v2 of the ssh-agent protocol is implemented. Relevant RFCs + are: + + RFC-4250 - Protocol Assigned Numbers + RFC-4251 - Protocol Architecture + RFC-4252 - Authentication Protocol + RFC-4253 - Transport Layer Protocol + RFC-5656 - ECC support + + The protocol for the agent is defined in OpenSSH's PROTOCL.agent + file. + */ #include @@ -61,6 +72,7 @@ #define SSH_DSA_SIGNATURE_PADDING 20 #define SSH_DSA_SIGNATURE_ELEMS 2 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0) +#define SPEC_FLAG_IS_ECDSA (1 << 1) /* The name of the control file. */ #define SSH_CONTROL_FILE_NAME "sshcontrol" @@ -99,6 +111,10 @@ typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl, estream_t request, estream_t response); + +struct ssh_key_type_spec; +typedef struct ssh_key_type_spec ssh_key_type_spec_t; + /* Type, which is used for associating request handlers with the appropriate request IDs. */ typedef struct ssh_request_spec @@ -119,12 +135,13 @@ typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, /* The encoding of a generated signature is dependent on the algorithm; therefore algorithm specific signature encoding functions are necessary. */ -typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob, +typedef gpg_error_t (*ssh_signature_encoder_t) (ssh_key_type_spec_t *spec, + estream_t signature_blob, gcry_mpi_t *mpis); /* Type, which is used for boundling all the algorithm specific information together in a single object. */ -typedef struct ssh_key_type_spec +struct ssh_key_type_spec { /* Algorithm identifier as used by OpenSSH. */ const char *ssh_identifier; @@ -157,9 +174,16 @@ typedef struct ssh_key_type_spec algorithm. */ ssh_signature_encoder_t signature_encoder; + /* The name of the ECC curve or NULL. */ + const char *curve_name; + + /* The hash algorithm to be used with this key. 0 for using the + default. */ + int hash_algo; + /* Misc flags. */ unsigned int flags; -} ssh_key_type_spec_t; +}; /* An object used to access the sshcontrol file. */ @@ -204,10 +228,15 @@ static gpg_error_t ssh_handler_unlock (ctrl_t ctrl, estream_t response); static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis); -static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob, +static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec, + estream_t signature_blob, gcry_mpi_t *mpis); -static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, +static gpg_error_t ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec, + estream_t signature_blob, gcry_mpi_t *mpis); +static gpg_error_t ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec, + estream_t signature_blob, + gcry_mpi_t *mpis); @@ -240,13 +269,29 @@ static ssh_key_type_spec_t ssh_key_types[] = { "ssh-rsa", "rsa", "nedupq", "en", "s", "nedpqu", ssh_key_modifier_rsa, ssh_signature_encoder_rsa, - SPEC_FLAG_USE_PKCS1V2 + NULL, 0, SPEC_FLAG_USE_PKCS1V2 }, { "ssh-dss", "dsa", "pqgyx", "pqgy", "rs", "pqgyx", NULL, ssh_signature_encoder_dsa, - 0 + NULL, 0, 0 + }, + { + "ecdsa-sha2-nistp256", "ecdsa", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_ecdsa, + "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA }, + { + "ecdsa-sha2-nistp384", "ecdsa", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_ecdsa, + "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA + }, + { + "ecdsa-sha2-nistp521", "ecdsa", "qd", "q", "rs", "qd", + NULL, ssh_signature_encoder_ecdsa, + "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA + } + }; @@ -341,6 +386,7 @@ stream_write_byte (estream_t stream, unsigned char b) return err; } + /* Read a uint32 from STREAM, store it in UINT32. */ static gpg_error_t stream_read_uint32 (estream_t stream, u32 *uint32) @@ -431,8 +477,9 @@ stream_write_data (estream_t stream, const unsigned char *buffer, size_t size) } /* Read a binary string from STREAM into STRING, store size of string - in STRING_SIZE; depending on SECURE use secure memory for - string. */ + in STRING_SIZE. Append a hidden nul so that the result may + directly be used as a C string. Depending on SECURE use secure + memory for STRING. */ static gpg_error_t stream_read_string (estream_t stream, unsigned int secure, unsigned char **string, u32 *string_size) @@ -1114,13 +1161,16 @@ ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis) /* Signature encoder function for RSA. */ static gpg_error_t -ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) +ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec, + estream_t signature_blob, gcry_mpi_t *mpis) { unsigned char *data; size_t data_n; gpg_error_t err; gcry_mpi_t s; + (void)spec; + s = mpis[0]; err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s); @@ -1138,7 +1188,8 @@ ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) /* Signature encoder function for DSA. */ static gpg_error_t -ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) +ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec, + estream_t signature_blob, gcry_mpi_t *mpis) { unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS]; unsigned char *data; @@ -1146,8 +1197,12 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) gpg_error_t err; int i; + (void)spec; + data = NULL; + /* FIXME: Why this complicated code? Why collecting boths mpis in a + buffer instead of writing them out one after the other? */ for (i = 0; i < 2; i++) { err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]); @@ -1180,23 +1235,63 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) return err; } + +/* Signature encoder function for ECDSA. */ +static gpg_error_t +ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec, + estream_t stream, gcry_mpi_t *mpis) +{ + unsigned char *data[2] = {NULL, NULL}; + size_t data_n[2]; + size_t innerlen; + gpg_error_t err; + int i; + + innerlen = 0; + for (i = 0; i < DIM(data); i++) + { + err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &data[i], &data_n[i], mpis[i]); + if (err) + goto out; + innerlen += 4 + data_n[i]; + } + + err = stream_write_uint32 (stream, innerlen); + if (err) + goto out; + + for (i = 0; i < DIM(data); i++) + { + err = stream_write_string (stream, data[i], data_n[i]); + if (err) + goto out; + } + + out: + for (i = 0; i < DIM(data); i++) + xfree (data[i]); + return err; +} + + /* S-Expressions. */ /* This function constructs a new S-Expression for the key identified - by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in - *SEXP. Returns usual error code. */ + by the KEY_SPEC, SECRET, CURVE_NAME, MPIS, and COMMENT, which is to + be stored at R_SEXP. Returns an error code. */ static gpg_error_t sexp_key_construct (gcry_sexp_t *r_sexp, ssh_key_type_spec_t key_spec, int secret, - gcry_mpi_t *mpis, const char *comment) + const char *curve_name, gcry_mpi_t *mpis, + const char *comment) { const char *key_identifier[] = { "public-key", "private-key" }; gpg_error_t err; gcry_sexp_t sexp_new = NULL; - char *formatbuf = NULL; + void *formatbuf = NULL; void **arg_list = NULL; int arg_idx; estream_t format; @@ -1219,7 +1314,7 @@ sexp_key_construct (gcry_sexp_t *r_sexp, /* Key identifier, algorithm identifier, mpis, comment, and a NULL as a safeguard. */ - arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1 + 1)); + arg_list = xtrymalloc (sizeof (*arg_list) * (2 + 1 + elems_n + 1 + 1)); if (!arg_list) { err = gpg_error_from_syserror (); @@ -1230,6 +1325,11 @@ sexp_key_construct (gcry_sexp_t *r_sexp, es_fputs ("(%s(%s", format); arg_list[arg_idx++] = &key_identifier[secret]; arg_list[arg_idx++] = &key_spec.identifier; + if (curve_name) + { + es_fputs ("(curve%s)", format); + arg_list[arg_idx++] = &curve_name; + } for (i = 0; i < elems_n; i++) { @@ -1261,7 +1361,6 @@ sexp_key_construct (gcry_sexp_t *r_sexp, } format = NULL; - log_debug ("sexp formatbuf='%s' nargs=%d\n", formatbuf, arg_idx); err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list); if (err) goto out; @@ -1281,34 +1380,28 @@ sexp_key_construct (gcry_sexp_t *r_sexp, /* This functions breaks up the key contained in the S-Expression SEXP according to KEY_SPEC. The MPIs are bundled in a newly create list, which is to be stored in MPIS; a newly allocated string - holding the comment will be stored in COMMENT; SECRET will be - filled with a boolean flag specifying what kind of key it is. - Returns usual error code. */ + holding the curve name may be stored at RCURVE, and a comment will + be stored at COMMENT; SECRET will be filled with a boolean flag + specifying what kind of key it is. Returns an error code. */ static gpg_error_t sexp_key_extract (gcry_sexp_t sexp, ssh_key_type_spec_t key_spec, int *secret, - gcry_mpi_t **mpis, char **comment) + gcry_mpi_t **mpis, char **r_curve, char **comment) { - gpg_error_t err; - gcry_sexp_t value_list; - gcry_sexp_t value_pair; - gcry_sexp_t comment_list; + gpg_error_t err = 0; + gcry_sexp_t value_list = NULL; + gcry_sexp_t value_pair = NULL; + gcry_sexp_t comment_list = NULL; unsigned int i; - char *comment_new; + char *comment_new = NULL; const char *data; size_t data_n; int is_secret; size_t elems_n; const char *elems; - gcry_mpi_t *mpis_new; + gcry_mpi_t *mpis_new = NULL; gcry_mpi_t mpi; - - err = 0; - value_list = NULL; - value_pair = NULL; - comment_list = NULL; - comment_new = NULL; - mpis_new = NULL; + char *curve_name = NULL; data = gcry_sexp_nth_data (sexp, 0, &data_n); if (! data) @@ -1374,6 +1467,51 @@ sexp_key_extract (gcry_sexp_t sexp, if (err) goto out; + if ((key_spec.flags & SPEC_FLAG_IS_ECDSA)) + { + /* Parse the "curve" parameter. We currently expect the curve + name for ECC and not the parameters of the curve. This can + easily be changed but then we need to find the curve name + from the parameters using gcry_pk_get_curve. */ + const char *mapped; + + value_pair = gcry_sexp_find_token (value_list, "curve", 5); + if (!value_pair) + { + err = gpg_error (GPG_ERR_INV_CURVE); + goto out; + } + curve_name = gcry_sexp_nth_string (value_pair, 1); + if (!curve_name) + { + err = gpg_error (GPG_ERR_INV_CURVE); /* (Or out of core.) */ + goto out; + } + + /* Fixme: The mapping should be done by using gcry_pk_get_curve + et al to iterate over all name aliases. */ + if (!strcmp (curve_name, "NIST P-256")) + mapped = "nistp256"; + else if (!strcmp (curve_name, "NIST P-384")) + mapped = "nistp384"; + else if (!strcmp (curve_name, "NIST P-521")) + mapped = "nistp521"; + else + mapped = NULL; + if (mapped) + { + xfree (curve_name); + curve_name = xtrystrdup (mapped); + if (!curve_name) + { + err = gpg_error_from_syserror (); + goto out; + } + } + gcry_sexp_release (value_pair); + value_pair = NULL; + } + /* We do not require a comment sublist to be present here. */ data = NULL; data_n = 0; @@ -1398,6 +1536,7 @@ sexp_key_extract (gcry_sexp_t sexp, *secret = is_secret; *mpis = mpis_new; *comment = comment_new; + *r_curve = curve_name; out: @@ -1407,6 +1546,7 @@ sexp_key_extract (gcry_sexp_t sexp, if (err) { + xfree (curve_name); xfree (comment_new); mpint_list_free (mpis_new); } @@ -1493,6 +1633,24 @@ ssh_key_type_lookup (const char *ssh_name, const char *name, return err; } + +/* Lookup the ssh-identifier for the ECC curve CURVE_NAME. Returns + NULL if not found. */ +static const char * +ssh_identifier_from_curve_name (const char *curve_name) +{ + int i; + + for (i = 0; i < DIM (ssh_key_types); i++) + if (ssh_key_types[i].curve_name + && !strcmp (ssh_key_types[i].curve_name, curve_name)) + return ssh_key_types[i].ssh_identifier; + + return NULL; +} + + + /* Receive a key from STREAM, according to the key specification given as KEY_SPEC. Depending on SECRET, receive a secret or a public key. If READ_COMMENT is true, receive a comment string as well. @@ -1509,6 +1667,8 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, ssh_key_type_spec_t spec; gcry_mpi_t *mpi_list = NULL; const char *elems; + char *curve_name = NULL; + err = stream_read_cstring (stream, &key_type); if (err) @@ -1518,6 +1678,50 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, if (err) goto out; + if ((spec.flags & SPEC_FLAG_IS_ECDSA)) + { + /* The format of an ECDSA key is: + * string key_type ("ecdsa-sha2-nistp256" | + * "ecdsa-sha2-nistp384" | + * "ecdsa-sha2-nistp521" ) + * string ecdsa_curve_name + * string ecdsa_public_key + * mpint ecdsa_private + * + * Note that we use the mpint reader instead of the string + * reader for ecsa_public_key. + */ + unsigned char *buffer; + const char *mapped; + + err = stream_read_string (stream, 0, &buffer, NULL); + if (err) + goto out; + curve_name = buffer; + /* Fixme: Check that curve_name matches the keytype. */ + /* Because Libgcrypt < 1.6 has no support for the "nistpNNN" + curve names, we need to translate them here to Libgcrypt's + native names. */ + if (!strcmp (curve_name, "nistp256")) + mapped = "NIST P-256"; + else if (!strcmp (curve_name, "nistp384")) + mapped = "NIST P-384"; + else if (!strcmp (curve_name, "nistp521")) + mapped = "NIST P-521"; + else + mapped = NULL; + if (mapped) + { + xfree (curve_name); + curve_name = xtrystrdup (mapped); + if (!curve_name) + { + err = gpg_error_from_syserror (); + goto out; + } + } + } + err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list); if (err) goto out; @@ -1541,7 +1745,8 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, goto out; } - err = sexp_key_construct (&key, spec, secret, mpi_list, comment? comment:""); + err = sexp_key_construct (&key, spec, secret, curve_name, mpi_list, + comment? comment:""); if (err) goto out; @@ -1550,8 +1755,8 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, *key_new = key; out: - mpint_list_free (mpi_list); + xfree (curve_name); xfree (key_type); xfree (comment); @@ -1563,7 +1768,8 @@ ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, BLOB/BLOB_SIZE. Returns zero on success or an error code. */ static gpg_error_t ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, - const char *type, gcry_mpi_t *mpis) + ssh_key_type_spec_t *spec, + const char *curve_name, gcry_mpi_t *mpis) { unsigned char *blob_new; long int blob_size_new; @@ -1585,14 +1791,31 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, goto out; } - err = stream_write_cstring (stream, type); - if (err) - goto out; + if ((spec->flags & SPEC_FLAG_IS_ECDSA) && curve_name) + { + const char *sshname = ssh_identifier_from_curve_name (curve_name); + if (!curve_name) + { + err = gpg_error (GPG_ERR_UNKNOWN_CURVE); + goto out; + } + err = stream_write_cstring (stream, sshname); + if (err) + goto out; + err = stream_write_cstring (stream, curve_name); + if (err) + goto out; + } + else + { + err = stream_write_cstring (stream, spec->ssh_identifier); + if (err) + goto out; + } - for (i = 0; mpis[i] && (! err); i++) - err = stream_write_mpi (stream, mpis[i]); - if (err) - goto out; + for (i = 0; mpis[i]; i++) + if ((err = stream_write_mpi (stream, mpis[i]))) + goto out; blob_size_new = es_ftell (stream); if (blob_size_new == -1) @@ -1634,22 +1857,19 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, OVERRIDE_COMMENT is not NULL, it will be used instead of the comment stored in the key. */ static gpg_error_t -ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, +ssh_send_key_public (estream_t stream, + gcry_sexp_t key_public, const char *override_comment) { ssh_key_type_spec_t spec; - gcry_mpi_t *mpi_list; - char *key_type; - char *comment; - unsigned char *blob; + gcry_mpi_t *mpi_list = NULL; + char *key_type = NULL; + char *curve; + char *comment = NULL; + unsigned char *blob = NULL; size_t blob_n; gpg_error_t err; - key_type = NULL; - mpi_list = NULL; - comment = NULL; - blob = NULL; - err = sexp_extract_identifier (key_public, &key_type); if (err) goto out; @@ -1658,12 +1878,11 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, if (err) goto out; - err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment); + err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &curve, &comment); if (err) goto out; - err = ssh_convert_key_to_blob (&blob, &blob_n, - spec.ssh_identifier, mpi_list); + err = ssh_convert_key_to_blob (&blob, &blob_n, &spec, curve, mpi_list); if (err) goto out; @@ -1677,8 +1896,9 @@ ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, out: mpint_list_free (mpi_list); - xfree (key_type); + xfree (curve); xfree (comment); + xfree (key_type); xfree (blob); return err; @@ -1731,7 +1951,10 @@ static gpg_error_t ssh_key_grip (gcry_sexp_t key, unsigned char *buffer) { if (!gcry_pk_get_keygrip (key, buffer)) - return gpg_error (GPG_ERR_INTERNAL); + { + gpg_error_t err = gcry_pk_testkey (key); + return err? err : gpg_error (GPG_ERR_INTERNAL); + } return 0; } @@ -1744,6 +1967,7 @@ static gpg_error_t key_secret_to_public (gcry_sexp_t *key_public, ssh_key_type_spec_t spec, gcry_sexp_t key_secret) { + char *curve; char *comment; gcry_mpi_t *mpis; gpg_error_t err; @@ -1752,16 +1976,18 @@ key_secret_to_public (gcry_sexp_t *key_public, comment = NULL; mpis = NULL; - err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment); + err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, + &curve, &comment); if (err) goto out; - err = sexp_key_construct (key_public, spec, 0, mpis, comment); + err = sexp_key_construct (key_public, spec, 0, curve, mpis, comment); out: mpint_list_free (mpis); xfree (comment); + xfree (curve); return err; } @@ -2134,7 +2360,7 @@ data_hash (unsigned char *data, size_t data_n, signature in newly allocated memory in SIG and it's size in SIG_N; SIG_ENCODER is the signature encoder to use. */ static gpg_error_t -data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, +data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec, unsigned char **sig, size_t *sig_n) { gpg_error_t err; @@ -2145,10 +2371,6 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, gcry_mpi_t sig_value = NULL; unsigned char *sig_blob = NULL; size_t sig_blob_n = 0; - char *identifier = NULL; - const char *identifier_raw; - size_t identifier_n; - ssh_key_type_spec_t spec; int ret; unsigned int i; const char *elems; @@ -2227,29 +2449,11 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, goto out; } - identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n); - if (! identifier_raw) - { - err = gpg_error (GPG_ERR_INV_SEXP); - goto out; - } - - identifier = make_cstring (identifier_raw, identifier_n); - if (! identifier) - { - err = gpg_error_from_syserror (); - goto out; - } - - err = ssh_key_type_lookup (NULL, identifier, &spec); - if (err) - goto out; - - err = stream_write_cstring (stream, spec.ssh_identifier); + err = stream_write_cstring (stream, spec->ssh_identifier); if (err) goto out; - elems = spec.elems_signature; + elems = spec->elems_signature; elems_n = strlen (elems); mpis = xtrycalloc (elems_n + 1, sizeof *mpis); @@ -2261,7 +2465,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, for (i = 0; i < elems_n; i++) { - sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1); + sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1); if (! sublist) { err = gpg_error (GPG_ERR_INV_SEXP); @@ -2282,7 +2486,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, if (err) goto out; - err = (*sig_encoder) (stream, mpis); + err = spec->signature_encoder (spec, stream, mpis); if (err) goto out; @@ -2325,7 +2529,6 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, gcry_sexp_release (signature_sexp); gcry_sexp_release (sublist); mpint_list_free (mpis); - xfree (identifier); return err; } @@ -2348,6 +2551,7 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) u32 flags; gpg_error_t err; gpg_error_t ret_err; + int hash_algo; key_blob = NULL; data = NULL; @@ -2374,14 +2578,18 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) if (err) goto out; + hash_algo = spec.hash_algo; + if (!hash_algo) + hash_algo = GCRY_MD_SHA1; /* Use the default. */ + /* Hash data. */ - hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1); + hash_n = gcry_md_get_algo_dlen (hash_algo); if (! hash_n) { err = gpg_error (GPG_ERR_INTERNAL); goto out; } - err = data_hash (data, data_size, GCRY_MD_SHA1, hash); + err = data_hash (data, data_size, hash_algo, hash); if (err) goto out; @@ -2392,14 +2600,17 @@ ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) /* Sign data. */ - ctrl->digest.algo = GCRY_MD_SHA1; + ctrl->digest.algo = hash_algo; memcpy (ctrl->digest.value, hash, hash_n); ctrl->digest.valuelen = hash_n; - ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2); + if ((spec.flags & SPEC_FLAG_USE_PKCS1V2)) + ctrl->digest.raw_value = 0; + else + ctrl->digest.raw_value = 1; ctrl->have_keygrip = 1; memcpy (ctrl->keygrip, key_grip, 20); - err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n); + err = data_sign (ctrl, &spec, &sig, &sig_n); out: @@ -2520,6 +2731,7 @@ reenter_compare_cb (struct pin_entry_info_s *pi) return -1; } + /* Store the ssh KEY into our local key storage and protect it after asking for a passphrase. Cache that passphrase. TTL is the maximum caching time for that key. If the key already exists in @@ -2570,7 +2782,6 @@ ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm) goto out; } - pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1); if (!pi) { diff --git a/agent/protect.c b/agent/protect.c index 68e1a04..d26573d 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -51,13 +51,14 @@ static struct { const char *algo; const char *parmlist; int prot_from, prot_to; + int ecc_hack; } protect_info[] = { { "rsa", "nedpqu", 2, 5 }, { "dsa", "pqgyx", 4, 4 }, { "elg", "pgyx", 3, 3 }, - { "ecdsa","pabgnqd", 6, 6 }, - { "ecdh", "pabgnqd", 6, 6 }, - { "ecc", "pabgnqd", 6, 6 }, + { "ecdsa","pabgnqd", 6, 6, 1 }, + { "ecdh", "pabgnqd", 6, 6, 1 }, + { "ecc", "pabgnqd", 6, 6, 1 }, { NULL } }; @@ -450,6 +451,8 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, unsigned long s2k_count) { int rc; + const char *parmlist; + int prot_from_idx, prot_to_idx; const unsigned char *s; const unsigned char *hash_begin, *hash_end; const unsigned char *prot_begin, *prot_end, *real_end; @@ -494,10 +497,13 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, if (!protect_info[infidx].algo) return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + parmlist = protect_info[infidx].parmlist; + prot_from_idx = protect_info[infidx].prot_from; + prot_to_idx = protect_info[infidx].prot_to; prot_begin = prot_end = NULL; - for (i=0; (c=protect_info[infidx].parmlist[i]); i++) + for (i=0; (c=parmlist[i]); i++) { - if (i == protect_info[infidx].prot_from) + if (i == prot_from_idx) prot_begin = s; if (*s != '(') return gpg_error (GPG_ERR_INV_SEXP); @@ -507,7 +513,20 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, if (!n) return gpg_error (GPG_ERR_INV_SEXP); if (n != 1 || c != *s) - return gpg_error (GPG_ERR_INV_SEXP); + { + if (n == 5 && !memcmp (s, "curve", 5) + && !i && protect_info[infidx].ecc_hack) + { + /* This is a private ECC key but the first parameter is + the name of the curve. We change the parameter list + here to the one we expect in this case. */ + parmlist = "?qd"; + prot_from_idx = 2; + prot_to_idx = 2; + } + else + return gpg_error (GPG_ERR_INV_SEXP); + } s += n; n = snext (&s); if (!n) @@ -516,7 +535,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, if (*s != ')') return gpg_error (GPG_ERR_INV_SEXP); depth--; - if (i == protect_info[infidx].prot_to) + if (i == prot_to_idx) prot_end = s; s++; } @@ -533,7 +552,6 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, assert (!depth); real_end = s-1; - /* Hash the stuff. Because the timestamp_exp won't get protected, we can't simply hash a continuous buffer but need to use several md_writes. */ diff --git a/agent/t-protect.c b/agent/t-protect.c index 67a60a8..02b614a 100644 --- a/agent/t-protect.c +++ b/agent/t-protect.c @@ -138,6 +138,24 @@ test_agent_protect (void) "\x55\x87\x11\x1C\x74\xE7\x7F\xA0\xBA\xE3\x34\x5D\x61\xBF\x29\x29\x29\x00" }; + struct key_spec key_ecdsa_valid = + { + "\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28" + "\x35\x3A\x65\x63\x64\x73\x61\x28\x35\x3A\x63\x75\x72\x76\x65\x31" + "\x30\x3A\x4E\x49\x53\x54\x20\x50\x2D\x32\x35\x36\x29\x28\x31\x3A" + "\x71\x36\x35\x3A\x04\x64\x5A\x12\x6F\x86\x7C\x43\x87\x2B\x7C\xAF" + "\x77\xFE\xD8\x22\x31\xEA\xE6\x89\x9F\xAA\xEA\x63\x26\xBC\x49\xED" + "\x85\xC6\xD2\xC9\x8B\x38\xD2\x78\x75\xE6\x1C\x27\x57\x01\xC5\xA1" + "\xE3\xF9\x1F\xBE\xCF\xC1\x72\x73\xFE\xA4\x58\xB6\x6A\x92\x7D\x33" + "\x1D\x02\xC9\xCB\x12\x29\x28\x31\x3A\x64\x33\x33\x3A\x00\x81\x2D" + "\x69\x9A\x5F\x5B\x6F\x2C\x99\x61\x36\x15\x6B\x44\xD8\x06\xC1\x54" + "\xC1\x4C\xFB\x70\x6A\xB6\x64\x81\x78\xF3\x94\x2F\x30\x5D\x29\x29" + "\x28\x37\x3A\x63\x6F\x6D\x6D\x65\x6E\x74\x32\x32\x3A\x2F\x68\x6F" + "\x6D\x65\x2F\x77\x6B\x2F\x2E\x73\x73\x68\x2F\x69\x64\x5F\x65\x63" + "\x64\x73\x61\x29\x29" + }; + + struct { const char *key; @@ -167,6 +185,9 @@ test_agent_protect (void) { key_rsa_bogus_1.string, "passphrase", 0, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 }, + { key_ecdsa_valid.string, + "passphrase", 0, 0, NULL, 0, 0, NULL, 0 }, + /* FIXME: add more test data. */ }; @@ -177,8 +198,8 @@ test_agent_protect (void) &specs[i].result, &specs[i].resultlen, 0); if (gpg_err_code (ret) != specs[i].ret_expected) { - printf ("agent_protect() returned '%i/%s'; expected '%i/%s'\n", - ret, gpg_strerror (ret), + printf ("agent_protect(%d) returned '%i/%s'; expected '%i/%s'\n", + i, ret, gpg_strerror (ret), specs[i].ret_expected, gpg_strerror (specs[i].ret_expected)); abort (); } diff --git a/common/ssh-utils.c b/common/ssh-utils.c index dc0ca26..0c71567 100644 --- a/common/ssh-utils.c +++ b/common/ssh-utils.c @@ -97,6 +97,34 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string) elems = "pqgy"; gcry_md_write (md, "\0\0\0\x07ssh-dss", 11); break; + case GCRY_PK_ECDSA: + /* We only support the 3 standard curves for now. It is just a + quick hack. */ + elems = "q"; + gcry_md_write (md, "\0\0\0\x13" "ecdsa-sha2-nistp", 20); + l2 = gcry_sexp_find_token (list, "curve", 0); + if (!l2) + elems = ""; + else + { + gcry_free (name); + name = gcry_sexp_nth_string (l2, 1); + gcry_sexp_release (l2); + l2 = NULL; + if (!name) + elems = ""; + else if (!strcmp (name, "NIST P-256") || !strcmp (name, "nistp256")) + gcry_md_write (md, "256\0\0\0\x08nistp256", 15); + else if (!strcmp (name, "NIST P-384") || !strcmp (name, "nistp384")) + gcry_md_write (md, "384\0\0\0\x08nistp521", 15); + else if (!strcmp (name, "NIST P-521") || !strcmp (name, "nistp521")) + gcry_md_write (md, "521\0\0\0\x08nistp521", 15); + else + elems = ""; + } + if (!*elems) + err = gpg_err_make (default_errsource, GPG_ERR_UNKNOWN_CURVE); + break; default: elems = ""; err = gpg_err_make (default_errsource, GPG_ERR_PUBKEY_ALGO); commit f76a0312c3794afd81fe1e172df15eb0612deae0 Author: Werner Koch Date: Tue Dec 11 14:50:34 2012 +0100 ssh: Rewrite a function for better maintainability * agent/command-ssh.c (ssh_signature_encoder_dsa): Rewrite. -- Using es_fopenmem instead of a preallocated buffer is safer and easier to read. diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 533793c..31195c4 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1189,65 +1189,51 @@ ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in *SEXP. Returns usual error code. */ static gpg_error_t -sexp_key_construct (gcry_sexp_t *sexp, +sexp_key_construct (gcry_sexp_t *r_sexp, ssh_key_type_spec_t key_spec, int secret, gcry_mpi_t *mpis, const char *comment) { const char *key_identifier[] = { "public-key", "private-key" }; - gcry_sexp_t sexp_new; - char *sexp_template; - size_t sexp_template_n; gpg_error_t err; + gcry_sexp_t sexp_new = NULL; + char *formatbuf = NULL; + void **arg_list = NULL; + int arg_idx; + estream_t format; const char *elems; size_t elems_n; - unsigned int i; - unsigned int j; - void **arg_list; + unsigned int i, j; - err = 0; - sexp_new = NULL; - arg_list = NULL; if (secret) elems = key_spec.elems_sexp_order; else elems = key_spec.elems_key_public; elems_n = strlen (elems); - /* - Calculate size for sexp_template_n: - - "(%s(%s)(comment%s))" -> 20 + sizeof (). - - mpi: (X%m) -> 5. - - */ - sexp_template_n = 20 + (elems_n * 5); - sexp_template = xtrymalloc (sexp_template_n); - if (! sexp_template) + format = es_fopenmem (0, "a+b"); + if (!format) { err = gpg_error_from_syserror (); goto out; } - /* Key identifier, algorithm identifier, mpis, comment. */ - arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1)); - if (! arg_list) + /* Key identifier, algorithm identifier, mpis, comment, and a NULL + as a safeguard. */ + arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1 + 1)); + if (!arg_list) { err = gpg_error_from_syserror (); goto out; } + arg_idx = 0; - i = 0; - arg_list[i++] = &key_identifier[secret]; - arg_list[i++] = &key_spec.identifier; + es_fputs ("(%s(%s", format); + arg_list[arg_idx++] = &key_identifier[secret]; + arg_list[arg_idx++] = &key_spec.identifier; - *sexp_template = 0; - sexp_template_n = 0; - sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s"); for (i = 0; i < elems_n; i++) { - sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)", - elems[i]); + es_fprintf (format, "(%c%%m)", elems[i]); if (secret) { for (j = 0; j < elems_n; j++) @@ -1256,27 +1242,42 @@ sexp_key_construct (gcry_sexp_t *sexp, } else j = i; - arg_list[i + 2] = &mpis[j]; + arg_list[arg_idx++] = &mpis[j]; } - sexp_template_n += sprintf (sexp_template + sexp_template_n, - ")(comment%%s))"); + es_fputs (")(comment%s))", format); + arg_list[arg_idx++] = &comment; + arg_list[arg_idx] = NULL; - arg_list[i + 2] = &comment; + es_putc (0, format); + if (es_ferror (format)) + { + err = gpg_error_from_syserror (); + goto out; + } + if (es_fclose_snatch (format, &formatbuf, NULL)) + { + err = gpg_error_from_syserror (); + goto out; + } + format = NULL; - err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list); + log_debug ("sexp formatbuf='%s' nargs=%d\n", formatbuf, arg_idx); + err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list); if (err) goto out; - *sexp = sexp_new; + *r_sexp = sexp_new; + err = 0; out: - + es_fclose (format); xfree (arg_list); - xfree (sexp_template); + xfree (formatbuf); return err; } + /* This functions breaks up the key contained in the S-Expression SEXP according to KEY_SPEC. The MPIs are bundled in a newly create list, which is to be stored in MPIS; a newly allocated string ----------------------------------------------------------------------- Summary of changes: agent/command-ssh.c | 478 +++++++++++++++++++++++++++++++++++++-------------- agent/protect.c | 34 +++- agent/t-protect.c | 25 +++- common/ssh-utils.c | 28 +++ 4 files changed, 422 insertions(+), 143 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 13 05:44:28 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 13 Dec 2012 05:44:28 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-45-g3e7cc25 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 3e7cc25d4a574d27e08322d9e82915ddcb8416f1 (commit) from 0d7cf7bb0669ca280e6259a9c34612a8ff56acda (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 3e7cc25d4a574d27e08322d9e82915ddcb8416f1 Author: NIIBE Yutaka Date: Thu Dec 13 13:36:23 2012 +0900 SCD: Fix the process of writing key or generating key. * scd/app-openpgp.c (store_fpr): Flush KEY-FPR and KEY-TIME. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 141b2b7..98af5e8 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -688,9 +688,9 @@ store_fpr (app_t app, int keynumber, u32 timestamp, xfree (buffer); tag = (card_version > 0x0007? 0xC7 : 0xC6) + keynumber; - flush_cache_item (app, tag); + flush_cache_item (app, 0xC5); tag2 = 0xCE + keynumber; - flush_cache_item (app, tag2); + flush_cache_item (app, 0xCD); rc = iso7816_put_data (app->slot, 0, tag, fpr, 20); if (rc) ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 13 05:58:48 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 13 Dec 2012 05:58:48 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-113-ge7dca3e 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 e7dca3e83ebd6df0a7ea55e97c3cd6e91be90af5 (commit) from 649b31c663b8674bc874b4ef283d714a13dc8cfe (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 e7dca3e83ebd6df0a7ea55e97c3cd6e91be90af5 Author: NIIBE Yutaka Date: Thu Dec 13 13:36:23 2012 +0900 SCD: Fix the process of writing key or generating key. * scd/app-openpgp.c (store_fpr): Flush KEY-FPR and KEY-TIME. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 5a9214c..5928ec6 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -688,9 +688,9 @@ store_fpr (app_t app, int keynumber, u32 timestamp, xfree (buffer); tag = (card_version > 0x0007? 0xC7 : 0xC6) + keynumber; - flush_cache_item (app, tag); + flush_cache_item (app, 0xC5); tag2 = 0xCE + keynumber; - flush_cache_item (app, tag2); + flush_cache_item (app, 0xCD); rc = iso7816_put_data (app->slot, 0, tag, fpr, 20); if (rc) ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 13 17:12:50 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 13 Dec 2012 17:12:50 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-114-g6177fb3 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 6177fb3c87f485fb654bbba492d04508755718b3 (commit) from e7dca3e83ebd6df0a7ea55e97c3cd6e91be90af5 (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 6177fb3c87f485fb654bbba492d04508755718b3 Author: Werner Koch Date: Mon Nov 12 15:38:51 2012 +0100 utf8conv.c: Add hacks for Android. * common/utf8conv.c [HAVE_ANDROID_SYSTEM]: Do not include iconv.h. (iconv_open, iconv_close, load_libiconv) [HAVE_ANDROID_SYSTEM]: New dummy functions. (set_native_charset) [HAVE_ANDROID_SYSTEM]: Force use of "utf-8". (jnlib_iconv_open) [HAVE_ANDROID_SYSTEM]: Act the same as under W32. (jnlib_iconv) [HAVE_ANDROID_SYSTEM]: Ditto. (jnlib_iconv_close) [HAVE_ANDROID_SYSTEM]: Ditto. -- Co-authored-by: Hans of Guardian diff --git a/common/utf8conv.c b/common/utf8conv.c index 1d64933..a45bb63 100644 --- a/common/utf8conv.c +++ b/common/utf8conv.c @@ -38,7 +38,7 @@ #include #endif #include -#ifndef HAVE_W32_SYSTEM +#if !defined HAVE_W32_SYSTEM && !defined HAVE_ANDROID_SYSTEM # include #endif @@ -56,9 +56,48 @@ static int no_translation; /* Set to true if we let simply pass through. */ static int use_iconv; /* iconv comversion fucntions required. */ +#ifdef HAVE_ANDROID_SYSTEM +/* Fake stuff to get things building. */ +typedef void *iconv_t; +#define ICONV_CONST + +static iconv_t +iconv_open (const char *tocode, const char *fromcode) +{ + (void)tocode; + (void)fromcode; + return (iconv_t)(-1); +} + +static size_t +iconv (iconv_t cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + (void)cd; + (void)inbuf; + (void)inbytesleft; + (void)outbuf; + (void)outbytesleft; + return (size_t)(0); +} + +static int +iconv_close (iconv_t cd) +{ + (void)cd; + return 0; +} + + +static int +load_libiconv (void) +{ + return -1; +} + +#elif defined HAVE_W32_SYSTEM /* Under W32 we dlopen the iconv dll and don't require any iconv related headers at all. However we need to define some stuff. */ -#ifdef HAVE_W32_SYSTEM typedef void *iconv_t; #ifndef ICONV_CONST #define ICONV_CONST @@ -170,7 +209,9 @@ set_native_charset (const char *newset) if (!newset) { -#ifdef HAVE_W32_SYSTEM +#ifdef HAVE_ANDROID_SYSTEM + newset = "utf-8"; +#elif defined HAVE_W32_SYSTEM static char codepage[30]; unsigned int cpno; const char *aliases; @@ -218,7 +259,7 @@ set_native_charset (const char *newset) } } -#else /*!HAVE_W32_SYSTEM*/ +#else /*!HAVE_W32_SYSTEM && !HAVE_ANDROID_SYSTEM*/ #ifdef HAVE_LANGINFO_CODESET newset = nl_langinfo (CODESET); @@ -252,7 +293,7 @@ set_native_charset (const char *newset) } newset = codepage; #endif /*!HAVE_LANGINFO_CODESET*/ -#endif /*!HAVE_W32_SYSTEM*/ +#endif /*!HAVE_W32_SYSTEM && !HAVE_ANDROID_SYSTEM*/ } full_newset = newset; @@ -291,10 +332,10 @@ set_native_charset (const char *newset) { iconv_t cd; -#ifdef HAVE_W32_SYSTEM +#if defined HAVE_W32_SYSTEM || defined HAVE_ANDROID_SYSTEM if (load_libiconv ()) return -1; -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM || HAVE_ANDROID_SYSTEM*/ cd = iconv_open (full_newset, "utf-8"); if (cd == (iconv_t)-1) @@ -717,10 +758,10 @@ utf8_to_native (const char *string, size_t length, int delim) jnlib_iconv_t jnlib_iconv_open (const char *tocode, const char *fromcode) { -#ifdef HAVE_W32_SYSTEM +#if defined HAVE_W32_SYSTEM || defined HAVE_ANDROID_SYSTEM if (load_libiconv ()) return (jnlib_iconv_t)(-1); -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM || HAVE_ANDROID_SYSTEM*/ return (jnlib_iconv_t)iconv_open (tocode, fromcode); } @@ -734,10 +775,10 @@ jnlib_iconv (jnlib_iconv_t cd, char **outbuf, size_t *outbytesleft) { -#ifdef HAVE_W32_SYSTEM +#if defined HAVE_W32_SYSTEM || defined HAVE_ANDROID_SYSTEM if (load_libiconv ()) return 0; -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM || HAVE_ANDROID_SYSTEM*/ return iconv ((iconv_t)cd, (char**)inbuf, inbytesleft, outbuf, outbytesleft); } @@ -747,10 +788,10 @@ jnlib_iconv (jnlib_iconv_t cd, int jnlib_iconv_close (jnlib_iconv_t cd) { -#ifdef HAVE_W32_SYSTEM +#if defined HAVE_W32_SYSTEM || defined HAVE_ANDROID_SYSTEM if (load_libiconv ()) return 0; -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM || HAVE_ANDROID_SYSTEM*/ return iconv_close ((iconv_t)cd); } @@ -826,4 +867,4 @@ utf8_to_wchar (const char *string) } return result; } -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM || HAVE_ANDROID_SYSTEM*/ ----------------------------------------------------------------------- Summary of changes: common/utf8conv.c | 69 ++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 55 insertions(+), 14 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 13 17:31:11 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 13 Dec 2012 17:31:11 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-22-g09dd073 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 09dd073096439f6ae0122e57321201f79045d3bc (commit) from e71dbf244a2b6e7edcca37ac9544000f0629de0e (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 09dd073096439f6ae0122e57321201f79045d3bc Author: NIIBE Yutaka Date: Thu Dec 13 13:36:23 2012 +0900 Card: Fix the process of writing key or generating key. * g10/app-openpgp.c (store_fpr): Flush KEY-FPR and KEY-TIME. -- (cherry picked from commit e7dca3e83ebd6df0a7ea55e97c3cd6e91be90af5) diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c index b2ca469..a3a977b 100644 --- a/g10/app-openpgp.c +++ b/g10/app-openpgp.c @@ -688,9 +688,9 @@ store_fpr (app_t app, int keynumber, u32 timestamp, xfree (buffer); tag = (card_version > 0x0007? 0xC7 : 0xC6) + keynumber; - flush_cache_item (app, tag); + flush_cache_item (app, 0xC5); tag2 = 0xCE + keynumber; - flush_cache_item (app, tag2); + flush_cache_item (app, 0xCD); rc = iso7816_put_data (app->slot, 0, tag, fpr, 20); if (rc) ----------------------------------------------------------------------- Summary of changes: g10/app-openpgp.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Dec 15 11:32:37 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 15 Dec 2012 11:32:37 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-27-ge33e74e 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 e33e74e3a4b2b4a0341f933410ddd5db7a12515e (commit) from eb541e35b80e5864bf7264157091afee3c4a8bfd (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 e33e74e3a4b2b4a0341f933410ddd5db7a12515e Author: Werner Koch Date: Sat Dec 15 11:28:00 2012 +0100 Fix potential heap corruption in "gpg -v --version" * g10/gpg.c (build_list): Rewrite to cope with buffer overflow in certain locales. * util/membuf.c (put_membuf_str): New. (get_membuf): Make LEN optional. -- This fixes an obvious bug in locales where the translated string is longer than the original. The bug could be exhibited by using LANG=ru_RU.utf8 gpg -v --version. En passant we also removed the trailing white space on continued lines. Reported-by: Dmitry V. Levin" diff --git a/THANKS b/THANKS index ae64d9f..791516e 100644 --- a/THANKS +++ b/THANKS @@ -49,6 +49,7 @@ David R. Bergstein dbergstein at home.com David Shaw dshaw at jabberwocky.com Detlef Lannert lannert at lannert.rz.uni-duesseldorf.de Dimitri dmitri at advantrix.com +Dmitry V. Levin ldv at altlinux dot org Dirk Lattermann dlatt at t-online.de Dirk Meyer dirk.meyer at dinoex.sub.org Disastry Disastry at saiknes.lv @@ -90,7 +91,7 @@ Ian McKellar imckellar at harvestroad.com.au Ingo Kl?cker kloecker at kde.org Ivo Timmermans itimmermans at bigfoot.com Jan Krueger max at physics.otago.ac.nz -Jan Niehusmann jan at gondor.com +Jan Niehusmann jan at gondor.com Janusz A. Urbanowicz alex at bofh.torun.pl James Troup james at nocrew.org Jason Woodward jason dot woodward at timesys dot com @@ -120,18 +121,18 @@ Karl Fogel kfogel at guanabana.onshore.com Karsten Thygesen karthy at kom.auc.dk Katsuhiro Kondou kondou at nec.co.jp Kazu Yamamoto kazu at iijlab.net -Kazuyoshi Kakihara +Kazuyoshi Kakihara Keith Clayton keith at claytons.org Kevin Ryde user42 at zip.com.au Klaus Singvogel ks at caldera.de Kurt Garloff garloff at suse.de Lars Kellogg-Stedman lars at bu.edu L. Sassaman rabbi at quickie.net -M Taylor mctaylor at privacy.nb.ca +M Taylor mctaylor at privacy.nb.ca Marcel Waldvogel mwa at arl.wustl.edu Marco d'Itri md at linux.it Marco Parrone marc0 at autistici.org -Marcus Brinkmann Marcus.Brinkmann at ruhr-uni-bochum.de +Marcus Brinkmann Marcus.Brinkmann at ruhr-uni-bochum.de Mark Adler madler at alumni.caltech.edu Mark Elbrecht snowball3 at bigfoot.com Mark Pettit pettit at yahoo-inc.com diff --git a/g10/gpg.c b/g10/gpg.c index 573bb90..96f9086 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -835,57 +835,53 @@ strusage( int level ) static char * -build_list( const char *text, char letter, - const char * (*mapf)(int), int (*chkf)(int) ) +build_list (const char *text, char letter, + const char * (*mapf)(int), int (*chkf)(int)) { - int i; - const char *s; - size_t n=strlen(text)+2; - char *list, *p, *line=NULL; - - if( maybe_setuid ) - secmem_init( 0 ); /* drop setuid */ - - for(i=0; i <= 110; i++ ) - if( !chkf(i) && (s=mapf(i)) ) - n += strlen(s) + 7 + 2; - list = xmalloc( 21 + n ); *list = 0; - for(p=NULL, i=0; i <= 110; i++ ) { - if( !chkf(i) && (s=mapf(i)) ) { - if( !p ) { - p = stpcpy( list, text ); - line=p; - } - else - p = stpcpy( p, ", "); + membuf_t mb; + int indent; + int i, j, len; + const char *s; + char *string; - if(strlen(line)>60) { - int spaces=strlen(text); + if (maybe_setuid) + secmem_init (0); /* Drop setuid */ - list=xrealloc(list,n+spaces+1); - /* realloc could move the block, so find the end again */ - p=list; - while(*p) - p++; + indent = strlen (text); + len = 0; + init_membuf (&mb, 512); - p=stpcpy(p, "\n"); - line=p; - for(;spaces;spaces--) - p=stpcpy(p, " "); + for (i=0; i <= 110; i++ ) + { + if (!chkf (i) && (s = mapf (i))) + { + if (mb.len - len > 60) + { + put_membuf_str (&mb, ",\n"); + len = mb.len; + for (j=0; j < indent; j++) + put_membuf_str (&mb, " "); } + else if (mb.len) + put_membuf_str (&mb, ", "); + else + put_membuf_str (&mb, text); - p = stpcpy(p, s ); - if(opt.verbose && letter) - { - char num[8]; - sprintf(num," (%c%d)",letter,i); - p = stpcpy(p,num); - } + put_membuf_str (&mb, s); + if (opt.verbose && letter) + { + char num[20]; + snprintf (num, sizeof num, " (%c%d)", letter, i); + put_membuf_str (&mb, num); + } } } - if( p ) - p = stpcpy(p, "\n" ); - return list; + if (mb.len) + put_membuf_str (&mb, "\n"); + put_membuf (&mb, "", 1); + + string = get_membuf (&mb, NULL); + return xrealloc (string, strlen (string)+1); } diff --git a/include/util.h b/include/util.h index 9303a50..3057b25 100644 --- a/include/util.h +++ b/include/util.h @@ -219,6 +219,7 @@ typedef struct private_membuf_s membuf_t; void init_membuf (membuf_t *mb, int initiallen); void put_membuf (membuf_t *mb, const void *buf, size_t len); +void put_membuf_str (membuf_t *mb, const char *buf); void *get_membuf (membuf_t *mb, size_t *len); diff --git a/util/membuf.c b/util/membuf.c index db3f5ac..3f7a61d 100644 --- a/util/membuf.c +++ b/util/membuf.c @@ -52,7 +52,7 @@ put_membuf (membuf_t *mb, const void *buf, size_t len) if (mb->len + len >= mb->size) { char *p; - + mb->size += len + 1024; p = xrealloc (mb->buf, mb->size); mb->buf = p; @@ -62,6 +62,13 @@ put_membuf (membuf_t *mb, const void *buf, size_t len) } +void +put_membuf_str (membuf_t *mb, const char *buf) +{ + put_membuf (mb, buf, strlen (buf)); +} + + void * get_membuf (membuf_t *mb, size_t *len) { @@ -75,7 +82,8 @@ get_membuf (membuf_t *mb, size_t *len) } p = mb->buf; - *len = mb->len; + if (len) + *len = mb->len; mb->buf = NULL; mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */ return p; ----------------------------------------------------------------------- Summary of changes: THANKS | 9 +++-- g10/gpg.c | 90 ++++++++++++++++++++++++++----------------------------- include/util.h | 1 + util/membuf.c | 12 ++++++- 4 files changed, 59 insertions(+), 53 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Dec 15 16:14:28 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Sat, 15 Dec 2012 16:14:28 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-46-gba9e974 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 ba9e974f1fd85b3dbbfb5e26d7a14f71d07c7cf2 (commit) from 3e7cc25d4a574d27e08322d9e82915ddcb8416f1 (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 ba9e974f1fd85b3dbbfb5e26d7a14f71d07c7cf2 Author: David Shaw Date: Sat Dec 15 10:11:11 2012 -0500 Fix issue 1446: honor ports given in SRV responses. * common/http.c (send_request, connect_server, http_open): Use a struct srv instead of a single srvtag so we can pass the chosen host and port back to the caller. (connect_server): Use the proper port in the HAVE_GETADDRINFO case. * keyserver/curl-shim.c (curl_easy_perform): Use struct srv and log chosen host and port. * keyserver/gpgkeys_hkp.c (main): Properly take the port given by SRV. diff --git a/common/http.c b/common/http.c index c12bd2b..ea8b8d5 100644 --- a/common/http.c +++ b/common/http.c @@ -1,6 +1,6 @@ /* http.c - HTTP protocol handler * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -129,12 +129,12 @@ static int insert_escapes (char *buffer, const char *string, const char *special); static uri_tuple_t parse_tuple (char *string); static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy, - const char *srvtag,strlist_t headers); + struct http_srv *srv,strlist_t headers); static char *build_rel_path (parsed_uri_t uri); static gpg_error_t parse_response (http_t hd); static int connect_server (const char *server, unsigned short port, - unsigned int flags, const char *srvtag); + unsigned int flags, struct http_srv *srv); static gpg_error_t write_server (int sock, const char *data, size_t length); #ifdef HTTP_USE_ESTREAM @@ -317,7 +317,7 @@ http_register_tls_callback ( gpg_error_t (*cb) (http_t, void *, int) ) gpg_error_t http_open (http_t *r_hd, http_req_t reqtype, const char *url, const char *auth, unsigned int flags, const char *proxy, - void *tls_context, const char *srvtag,strlist_t headers) + void *tls_context, struct http_srv *srv, strlist_t headers) { gpg_error_t err; http_t hd; @@ -338,7 +338,7 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url, err = http_parse_uri (&hd->uri, url); if (!err) - err = send_request (hd, auth, proxy, srvtag, headers); + err = send_request (hd, auth, proxy, srv, headers); if (err) { @@ -457,12 +457,13 @@ http_wait_response (http_t hd) gpg_error_t http_open_document (http_t *r_hd, const char *document, const char *auth, unsigned int flags, const char *proxy, - void *tls_context, const char *srvtag,strlist_t headers) + void *tls_context, struct http_srv *srv, + strlist_t headers) { gpg_error_t err; err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags, - proxy, tls_context, srvtag, headers); + proxy, tls_context, srv, headers); if (err) return err; @@ -836,7 +837,7 @@ parse_tuple (char *string) */ static gpg_error_t send_request (http_t hd, const char *auth, - const char *proxy,const char *srvtag,strlist_t headers) + const char *proxy, struct http_srv *srv, strlist_t headers) { gnutls_session_t tls_session; gpg_error_t err; @@ -894,13 +895,13 @@ send_request (http_t hd, const char *auth, hd->sock = connect_server (*uri->host ? uri->host : "localhost", uri->port ? uri->port : 80, - hd->flags, srvtag); + hd->flags, srv); save_errno = errno; http_release_parsed_uri (uri); } else { - hd->sock = connect_server (server, port, hd->flags, srvtag); + hd->sock = connect_server (server, port, hd->flags, srv); save_errno = errno; } @@ -1540,12 +1541,12 @@ start_server () error. ERRNO is set on error. */ static int connect_server (const char *server, unsigned short port, - unsigned int flags, const char *srvtag) + unsigned int flags, struct http_srv *srv) { int sock = -1; int srvcount = 0; int hostfound = 0; - int srv, connected; + int srvindex, connected, chosen=-1; int last_errno = 0; struct srventry *serverlist = NULL; @@ -1587,14 +1588,14 @@ connect_server (const char *server, unsigned short port, #ifdef USE_DNS_SRV /* Do the SRV thing */ - if (srvtag) + if (srv && srv->srvtag) { /* We're using SRV, so append the tags. */ - if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME) + if (1+strlen (srv->srvtag) + 6 + strlen (server) + 1 <= MAXDNAME) { char srvname[MAXDNAME]; - stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag), + stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srv->srvtag), "._tcp."), server); srvcount = getsrv (srvname, &serverlist); } @@ -1616,15 +1617,15 @@ connect_server (const char *server, unsigned short port, #ifdef HAVE_GETADDRINFO connected = 0; - for (srv=0; srv < srvcount && !connected; srv++) + for (srvindex=0; srvindex < srvcount && !connected; srvindex++) { struct addrinfo hints, *res, *ai; char portstr[35]; - sprintf (portstr, "%hu", port); + sprintf (portstr, "%hu", serverlist[srvindex].port); memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res)) + if (getaddrinfo (serverlist[srvindex].target, portstr, &hints, &res)) continue; /* Not found - try next one. */ hostfound = 1; @@ -1646,13 +1647,16 @@ connect_server (const char *server, unsigned short port, if (connect (sock, ai->ai_addr, ai->ai_addrlen)) last_errno = errno; else - connected = 1; + { + connected = 1; + chosen = srvindex; + } } freeaddrinfo (res); } #else /* !HAVE_GETADDRINFO */ connected = 0; - for (srv=0; srv < srvcount && !connected; srv++) + for (srvindex=0; srvindex < srvcount && !connected; srvindex++) { int i; struct hostent *host = NULL; @@ -1661,7 +1665,7 @@ connect_server (const char *server, unsigned short port, /* Note: This code is not thread-safe. */ memset (&addr, 0, sizeof (addr)); - host = gethostbyname (serverlist[srv].target); + host = gethostbyname (serverlist[srvindex].target); if (!host) continue; hostfound = 1; @@ -1680,15 +1684,15 @@ connect_server (const char *server, unsigned short port, if (addr.sin_family != AF_INET) { log_error ("unknown address family for `%s'\n", - serverlist[srv].target); + serverlist[srvindex].target); xfree (serverlist); return -1; } - addr.sin_port = htons (serverlist[srv].port); + addr.sin_port = htons (serverlist[srvindex].port); if (host->h_length != 4) { log_error ("illegal address length for `%s'\n", - serverlist[srv].target); + serverlist[srvindex].target); xfree (serverlist); return -1; } @@ -1702,12 +1706,19 @@ connect_server (const char *server, unsigned short port, else { connected = 1; + chosen = srvindex; break; } } } #endif /* !HAVE_GETADDRINFO */ + if(chosen>-1 && srv) + { + srv->used_server = xstrdup (serverlist[chosen].target); + srv->used_port = serverlist[chosen].port; + } + xfree (serverlist); if (!connected) diff --git a/common/http.h b/common/http.h index 28a5304..2b17ab7 100644 --- a/common/http.h +++ b/common/http.h @@ -1,6 +1,6 @@ /* http.h - HTTP protocol handler * Copyright (C) 1999, 2000, 2001, 2003, - * 2006 Free Software Foundation, Inc. + * 2006, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -76,13 +76,20 @@ gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri); void http_release_parsed_uri (parsed_uri_t uri); +struct http_srv +{ + const char *srvtag; + char *used_server; + unsigned short used_port; +}; + gpg_error_t http_open (http_t *r_hd, http_req_t reqtype, const char *url, const char *auth, unsigned int flags, const char *proxy, void *tls_context, - const char *srvtag, + struct http_srv *srv, strlist_t headers); void http_start_data (http_t hd); @@ -97,7 +104,7 @@ gpg_error_t http_open_document (http_t *r_hd, unsigned int flags, const char *proxy, void *tls_context, - const char *srvtag, + struct http_srv *srv, strlist_t headers); #ifdef HTTP_USE_ESTREAM diff --git a/keyserver/curl-shim.c b/keyserver/curl-shim.c index 500d9f5..136436a 100644 --- a/keyserver/curl-shim.c +++ b/keyserver/curl-shim.c @@ -1,7 +1,8 @@ /* curl-shim.c - Implement a small subset of the curl API in terms of * the iobuf HTTP API * - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009, + * 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -174,6 +175,9 @@ curl_easy_perform(CURL *curl) CURLcode err=CURLE_OK; const char *errstr=NULL; char *proxy=NULL; + struct http_srv srv; + + memset(&srv,0,sizeof(srv)); /* Emulate the libcurl proxy behavior. If the calling program set a proxy, use it. If it didn't set a proxy or set it to NULL, check @@ -186,10 +190,17 @@ curl_easy_perform(CURL *curl) else proxy=getenv(HTTP_PROXY_ENV); + if(curl->srvtag) + srv.srvtag=curl->srvtag; + if(curl->flags.verbose) { fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null"); fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url); + if(srv.srvtag) + fprintf(curl->errors, + "* SRV tag is \"%s\": host and port may be overridden\n", + srv.srvtag); fprintf(curl->errors,"* HTTP auth is \"%s\"\n", curl->auth?curl->auth:"null"); fprintf(curl->errors,"* HTTP method is %s\n", @@ -199,12 +210,16 @@ curl_easy_perform(CURL *curl) if(curl->flags.post) { rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth, - 0, proxy, NULL, curl->srvtag, + 0, proxy, NULL, &srv, curl->headers?curl->headers->list:NULL); if (!rc) { unsigned int post_len = strlen(curl->postfields); + if(curl->flags.verbose && srv.used_server && srv.used_port) + fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n", + srv.used_server, srv.used_port); + es_fprintf (http_get_write_ptr (curl->hd), "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: %u\r\n", post_len); @@ -223,10 +238,14 @@ curl_easy_perform(CURL *curl) else { rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth, - 0, proxy, NULL, curl->srvtag, + 0, proxy, NULL, &srv, curl->headers?curl->headers->list:NULL); if (!rc) { + if(curl->flags.verbose && srv.used_server && srv.used_port) + fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n", + srv.used_server, srv.used_port); + rc = http_wait_response (curl->hd); curl->status = http_get_status_code (curl->hd); if (!rc) @@ -268,6 +287,8 @@ curl_easy_perform(CURL *curl) } } + xfree(srv.used_server); + switch(gpg_err_code (rc)) { case 0: diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index ee6421a..42113b4 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -1,6 +1,6 @@ /* gpgkeys_hkp.c - talk to an HKP keyserver * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -693,6 +693,7 @@ main(int argc,char *argv[]) goto fail; } + /* Defaults */ if(ks_strcasecmp(opt->scheme,"hkps")==0) { proto="https"; @@ -725,11 +726,9 @@ main(int argc,char *argv[]) goto fail; } - /* If the user gives a :port, then disable SRV. The semantics of a - specified port and SRV do not play well together. */ - if(opt->port) - port=opt->port; - else if(try_srv) + /* Only use SRV if the user does not provide a :port. The semantics + of a specified port and SRV do not play well together. */ + if(!opt->port && try_srv) { char *srvtag; @@ -754,6 +753,11 @@ main(int argc,char *argv[]) #endif } + /* If the user provided a port (or it came in via SRV, above), + replace the default. */ + if(opt->port) + port=opt->port; + curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer); if(opt->auth) ----------------------------------------------------------------------- Summary of changes: common/http.c | 59 +++++++++++++++++++++++++++------------------- common/http.h | 13 ++++++++-- keyserver/curl-shim.c | 27 +++++++++++++++++++-- keyserver/gpgkeys_hkp.c | 16 ++++++++---- 4 files changed, 79 insertions(+), 36 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Dec 15 16:37:52 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Sat, 15 Dec 2012 16:37:52 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-47-gcbe98b2 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 cbe98b2cb1e40ba253300e604996681ae191e363 (commit) from ba9e974f1fd85b3dbbfb5e26d7a14f71d07c7cf2 (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 cbe98b2cb1e40ba253300e604996681ae191e363 Author: David Shaw Date: Sat Dec 15 10:35:19 2012 -0500 Part of issue 1447: Pass proper Host header when SRV is used. * common/http.c (send_request, connect_server): Set proper Host header (no :port, host is that of the SRV) when SRV is used in the curl-shim. diff --git a/common/http.c b/common/http.c index ea8b8d5..5b67acc 100644 --- a/common/http.c +++ b/common/http.c @@ -1009,7 +1009,7 @@ send_request (http_t hd, const char *auth, { char portstr[35]; - if (port == 80) + if (port == 80 || (srv && srv->used_server)) *portstr = 0; else sprintf (portstr, ":%u", port); @@ -1544,7 +1544,7 @@ connect_server (const char *server, unsigned short port, unsigned int flags, struct http_srv *srv) { int sock = -1; - int srvcount = 0; + int srvcount = 0, fakesrv = 0; int hostfound = 0; int srvindex, connected, chosen=-1; int last_errno = 0; @@ -1613,6 +1613,7 @@ connect_server (const char *server, unsigned short port, strncpy (serverlist->target, server, MAXDNAME); serverlist->target[MAXDNAME-1] = '\0'; srvcount = 1; + fakesrv = 1; } #ifdef HAVE_GETADDRINFO @@ -1713,7 +1714,7 @@ connect_server (const char *server, unsigned short port, } #endif /* !HAVE_GETADDRINFO */ - if(chosen>-1 && srv) + if(!fakesrv && chosen>-1 && srv) { srv->used_server = xstrdup (serverlist[chosen].target); srv->used_port = serverlist[chosen].port; ----------------------------------------------------------------------- Summary of changes: common/http.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 05:55:05 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Tue, 18 Dec 2012 05:55:05 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-48-g6b1f710 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 6b1f71055ebab36989e2089cfde319d2ba40ada7 (commit) from cbe98b2cb1e40ba253300e604996681ae191e363 (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 6b1f71055ebab36989e2089cfde319d2ba40ada7 Author: David Shaw Date: Mon Dec 17 23:52:15 2012 -0500 Issue 1447: Pass proper Host header and SNI when SRV is used with curl. * configure.ac: Check for inet_ntop. * m4/libcurl.m4: Provide a #define for the version of the curl library. * keyserver/gpgkeys_hkp.c (main, srv_replace): Call getaddrinfo() on each target. Once we find one that resolves to an address (whether IPv4 or IPv6), pass it into libcurl via CURLOPT_RESOLVE using the SRV name as the "host". Force the HTTP Host header to be the same. diff --git a/configure.ac b/configure.ac index 6c65798..b1946a3 100644 --- a/configure.ac +++ b/configure.ac @@ -1107,7 +1107,7 @@ AC_FUNC_VPRINTF AC_FUNC_FORK AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap]) AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r]) -AC_CHECK_FUNCS([unsetenv fcntl ftruncate]) +AC_CHECK_FUNCS([unsetenv fcntl ftruncate inet_ntop]) AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime]) AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale]) AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe stat getaddrinfo]) diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index 42113b4..8e35783 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -40,6 +40,19 @@ #endif #ifdef HAVE_LIBCURL #include +/* This #define rigamarole is to enable a hack to fake DNS SRV using + libcurl. It only works if we have getaddrinfo(), inet_ntop(), and + a modern enough version of libcurl (7.21.3) so we can use + CURLOPT_RESOLVE to feed the resolver from the outside to force + libcurl to pass the right SNI. */ +#if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP) && LIBCURL_VERNUM >= 0x071503 +#include +#include +#include +#include +#else +#undef USE_DNS_SRV +#endif #else #include "curl-shim.h" #endif @@ -499,19 +512,29 @@ fail_all(struct keylist *keylist,int err) } } -#ifdef HAVE_LIBCURL +#if defined(HAVE_LIBCURL) && defined(USE_DNS_SRV) /* If there is a SRV record, take the highest ranked possibility. - This is a hack, as we don't proceed downwards. */ + This is a hack, as we don't proceed downwards if we can't + connect(), but only if we can't getaddinfo(). All this should + ideally be replaced by actual SRV support in libcurl someday! */ + +#define HOST_HEADER "Host:" + static void -srv_replace(const char *srvtag) +srv_replace(const char *srvtag, + struct curl_slist **headers,struct curl_slist **resolve) { -#ifdef USE_DNS_SRV struct srventry *srvlist=NULL; - int srvcount; + int srvcount, srvindex; + char *portstr; if(!srvtag) return; + portstr=malloc (MAX_PORT); + if(!portstr) + return; + if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME) { char srvname[MAXDNAME]; @@ -523,27 +546,74 @@ srv_replace(const char *srvtag) srvcount=getsrv(srvname,&srvlist); } - if(srvlist) + for(srvindex=0 ; srvindextarget); - newport=malloc(MAX_PORT); - if(newname && newport) + if (getaddrinfo (srvlist[srvindex].target, portstr, &hints, &res) == 0) { - free(opt->host); - free(opt->port); - opt->host=newname; - snprintf(newport,MAX_PORT,"%u",srvlist->port); - opt->port=newport; + /* Very safe */ + char ipaddr[INET_ADDRSTRLEN+INET6_ADDRSTRLEN]; + + if((res->ai_family==AF_INET + && inet_ntop (res->ai_family, + &((struct sockaddr_in *)res->ai_addr)->sin_addr, + ipaddr,sizeof(ipaddr))) + || (res->ai_family==AF_INET6 + && inet_ntop (res->ai_family, + &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, + ipaddr,sizeof(ipaddr)))) + { + char *entry,*host; + + entry=malloc (strlen(opt->host)+1 + +strlen(portstr)+1+strlen(ipaddr)+1); + + host=malloc (strlen(HOST_HEADER)+1+strlen(opt->host)+1); + + if(entry && host) + { + sprintf (entry, "%s:%s:%s", opt->host, portstr, ipaddr); + sprintf (host, "%s %s", HOST_HEADER, opt->host); + + *resolve=curl_slist_append (*resolve,entry); + *headers=curl_slist_append (*headers,host); + + if(*resolve && *headers) + { + if(curl_easy_setopt (curl, + CURLOPT_RESOLVE,*resolve)==CURLE_OK) + { + if(opt->debug) + fprintf (console, "gpgkeys: Faking %s SRV from" + " %s to %s:%u\n", + srvtag, opt->host, + srvlist[srvindex].target, + srvlist[srvindex].port); + + free (opt->port); + opt->port=portstr; + portstr=NULL; + } + } + } + + free (entry); + free (host); + } + + freeaddrinfo (res); } else - { - free(newname); - free(newport); - } + continue; /* Not found */ } -#endif + + free (srvlist); + free (portstr); } #endif @@ -564,7 +634,7 @@ main(int argc,char *argv[]) int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; char *proxy=NULL; - struct curl_slist *headers=NULL; + struct curl_slist *headers=NULL,*resolve=NULL; console=stderr; @@ -726,6 +796,13 @@ main(int argc,char *argv[]) goto fail; } + if(opt->debug) + { + fprintf(console,"gpgkeys: curl version = %s\n",curl_version()); + curl_easy_setopt(curl,CURLOPT_STDERR,console); + curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); + } + /* Only use SRV if the user does not provide a :port. The semantics of a specified port and SRV do not play well together. */ if(!opt->port && try_srv) @@ -744,8 +821,12 @@ main(int argc,char *argv[]) This isn't as good as true SRV support, as we do not try all possible targets at one particular level and work our way down the list, but it's better than nothing. */ - srv_replace(srvtag); +#ifdef USE_DNS_SRV + srv_replace(srvtag,&headers,&resolve); #else + fprintf(console,"gpgkeys: try-dns-srv was requested, but not SRV capable\n"); +#endif +#else /* !HAVE_LIBCURL */ /* We're using our internal curl shim, so we can use its (true) SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real libcurl option. It's specific to our shim. */ @@ -763,13 +844,6 @@ main(int argc,char *argv[]) if(opt->auth) curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth); - if(opt->debug) - { - fprintf(console,"gpgkeys: curl version = %s\n",curl_version()); - curl_easy_setopt(curl,CURLOPT_STDERR,console); - curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); - } - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); @@ -971,6 +1045,7 @@ main(int argc,char *argv[]) free_ks_options(opt); curl_slist_free_all(headers); + curl_slist_free_all(resolve); if(curl) curl_easy_cleanup(curl); diff --git a/m4/libcurl.m4 b/m4/libcurl.m4 index 7d1dbd3..fe9809e 100644 --- a/m4/libcurl.m4 +++ b/m4/libcurl.m4 @@ -65,6 +65,10 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG], AC_PROG_AWK _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" + # More recent versions of curl-config have a direct --vernum + # option, but we'd like this code to work with older versions as + # well, so just convert --version. + _libcurl_vernum_parse="eval $AWK '{printf \"0x%06X\",\$NF}'" _libcurl_try_link=yes @@ -184,6 +188,10 @@ x=CURLOPT_VERBOSE; AC_SUBST(LIBCURL_CPPFLAGS) AC_SUBST(LIBCURL) + _libcurl_vernum=`echo $_libcurl_version | $_libcurl_vernum_parse` + + AC_DEFINE_UNQUOTED(LIBCURL_VERNUM,$_libcurl_vernum,[The version of the libcurl library in packed hex form]) + for _libcurl_feature in $_libcurl_features ; do AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes @@ -224,6 +232,7 @@ x=CURLOPT_VERBOSE; unset _libcurl_protocol unset _libcurl_protocols unset _libcurl_version + unset _libcurl_vernum unset _libcurl_ldflags fi ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 +- keyserver/gpgkeys_hkp.c | 133 ++++++++++++++++++++++++++++++++++++---------- m4/libcurl.m4 | 9 +++ 3 files changed, 114 insertions(+), 30 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 06:11:38 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Tue, 18 Dec 2012 06:11:38 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-49-g732f3d1 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 732f3d1d4786239db5f31f82cc04ec79326cc13c (commit) from 6b1f71055ebab36989e2089cfde319d2ba40ada7 (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 732f3d1d4786239db5f31f82cc04ec79326cc13c Author: David Shaw Date: Tue Dec 18 00:08:51 2012 -0500 No point in defaulting try-dns-srv to on if we don't have SRV support. * keyserver/gpgkeys_hkp.c (main): Only default try-dns-srv to on if we have SRV support in the first place. diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index 8e35783..73f5e56 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -629,13 +629,20 @@ show_help (FILE *fp) int main(int argc,char *argv[]) { - int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1; + int arg,ret=KEYSERVER_INTERNAL_ERROR; char line[MAX_LINE]; int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; char *proxy=NULL; struct curl_slist *headers=NULL,*resolve=NULL; + /* Only default this to on if we have SRV support */ +#ifdef USE_DNS_SRV + int try_srv = 1; +#else + int try_srv = 0; +#endif + console=stderr; /* Kludge to implement standard GNU options. */ ----------------------------------------------------------------------- Summary of changes: keyserver/gpgkeys_hkp.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 18:12:13 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 18:12:13 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-115-g41d5643 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 41d564333d35c923f473aa90625d91f8fe18cd0b (commit) from 6177fb3c87f485fb654bbba492d04508755718b3 (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 41d564333d35c923f473aa90625d91f8fe18cd0b Author: Werner Koch Date: Tue Dec 18 18:06:41 2012 +0100 common: Add meta option ignore-invalid-option. * common/argparse.c (iio_item_def_s, IIO_ITEM_DEF): New. (initialize): Init field IIO_LIST. (ignore_invalid_option_p): New. (ignore_invalid_option_add): New. (ignore_invalid_option_clear): New. (optfile_parse): Implement meta option. -- This option is currently of no use. However, as soon as it has been deployed in all stable versions of GnuPG, it will allow the use of the same configuration file with an old and a new version of GnuPG. For example: If a new version implements the option "foobar", and a user uses it in gpg.conf, an old version of gpg would bail out with the error "invalid option". To avoid that the following line can be put above that option in gpg.conf ignore-invalid-option foobar This meta option may be given several times or several option names may be given as arguments (space delimited). Note that this option is not available on the command line. diff --git a/common/argparse.c b/common/argparse.c index 3021745..6a90920 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -1,6 +1,6 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling * Copyright (C) 1998, 1999, 2000, 2001, 2006 - * 2007, 2008 Free Software Foundation, Inc. + * 2007, 2008, 2012 Free Software Foundation, Inc. * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -155,6 +155,16 @@ struct alias_def_s { const char *value; /* ptr into name */ }; + +/* Object to store the names for the --ignore-invalid-option option. + This is a simple linked list. */ +typedef struct iio_item_def_s *IIO_ITEM_DEF; +struct iio_item_def_s +{ + IIO_ITEM_DEF next; + char name[1]; /* String with the long option name. */ +}; + static const char *(*strusage_handler)( int ) = NULL; static int (*custom_outfnc) (int, const char *); @@ -226,6 +236,7 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) arg->internal.stopped = 0; arg->internal.aliases = NULL; arg->internal.cur_alias = NULL; + arg->internal.iio_list = NULL; arg->err = 0; arg->flags |= 1<<15; /* Mark as initialized. */ if ( *arg->argc < 0 ) @@ -308,6 +319,111 @@ store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) #endif } + +/* Return true if KEYWORD is in the ignore-invalid-option list. */ +static int +ignore_invalid_option_p (ARGPARSE_ARGS *arg, const char *keyword) +{ + IIO_ITEM_DEF item = arg->internal.iio_list; + + for (; item; item = item->next) + if (!strcmp (item->name, keyword)) + return 1; + return 0; +} + + +/* Add the keywords up to the next LF to the list of to be ignored + options. After returning FP will either be at EOF or the next + character read wll be the first of a new line. The function + returns 0 on success or true on malloc failure. */ +static int +ignore_invalid_option_add (ARGPARSE_ARGS *arg, FILE *fp) +{ + IIO_ITEM_DEF item; + int c; + char name[100]; + int namelen = 0; + int ready = 0; + enum { skipWS, collectNAME, skipNAME, addNAME} state = skipWS; + + while (!ready) + { + c = getc (fp); + if (c == '\n') + ready = 1; + else if (c == EOF) + { + c = '\n'; + ready = 1; + } + again: + switch (state) + { + case skipWS: + if (!isascii (c) || !isspace(c)) + { + namelen = 0; + state = collectNAME; + goto again; + } + break; + + case collectNAME: + if (isspace (c)) + { + state = addNAME; + goto again; + } + else if (namelen < DIM(name)-1) + name[namelen++] = c; + else /* Too long. */ + state = skipNAME; + break; + + case skipNAME: + if (isspace (c)) + { + state = skipWS; + goto again; + } + break; + + case addNAME: + name[namelen] = 0; + if (!ignore_invalid_option_p (arg, name)) + { + item = jnlib_malloc (sizeof *item + namelen); + if (!item) + return 1; + strcpy (item->name, name); + item->next = (IIO_ITEM_DEF)arg->internal.iio_list; + arg->internal.iio_list = item; + } + state = skipWS; + goto again; + } + } + return 0; +} + + +/* Clear the entire ignore-invalid-option list. */ +static void +ignore_invalid_option_clear (ARGPARSE_ARGS *arg) +{ + IIO_ITEM_DEF item, tmpitem; + + for (item = arg->internal.iio_list; item; item = tmpitem) + { + tmpitem = item->next; + jnlib_free (item); + } + arg->internal.iio_list = NULL; +} + + + /**************** * Get options from a file. * Lines starting with '#' are comment lines. @@ -317,6 +433,10 @@ store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) * are not valid here. * The special keyword "alias" may be used to store alias definitions, * which are later expanded like long options. + * The option + * ignore-invalid-option OPTIONNAMEs + * is recognized and updates a list of option which should be ignored if they + * are not defined. * Caller must free returned strings. * If called with FP set to NULL command line args are parse instead. * @@ -363,9 +483,23 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, idx = i; arg->r_opt = opts[idx].short_opt; if (!opts[idx].short_opt ) - arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) - ? ARGPARSE_INVALID_COMMAND - : ARGPARSE_INVALID_OPTION); + { + if (!strcmp (keyword, "ignore-invalid-option")) + { + /* No argument - ignore this meta option. */ + state = i = 0; + continue; + } + else if (ignore_invalid_option_p (arg, keyword)) + { + /* This invalid option is in the iio list. */ + state = i = 0; + continue; + } + arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) + ? ARGPARSE_INVALID_COMMAND + : ARGPARSE_INVALID_OPTION); + } else if (!(opts[idx].flags & 7)) arg->r_type = 0; /* Does not take an arg. */ else if ((opts[idx].flags & 8) ) @@ -453,6 +587,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, } else if (c == EOF) { + ignore_invalid_option_clear (arg); if (ferror (fp)) arg->r_opt = ARGPARSE_READ_ERROR; else @@ -486,6 +621,18 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, in_alias = 1; state = 3; } + else if (!strcmp (keyword, "ignore-invalid-option")) + { + if (ignore_invalid_option_add (arg, fp)) + { + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + state = i = 0; + ++*lineno; + } + else if (ignore_invalid_option_p (arg, keyword)) + state = 1; /* Process like a comment. */ else { arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) @@ -615,7 +762,7 @@ find_long_option( ARGPARSE_ARGS *arg, return i; } } - return -1; + return -1; /* Not found. */ } int @@ -1204,7 +1351,7 @@ strusage( int level ) break; case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2011 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2012 Free Software Foundation, Inc."; break; case 15: p = "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n"; diff --git a/common/argparse.h b/common/argparse.h index c8f4c60..a36218f 100644 --- a/common/argparse.h +++ b/common/argparse.h @@ -60,6 +60,7 @@ typedef struct const char *last; void *aliases; const void *cur_alias; + void *iio_list; } internal; /* Private - do not change. */ } ARGPARSE_ARGS; ----------------------------------------------------------------------- Summary of changes: common/argparse.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++-- common/argparse.h | 1 + 2 files changed, 154 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 18:32:07 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 18:32:07 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-28-g8044a5a 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 8044a5acea80cb749159cd725e95bad246be5f72 (commit) from e33e74e3a4b2b4a0341f933410ddd5db7a12515e (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 8044a5acea80cb749159cd725e95bad246be5f72 Author: Werner Koch Date: Tue Dec 18 18:26:56 2012 +0100 Add meta option ignore-invalid-option. * util/argparse.c (iio_item_def_s, IIO_ITEM_DEF): New. (initialize): Init field IIO_LIST. (ignore_invalid_option_p): New. (ignore_invalid_option_add): New. (ignore_invalid_option_clear): New. (optfile_parse): Implement meta option. -- This option is currently of no use. However, as soon as it has been deployed in all stable versions of GnuPG, it will allow the use of the same configuration file with an old and a new version of GnuPG. For example: If a new version implements the option "foobar", and a user uses it in gpg.conf, an old version of gpg would bail out with the error "invalid option". To avoid that the following line can be put above that option in gpg.conf ignore-invalid-option foobar This meta option may be given several times or several option names may be given as arguments (space delimited). Note that this option is not available on the command line. (backported from commit 41d564333d35c923f473aa90625d91f8fe18cd0b) diff --git a/include/util.h b/include/util.h index 3057b25..0eb6281 100644 --- a/include/util.h +++ b/include/util.h @@ -49,6 +49,7 @@ typedef struct { const char *last; void *aliases; const void *cur_alias; + void *iio_list; } internal; /* DO NOT CHANGE */ } ARGPARSE_ARGS; diff --git a/util/argparse.c b/util/argparse.c index e28a181..542957d 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -133,6 +133,15 @@ struct alias_def_s { const char *value; /* ptr into name */ }; +/* Object to store the names for the --ignore-invalid-option option. + This is a simple linked list. */ +typedef struct iio_item_def_s *IIO_ITEM_DEF; +struct iio_item_def_s +{ + IIO_ITEM_DEF next; + char name[1]; /* String with the long option name. */ +}; + static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); static void show_help(ARGPARSE_OPTS *opts, unsigned flags); static void show_version(void); @@ -147,6 +156,7 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) arg->internal.stopped = 0; arg->internal.aliases = NULL; arg->internal.cur_alias = NULL; + arg->internal.iio_list = NULL; arg->err = 0; arg->flags |= 1<<15; /* mark initialized */ if( *arg->argc < 0 ) @@ -219,6 +229,105 @@ store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) #endif } + +/* Return true if KEYWORD is in the ignore-invalid-option list. */ +static int +ignore_invalid_option_p (ARGPARSE_ARGS *arg, const char *keyword) +{ + IIO_ITEM_DEF item = arg->internal.iio_list; + + for (; item; item = item->next) + if (!strcmp (item->name, keyword)) + return 1; + return 0; +} + + +/* Add the keywords up to the next LF to the list of to be ignored + options. After returning FP will either be at EOF or the next + character read wll be the first of a new line. */ +static void +ignore_invalid_option_add (ARGPARSE_ARGS *arg, FILE *fp) +{ + IIO_ITEM_DEF item; + int c; + char name[100]; + int namelen = 0; + int ready = 0; + enum { skipWS, collectNAME, skipNAME, addNAME} state = skipWS; + + while (!ready) + { + c = getc (fp); + if (c == '\n') + ready = 1; + else if (c == EOF) + { + c = '\n'; + ready = 1; + } + again: + switch (state) + { + case skipWS: + if (!isascii (c) || !isspace(c)) + { + namelen = 0; + state = collectNAME; + goto again; + } + break; + + case collectNAME: + if (isspace (c)) + { + state = addNAME; + goto again; + } + else if (namelen < DIM(name)-1) + name[namelen++] = c; + else /* Too long. */ + state = skipNAME; + break; + + case skipNAME: + if (isspace (c)) + { + state = skipWS; + goto again; + } + break; + + case addNAME: + name[namelen] = 0; + if (!ignore_invalid_option_p (arg, name)) + { + item = xmalloc (sizeof *item + namelen); + strcpy (item->name, name); + item->next = (IIO_ITEM_DEF)arg->internal.iio_list; + arg->internal.iio_list = item; + } + state = skipWS; + goto again; + } + } +} + + +/* Clear the entire ignore-invalid-option list. */ +static void +ignore_invalid_option_clear (ARGPARSE_ARGS *arg) +{ + IIO_ITEM_DEF item, tmpitem; + + for (item = arg->internal.iio_list; item; item = tmpitem) + { + tmpitem = item->next; + xfree (item); + } + arg->internal.iio_list = NULL; +} + /**************** * Get options from a file. * Lines starting with '#' are comment lines. @@ -271,14 +380,26 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno, arg->r_opt = opts[idx].short_opt; if( inverse ) /* this does not have an effect, hmmm */ arg->r_opt = -arg->r_opt; - if( !opts[idx].short_opt ) /* unknown command/option */ + if( !opts[idx].short_opt ) { /* unknown command/option */ + if (!strcmp (keyword, "ignore-invalid-option")) { + /* No argument - ignore this meta option. */ + state = i = 0; + continue; + } + else if (ignore_invalid_option_p (arg, keyword)) { + /* This invalid option is in the iio list. */ + state = i = 0; + continue; + } arg->r_opt = (opts[idx].flags & 256)? -7:-2; + } else if( !(opts[idx].flags & 7) ) /* does not take an arg */ arg->r_type = 0; /* okay */ else if( (opts[idx].flags & 8) ) /* argument is optional */ arg->r_type = 0; /* okay */ else /* required argument */ arg->r_opt = -3; /* error */ + break; } else if( state == 3 ) { /* no argument found */ @@ -347,6 +468,7 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno, break; } else if( c == EOF ) { + ignore_invalid_option_clear (arg); if( ferror(fp) ) arg->r_opt = -5; /* read error */ else @@ -376,6 +498,13 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno, in_alias = 1; state = 3; } + else if (!strcmp (keyword, "ignore-invalid-option")) { + ignore_invalid_option_add (arg, fp); + state = i = 0; + ++*lineno; + } + else if (ignore_invalid_option_p (arg, keyword)) + state = 1; /* Process like a comment. */ else { arg->r_opt = (opts[idx].flags & 256)? -7:-2; state = -1; /* skip rest of line and leave */ ----------------------------------------------------------------------- Summary of changes: include/util.h | 1 + util/argparse.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 18:44:13 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 18:44:13 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-50-g8ea49cf 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 8ea49cf513e1fb47913473ec8bf22ff832878506 (commit) from 732f3d1d4786239db5f31f82cc04ec79326cc13c (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 8ea49cf513e1fb47913473ec8bf22ff832878506 Author: Werner Koch Date: Tue Dec 18 18:06:41 2012 +0100 jnlib: Add meta option ignore-invalid-option. * jnlib/argparse.c (iio_item_def_s, IIO_ITEM_DEF): New. (initialize): Init field IIO_LIST. (ignore_invalid_option_p): New. (ignore_invalid_option_add): New. (ignore_invalid_option_clear): New. (optfile_parse): Implement meta option. -- This option is currently of no use. However, as soon as it has been deployed in all stable versions of GnuPG, it will allow the use of the same configuration file with an old and a new version of GnuPG. For example: If a new version implements the option "foobar", and a user uses it in gpg.conf, an old version of gpg would bail out with the error "invalid option". To avoid that the following line can be put above that option in gpg.conf ignore-invalid-option foobar This meta option may be given several times or several option names may be given as arguments (space delimited). Note that this option is not available on the command line. (cherry-picked from commit 41d564333d35c923f473aa90625d91f8fe18cd0b) diff --git a/jnlib/argparse.c b/jnlib/argparse.c index c9b5384..dab4bba 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -1,6 +1,6 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling * Copyright (C) 1998, 1999, 2000, 2001, 2006 - * 2007, 2008 Free Software Foundation, Inc. + * 2007, 2008, 2012 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -143,6 +143,16 @@ struct alias_def_s { const char *value; /* ptr into name */ }; + +/* Object to store the names for the --ignore-invalid-option option. + This is a simple linked list. */ +typedef struct iio_item_def_s *IIO_ITEM_DEF; +struct iio_item_def_s +{ + IIO_ITEM_DEF next; + char name[1]; /* String with the long option name. */ +}; + static const char *(*strusage_handler)( int ) = NULL; static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); @@ -162,6 +172,7 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) arg->internal.stopped = 0; arg->internal.aliases = NULL; arg->internal.cur_alias = NULL; + arg->internal.iio_list = NULL; arg->err = 0; arg->flags |= 1<<15; /* Mark as initialized. */ if ( *arg->argc < 0 ) @@ -244,6 +255,111 @@ store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) #endif } + +/* Return true if KEYWORD is in the ignore-invalid-option list. */ +static int +ignore_invalid_option_p (ARGPARSE_ARGS *arg, const char *keyword) +{ + IIO_ITEM_DEF item = arg->internal.iio_list; + + for (; item; item = item->next) + if (!strcmp (item->name, keyword)) + return 1; + return 0; +} + + +/* Add the keywords up to the next LF to the list of to be ignored + options. After returning FP will either be at EOF or the next + character read wll be the first of a new line. The function + returns 0 on success or true on malloc failure. */ +static int +ignore_invalid_option_add (ARGPARSE_ARGS *arg, FILE *fp) +{ + IIO_ITEM_DEF item; + int c; + char name[100]; + int namelen = 0; + int ready = 0; + enum { skipWS, collectNAME, skipNAME, addNAME} state = skipWS; + + while (!ready) + { + c = getc (fp); + if (c == '\n') + ready = 1; + else if (c == EOF) + { + c = '\n'; + ready = 1; + } + again: + switch (state) + { + case skipWS: + if (!isascii (c) || !isspace(c)) + { + namelen = 0; + state = collectNAME; + goto again; + } + break; + + case collectNAME: + if (isspace (c)) + { + state = addNAME; + goto again; + } + else if (namelen < DIM(name)-1) + name[namelen++] = c; + else /* Too long. */ + state = skipNAME; + break; + + case skipNAME: + if (isspace (c)) + { + state = skipWS; + goto again; + } + break; + + case addNAME: + name[namelen] = 0; + if (!ignore_invalid_option_p (arg, name)) + { + item = jnlib_malloc (sizeof *item + namelen); + if (!item) + return 1; + strcpy (item->name, name); + item->next = (IIO_ITEM_DEF)arg->internal.iio_list; + arg->internal.iio_list = item; + } + state = skipWS; + goto again; + } + } + return 0; +} + + +/* Clear the entire ignore-invalid-option list. */ +static void +ignore_invalid_option_clear (ARGPARSE_ARGS *arg) +{ + IIO_ITEM_DEF item, tmpitem; + + for (item = arg->internal.iio_list; item; item = tmpitem) + { + tmpitem = item->next; + jnlib_free (item); + } + arg->internal.iio_list = NULL; +} + + + /**************** * Get options from a file. * Lines starting with '#' are comment lines. @@ -253,6 +369,10 @@ store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) * are not valid here. * The special keyword "alias" may be used to store alias definitions, * which are later expanded like long options. + * The option + * ignore-invalid-option OPTIONNAMEs + * is recognized and updates a list of option which should be ignored if they + * are not defined. * Caller must free returned strings. * If called with FP set to NULL command line args are parse instead. * @@ -299,9 +419,23 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, idx = i; arg->r_opt = opts[idx].short_opt; if (!opts[idx].short_opt ) - arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) - ? ARGPARSE_INVALID_COMMAND - : ARGPARSE_INVALID_OPTION); + { + if (!strcmp (keyword, "ignore-invalid-option")) + { + /* No argument - ignore this meta option. */ + state = i = 0; + continue; + } + else if (ignore_invalid_option_p (arg, keyword)) + { + /* This invalid option is in the iio list. */ + state = i = 0; + continue; + } + arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) + ? ARGPARSE_INVALID_COMMAND + : ARGPARSE_INVALID_OPTION); + } else if (!(opts[idx].flags & 7)) arg->r_type = 0; /* Does not take an arg. */ else if ((opts[idx].flags & 8) ) @@ -389,6 +523,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, } else if (c == EOF) { + ignore_invalid_option_clear (arg); if (ferror (fp)) arg->r_opt = ARGPARSE_READ_ERROR; else @@ -422,6 +557,18 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, in_alias = 1; state = 3; } + else if (!strcmp (keyword, "ignore-invalid-option")) + { + if (ignore_invalid_option_add (arg, fp)) + { + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + state = i = 0; + ++*lineno; + } + else if (ignore_invalid_option_p (arg, keyword)) + state = 1; /* Process like a comment. */ else { arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND) @@ -551,7 +698,7 @@ find_long_option( ARGPARSE_ARGS *arg, return i; } } - return -1; + return -1; /* Not found. */ } int diff --git a/jnlib/argparse.h b/jnlib/argparse.h index b211e5f..a4203b5 100644 --- a/jnlib/argparse.h +++ b/jnlib/argparse.h @@ -49,6 +49,7 @@ typedef struct const char *last; void *aliases; const void *cur_alias; + void *iio_list; } internal; /* Private - do not change. */ } ARGPARSE_ARGS; ----------------------------------------------------------------------- Summary of changes: jnlib/argparse.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- jnlib/argparse.h | 1 + 2 files changed, 153 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 19:38:22 2012 From: cvs at cvs.gnupg.org (by Dmitry Kasatkin) Date: Tue, 18 Dec 2012 19:38:22 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-79-gefd7002 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 efd7002188e6d50013e4d9a920a8b9afa9d210e5 (commit) via bfe4dc11bb822cbc5bf2b425e5a5a2867a904518 (commit) from 6d20c1fab7f6005b34103de40c9707411b047f07 (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 efd7002188e6d50013e4d9a920a8b9afa9d210e5 Author: Dmitry Kasatkin Date: Tue Dec 18 14:56:48 2012 +0200 Add support for using DRNG random number generator * configure.ac: Add option --disable-drng-support. (ENABLE_DRNG_SUPPORT): New. * random/rndhw.c (USE_DRNG): New. (rdrand_long, rdrand_nlong, poll_drng): New. (_gcry_rndhw_poll_fast, _gcry_rndhw_poll_slow): Call poll function. * src/g10lib.h (HWF_INTEL_RDRAND): New. * src/global.c (hwflist): Add "intel-rdrand". * src/hwfeatures.c (detect_x86_64_gnuc) [ENABLE_DRNG_SUPPORT]: Detect RDRAND. (detect_ia32_gnuc) [ENABLE_DRNG_SUPPORT]: Detect RDRAND. -- This patch provides support for using Digital Random Number Generator (DRNG) engine, which is available on the latest Intel's CPUs. DRNG engine is accesible via new the RDRAND instruction. This patch adds the following: - support for disabling using of rdrand instruction - checking for RDRAND instruction support using cpuid - RDRAND usage implementation Signed-off-by: Dmitry Kasatkin ChangeLog and editorial changes by wk. diff --git a/configure.ac b/configure.ac index ff07dda..7d162a2 100644 --- a/configure.ac +++ b/configure.ac @@ -544,6 +544,18 @@ if test x"$aesnisupport" = xyes ; then [Enable support for Intel AES-NI instructions.]) fi +# Implementation of the --disable-drng-support switch. +AC_MSG_CHECKING([whether DRNG support is requested]) +AC_ARG_ENABLE(drng-support, + AC_HELP_STRING([--disable-drng-support], + [Disable support for the Intel DRNG (RDRAND instruction)]), + drngsupport=$enableval,drngsupport=yes) +AC_MSG_RESULT($drngsupport) +if test x"$drngsupport" = xyes ; then + AC_DEFINE(ENABLE_DRNG_SUPPORT, 1, + [Enable support for Intel DRNG (RDRAND instruction).]) +fi + # Implementation of the --disable-O-flag-munging switch. AC_MSG_CHECKING([whether a -O flag munging is requested]) AC_ARG_ENABLE([O-flag-munging], @@ -1304,6 +1316,7 @@ echo " Using linux capabilities: $use_capabilities Try using Padlock crypto: $padlocksupport Try using AES-NI crypto: $aesnisupport + Try using DRNG (RDRAND): $drngsupport " if test "$print_egd_notice" = "yes"; then diff --git a/random/rndhw.c b/random/rndhw.c index 775d90f..cbb28d1 100644 --- a/random/rndhw.c +++ b/random/rndhw.c @@ -1,5 +1,6 @@ /* rndhw.c - Access to the external random daemon * Copyright (C) 2007 Free Software Foundation, Inc. + * Copyright (C) 2012 Dmitry Kasatkin * * This file is part of Libgcrypt. * @@ -34,6 +35,16 @@ # endif #endif /*ENABLE_PADLOCK_SUPPORT*/ +#undef USE_DRNG +#ifdef ENABLE_DRNG_SUPPORT +# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED +# if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__) +# define USE_DRNG 1 +# endif +# endif +#endif /*ENABLE_RDRAND_SUPPORT*/ + +typedef void (*add_fn_t)(const void*, size_t, enum random_origins); /* Keep track on whether the RNG has problems. */ static volatile int rng_failed; @@ -109,6 +120,55 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), #endif /*USE_PADLOCK*/ +#ifdef USE_DRNG +# define RDRAND_RETRY_LOOPS 10 +# define RDRAND_INT ".byte 0x0f,0xc7,0xf0" +# ifdef __x86_64__ +# define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0" +# else +# define RDRAND_LONG RDRAND_INT +# endif +static inline int +rdrand_long (unsigned long *v) +{ + int ok; + asm volatile ("1: " RDRAND_LONG "\n\t" + "jc 2f\n\t" + "decl %0\n\t" + "jnz 1b\n\t" + "2:" + : "=r" (ok), "=a" (*v) + : "0" (RDRAND_RETRY_LOOPS)); + return ok; +} + + +static inline int +rdrand_nlong (unsigned long *v, int count) +{ + while (count--) + if (!rdrand_long(v++)) + return 0; + return 1; +} + + +static size_t +poll_drng (add_fn_t add, enum random_origins origin, int fast) +{ + volatile char buffer[64] __attribute__ ((aligned (8))); + unsigned int nbytes = sizeof (buffer); + + (void)fast; + + if (!rdrand_nlong ((unsigned long *)buffer, sizeof(buffer)/sizeof(long))) + return 0; + (*add)((void *)buffer, nbytes, origin); + return nbytes; +} +#endif /*USE_DRNG*/ + + int _gcry_rndhw_failed_p (void) { @@ -125,6 +185,10 @@ _gcry_rndhw_poll_fast (void (*add)(const void*, size_t, enum random_origins), (void)add; (void)origin; +#ifdef USE_DRNG + if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND)) + poll_drng (add, origin, 1); +#endif #ifdef USE_PADLOCK if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG)) poll_padlock (add, origin, 1); @@ -143,6 +207,10 @@ _gcry_rndhw_poll_slow (void (*add)(const void*, size_t, enum random_origins), (void)add; (void)origin; +#ifdef USE_DRNG + if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND)) + nbytes += poll_drng (add, origin, 0); +#endif #ifdef USE_PADLOCK if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG)) nbytes += poll_padlock (add, origin, 0); diff --git a/src/g10lib.h b/src/g10lib.h index f1af399..5e99c46 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -151,6 +151,7 @@ int _gcry_log_verbosity( int level ); #define HWF_PADLOCK_MMUL 8 #define HWF_INTEL_AESNI 256 +#define HWF_INTEL_RDRAND 512 unsigned int _gcry_get_hw_features (void); diff --git a/src/global.c b/src/global.c index f280a7b..2428e21 100644 --- a/src/global.c +++ b/src/global.c @@ -66,6 +66,7 @@ static struct { HWF_PADLOCK_SHA, "padlock-sha" }, { HWF_PADLOCK_MMUL,"padlock-mmul"}, { HWF_INTEL_AESNI, "intel-aesni" }, + { HWF_INTEL_RDRAND,"intel-rdrand" }, { 0, NULL} }; diff --git a/src/hwfeatures.c b/src/hwfeatures.c index 82c435b..e89c825 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -134,6 +134,20 @@ detect_x86_64_gnuc (void) : "%eax", "%ebx", "%ecx", "%edx", "cc" ); #endif /*#ifdef ENABLE_AESNI_SUPPORT*/ +#ifdef ENABLE_DRNG_SUPPORT + asm volatile + ("movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ + "cpuid\n" + "testl $0x40000000, %%ecx\n\t" /* Test bit 30. */ + "jz .Lno_rdrand%=\n\t" /* No RDRAND support. */ + "orl $512, %0\n" /* Set our HWF_INTEL_RDRAND bit. */ + + ".Lno_rdrand%=:\n" + : "+r" (hw_features) + : + : "%eax", "%ebx", "%ecx", "%edx", "cc" + ); +#endif /* #ifdef ENABLE_DRNG_SUPPORT */ } #endif /* __x86_64__ && __GNUC__ */ @@ -267,6 +281,22 @@ detect_ia32_gnuc (void) : "%eax", "%ecx", "%edx", "cc" ); #endif /*ENABLE_AESNI_SUPPORT*/ +#ifdef ENABLE_DRNG_SUPPORT + asm volatile + ("pushl %%ebx\n\t" /* Save GOT register. */ + "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ + "cpuid\n" + "popl %%ebx\n\t" /* Restore GOT register. */ + "testl $0x40000000, %%ecx\n\t" /* Test bit 30. */ + "jz .Lno_rdrand%=\n\t" /* No RDRAND support. */ + "orl $512, %0\n" /* Set our HWF_INTEL_RDRAND bit. */ + + ".Lno_rdrand%=:\n" + : "+r" (hw_features) + : + : "%eax", "%ecx", "%edx", "cc" + ); +#endif /*ENABLE_DRNG_SUPPORT*/ } #endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ commit bfe4dc11bb822cbc5bf2b425e5a5a2867a904518 Author: Werner Koch Date: Tue Dec 18 18:42:23 2012 +0100 doc: Add Dmitry to AUTHORS -- diff --git a/AUTHORS b/AUTHORS index 8f385f8..a2c36da 100644 --- a/AUTHORS +++ b/AUTHORS @@ -111,6 +111,7 @@ DCO:2012-04-16:Tom?? Mr?z DCO:2012-04-20:Rafa?l Carr? DCO:2012-11-14:Jussi Kivilinna DCO:2012-12-05:Werner Koch +DCO:2012-12-14:Dmitry Kasatkin More credits ----------------------------------------------------------------------- Summary of changes: AUTHORS | 1 + configure.ac | 13 ++++++++++ random/rndhw.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/g10lib.h | 1 + src/global.c | 1 + src/hwfeatures.c | 30 +++++++++++++++++++++++ 6 files changed, 114 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 20:01:33 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 20:01:33 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-116-g0e64e1a 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 0e64e1abd3acf5da73cbd981ef7a40971985822d (commit) from 41d564333d35c923f473aa90625d91f8fe18cd0b (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 0e64e1abd3acf5da73cbd981ef7a40971985822d Author: Werner Koch Date: Tue Dec 18 19:54:23 2012 +0100 State that disclaimers are not anymore needed for translations. -- diff --git a/AUTHORS b/AUTHORS index 6637615..cfcf984 100644 --- a/AUTHORS +++ b/AUTHORS @@ -134,6 +134,9 @@ Yutaka Niibe Assigns Past and Future Changes Other authors ============= +The need for copyright disclaimers for translations has been waived in +December 2012. + The files common/libestream.[ch] are maintained as a separate project by g10 Code GmbH. These files, as used here, are considered part of GnuPG. @@ -176,8 +179,9 @@ name gpg2keys_*. ========= - Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2005, - 2006, 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008, 2009, 2010, 2011, + 2012 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without ----------------------------------------------------------------------- Summary of changes: AUTHORS | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 20:01:56 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 20:01:56 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-51-g3d78be2 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 3d78be288653f848134cad44a1413363a3014d44 (commit) from 8ea49cf513e1fb47913473ec8bf22ff832878506 (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 3d78be288653f848134cad44a1413363a3014d44 Author: Werner Koch Date: Tue Dec 18 19:54:23 2012 +0100 State that disclaimers are not anymore needed for translations. -- diff --git a/AUTHORS b/AUTHORS index eea52a8..aff8abb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -128,6 +128,9 @@ Yuri Chornoivan, yurchor at ukr dot net: Translations [uk] Other authors ============= +The need for copyright disclaimers for translations has been waived in +December 2012. + The files common/libestream.[ch] are maintained as a separate project by g10 Code GmbH. These files, as used here, are considered part of GnuPG. @@ -167,8 +170,9 @@ name gpg2keys_*. ========= - Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2005, - 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008, 2009, 2010, 2011, + 2012 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without ----------------------------------------------------------------------- Summary of changes: AUTHORS | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 20:05:55 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 20:05:55 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-29-g80cd8f1 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 80cd8f18dd9e7fed438ed2fcc966b98260aa2535 (commit) from 8044a5acea80cb749159cd725e95bad246be5f72 (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 80cd8f18dd9e7fed438ed2fcc966b98260aa2535 Author: Werner Koch Date: Tue Dec 18 19:54:23 2012 +0100 State that disclaimers are not anymore needed for translations. -- diff --git a/AUTHORS b/AUTHORS index 6b37cea..ff0e69f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,5 @@ Program: GnuPG +Version: 1.4 Maintainer: Werner Koch Bug reports: http://bugs.gnupg.org Security related bug reports: @@ -121,6 +122,9 @@ Yuri Chornoivan, yurchor at ukr dot net: Translations [uk] Other authors ============= +The need for copyright disclaimers for translations has been waived in +December 2012. + This program uses the zlib compression library written by Jean-loup Gailly and Mark Adler. @@ -151,7 +155,7 @@ details. Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2012 Free Software Foundation, Inc. + 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without ----------------------------------------------------------------------- Summary of changes: AUTHORS | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Dec 18 20:08:17 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 18 Dec 2012 20:08:17 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-30-g3a51d50 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 3a51d501b915dd930445bcf8330acfdabb2e2934 (commit) from 80cd8f18dd9e7fed438ed2fcc966b98260aa2535 (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 3a51d501b915dd930445bcf8330acfdabb2e2934 Author: Werner Koch Date: Tue Dec 18 20:03:21 2012 +0100 .gitignore: Add cruft from other branches. -- diff --git a/.gitignore b/.gitignore index e23de9a..634ad9d 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,8 @@ tools/shmtest mpi/libmpi.a util/libcompat.a util/libutil.a +/common/audit-events.h +/common/status-codes.h +/doc/gnupg.info +/doc/gnupg.info-1 +/doc/gnupg.info-2 ----------------------------------------------------------------------- Summary of changes: .gitignore | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 04:02:31 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Wed, 19 Dec 2012 04:02:31 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-31-gf2f12f4 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 f2f12f41efe5a476833295dc6c44fcd887d0abe6 (commit) from 3a51d501b915dd930445bcf8330acfdabb2e2934 (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 f2f12f41efe5a476833295dc6c44fcd887d0abe6 Author: David Shaw Date: Tue Dec 18 21:58:53 2012 -0500 Fix issue 1446: honor ports given in SRV responses. * common/http.c (send_request, connect_server, http_open): Use a struct srv instead of a single srvtag so we can pass the chosen host and port back to the caller. (connect_server): Use the proper port in the HAVE_GETADDRINFO case. * keyserver/curl-shim.c (curl_easy_perform): Use struct srv and log chosen host and port. * keyserver/gpgkeys_hkp.c (main): Properly take the port given by SRV. Backported from ba9e974f1fd85b3dbbfb5e26d7a14f71d07c7cf2 diff --git a/include/http.h b/include/http.h index 7959be8..1ecdc60 100644 --- a/include/http.h +++ b/include/http.h @@ -1,6 +1,6 @@ /* http.h - HTTP protocol handler * Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -73,14 +73,21 @@ struct http_context { }; typedef struct http_context *HTTP_HD; +struct http_srv +{ + const char *srvtag; + char *used_server; + unsigned short used_port; +}; + int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, char *auth, unsigned int flags, const char *proxy, - const char *srvtag, STRLIST headers ); + struct http_srv *srv, STRLIST headers ); void http_start_data( HTTP_HD hd ); int http_wait_response( HTTP_HD hd, unsigned int *ret_status ); void http_close( HTTP_HD hd ); int http_open_document( HTTP_HD hd, const char *document, char *auth, unsigned int flags, const char *proxy, - const char *srvtag, STRLIST headers ); + struct http_srv *srv, STRLIST headers ); #endif /*G10_HTTP_H*/ diff --git a/keyserver/curl-shim.c b/keyserver/curl-shim.c index 2df7826..857b5c1 100644 --- a/keyserver/curl-shim.c +++ b/keyserver/curl-shim.c @@ -1,7 +1,7 @@ /* curl-shim.c - Implement a small subset of the curl API in terms of * the iobuf HTTP API * - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -164,6 +164,9 @@ curl_easy_perform(CURL *curl) CURLcode err=CURLE_OK; const char *errstr=NULL; char *proxy=NULL; + struct http_srv srv; + + memset(&srv,0,sizeof(srv)); /* Emulate the libcurl proxy behavior. If the calling program set a proxy, use it. If it didn't set a proxy or set it to NULL, check @@ -176,10 +179,17 @@ curl_easy_perform(CURL *curl) else proxy=getenv(HTTP_PROXY_ENV); + if(curl->srvtag) + srv.srvtag=curl->srvtag; + if(curl->flags.verbose) { fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null"); fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url); + if(srv.srvtag) + fprintf(curl->errors, + "* SRV tag is \"%s\": host and port may be overridden\n", + srv.srvtag); fprintf(curl->errors,"* HTTP auth is \"%s\"\n", curl->auth?curl->auth:"null"); fprintf(curl->errors,"* HTTP method is %s\n", @@ -189,12 +199,16 @@ curl_easy_perform(CURL *curl) if(curl->flags.post) { rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy, - curl->srvtag,curl->headers?curl->headers->list:NULL); + &srv,curl->headers?curl->headers->list:NULL); if(rc==0) { char content_len[50]; unsigned int post_len=strlen(curl->postfields); + if(curl->flags.verbose && srv.used_server && srv.used_port) + fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n", + srv.used_server, srv.used_port); + iobuf_writestr(curl->hd.fp_write, "Content-Type: application/x-www-form-urlencoded\r\n"); sprintf(content_len,"Content-Length: %u\r\n",post_len); @@ -211,9 +225,13 @@ curl_easy_perform(CURL *curl) else { rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy, - curl->srvtag,curl->headers?curl->headers->list:NULL); + &srv,curl->headers?curl->headers->list:NULL); if(rc==0) { + if(curl->flags.verbose && srv.used_server && srv.used_port) + fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n", + srv.used_server, srv.used_port); + rc=http_wait_response(&curl->hd,&curl->status); if(rc==0) { @@ -248,6 +266,8 @@ curl_easy_perform(CURL *curl) } } + free (srv.used_server); + switch(rc) { case 0: diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index b2e1a1a..27d67c6 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -1,6 +1,6 @@ /* gpgkeys_hkp.c - talk to an HKP keyserver * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -690,6 +690,7 @@ main(int argc,char *argv[]) goto fail; } + /* Defaults */ if(ascii_strcasecmp(opt->scheme,"hkps")==0) { proto="https"; @@ -722,11 +723,9 @@ main(int argc,char *argv[]) goto fail; } - /* If the user gives a :port, then disable SRV. The semantics of a - specified port and SRV do not play well together. */ - if(opt->port) - port=opt->port; - else if(try_srv) + /* Only use SRV if the user does not provide a :port. The semantics + of a specified port and SRV do not play well together. */ + if(!opt->port && try_srv) { char *srvtag; @@ -751,6 +750,11 @@ main(int argc,char *argv[]) #endif } + /* If the user provided a port (or it came in via SRV, above), + replace the default. */ + if(opt->port) + port=opt->port; + curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer); if(opt->auth) diff --git a/util/http.c b/util/http.c index 9aaa1d1..bab9796 100644 --- a/util/http.c +++ b/util/http.c @@ -1,6 +1,6 @@ /* http.c - HTTP protocol handler * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -69,12 +69,12 @@ static int insert_escapes( byte *buffer, const byte *string, const byte *special ); static URI_TUPLE parse_tuple( byte *string ); static int send_request( HTTP_HD hd, const char *auth, const char *proxy, - const char *srvtag, STRLIST headers); + struct http_srv *srv, STRLIST headers); static byte *build_rel_path( PARSED_URI uri ); static int parse_response( HTTP_HD hd ); static int connect_server( const char *server, ushort port, unsigned int flags, - const char *srvtag ); + struct http_srv *srv ); static int write_server( int sock, const char *data, size_t length ); #ifdef _WIN32 @@ -150,7 +150,7 @@ make_radix64_string( const byte *data, size_t len ) int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, char *auth, unsigned int flags, const char *proxy, - const char *srvtag, STRLIST headers ) + struct http_srv *srv, STRLIST headers ) { int rc; @@ -166,7 +166,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, rc = parse_uri( &hd->uri, url ); if( !rc ) { - rc = send_request( hd, auth, proxy, srvtag, headers ); + rc = send_request( hd, auth, proxy, srv, headers ); if( !rc ) { hd->fp_write = iobuf_sockopen( hd->sock , "w" ); if( hd->fp_write ) @@ -234,12 +234,12 @@ http_wait_response( HTTP_HD hd, unsigned int *ret_status ) int http_open_document( HTTP_HD hd, const char *document, char *auth, - unsigned int flags, const char *proxy, const char *srvtag, + unsigned int flags, const char *proxy, struct http_srv *srv, STRLIST headers ) { int rc; - rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy, srvtag, + rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy, srv, headers ); if( rc ) return rc; @@ -523,7 +523,7 @@ parse_tuple( byte *string ) */ static int send_request( HTTP_HD hd, const char *auth, const char *proxy, - const char *srvtag, STRLIST headers ) + struct http_srv *srv, STRLIST headers ) { const byte *server; byte *request, *p; @@ -546,7 +546,7 @@ send_request( HTTP_HD hd, const char *auth, const char *proxy, return G10ERR_NETWORK; } hd->sock = connect_server( *uri->host? uri->host : "localhost", - uri->port? uri->port : 80, 0, NULL ); + uri->port? uri->port : 80, 0, srv ); if(uri->auth) { char *x; @@ -560,7 +560,7 @@ send_request( HTTP_HD hd, const char *auth, const char *proxy, release_parsed_uri( uri ); } else - hd->sock = connect_server( server, port, hd->flags, srvtag ); + hd->sock = connect_server( server, port, hd->flags, srv ); if(auth || hd->uri->auth) { @@ -815,9 +815,9 @@ start_server(void) static int connect_server( const char *server, ushort port, unsigned int flags, - const char *srvtag ) + struct http_srv *srv ) { - int sock=-1,srv,srvcount=0,connected=0,hostfound=0; + int sock=-1, srvindex, srvcount=0, connected=0, hostfound=0, chosen=-1; struct srventry *srvlist=NULL; #ifdef _WIN32 @@ -854,15 +854,15 @@ connect_server( const char *server, ushort port, unsigned int flags, #ifdef USE_DNS_SRV /* Do the SRV thing */ - if(srvtag) + if(srv && srv->srvtag) { /* We're using SRV, so append the tags */ - if(1+strlen(srvtag)+6+strlen(server)+1<=MAXDNAME) + if(1+strlen(srv->srvtag)+6+strlen(server)+1<=MAXDNAME) { char srvname[MAXDNAME]; strcpy(srvname,"_"); - strcat(srvname,srvtag); + strcat(srvname,srv->srvtag); strcat(srvname,"._tcp."); strcat(srvname,server); srvcount=getsrv(srvname,&srvlist); @@ -885,15 +885,15 @@ connect_server( const char *server, ushort port, unsigned int flags, #ifdef HAVE_GETADDRINFO - for(srv=0;srvai_addr,ai->ai_addrlen)==0) { connected=1; + chosen = srvindex; break; } @@ -924,7 +925,7 @@ connect_server( const char *server, ushort port, unsigned int flags, #else /* !HAVE_GETADDRINFO */ - for(srv=0;srvh_addrtype; if(addr.sin_family!=AF_INET) { - log_error("%s: unknown address family\n",srvlist[srv].target); + log_error("%s: unknown address family\n",srvlist[srvindex].target); return -1; } - addr.sin_port=htons(srvlist[srv].port); + addr.sin_port=htons(srvlist[srvindex].port); /* Try all A records until one responds. */ while(host->h_addr_list[i]) { if(host->h_length!=4) { - log_error("%s: illegal address length\n",srvlist[srv].target); + log_error("%s: illegal address length\n",srvlist[srvindex].target); return -1; } @@ -966,6 +967,7 @@ connect_server( const char *server, ushort port, unsigned int flags, if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))==0) { connected=1; + chosen = srvindex; break; } @@ -979,6 +981,12 @@ connect_server( const char *server, ushort port, unsigned int flags, } #endif /* !HAVE_GETADDRINFO */ + if(chosen>-1 && srv) + { + srv->used_server = strdup (srvlist[chosen].target); + srv->used_port = srvlist[chosen].port; + } + free(srvlist); if(!connected) ----------------------------------------------------------------------- Summary of changes: include/http.h | 13 ++++++++-- keyserver/curl-shim.c | 26 ++++++++++++++++++++-- keyserver/gpgkeys_hkp.c | 16 ++++++++----- util/http.c | 54 +++++++++++++++++++++++++++-------------------- 4 files changed, 74 insertions(+), 35 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 11:10:04 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 11:10:04 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-117-g5a66316 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 5a66316ea4cd27e3081b2cce5385ae2429aa83b6 (commit) from 0e64e1abd3acf5da73cbd981ef7a40971985822d (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 5a66316ea4cd27e3081b2cce5385ae2429aa83b6 Author: Werner Koch Date: Wed Dec 19 11:05:05 2012 +0100 faq: Add a section on copyright assignments -- diff --git a/doc/faq.org b/doc/faq.org index 5d053c4..e4e9187 100644 --- a/doc/faq.org +++ b/doc/faq.org @@ -1470,11 +1470,19 @@ update this FAQ in the next month. See the section "Changes" for recent updates :CUSTOM_ID: bugreports-et-al :END: -** Copyright asssignments +** Copyright assignments :PROPERTIES: - :CUSTOM_ID: copyright-assigments + :CUSTOM_ID: copyright-assignments :END: +Like most core GNU projects, GnuPG requires the signing of a copyright +assignment to the FSF. Without such an assignment we may only accept +trivial patches. As a rule of thumb the sum of all changed lines by +one contributor may not exceed about 15 lines. Exceptions are typo +corrections and translations. See +http://www.gnu.org/prep/maintain/html_node/Copyright-Papers.html for +details. + ** U.S. export restrictions :PROPERTIES: :CUSTOM_ID: us-export-restrictions ----------------------------------------------------------------------- Summary of changes: doc/faq.org | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 11:26:24 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 11:26:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-118-g8325d61 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 8325d616593187ff227853de0295e3269b96edcb (commit) from 5a66316ea4cd27e3081b2cce5385ae2429aa83b6 (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 8325d616593187ff227853de0295e3269b96edcb Author: Werner Koch Date: Wed Dec 19 11:21:26 2012 +0100 gpg: Suppress "public key already present" in quiet mode. * g10/pkclist.c (find_and_check_key, build_pk_list): Print a diagnostic only in non-quiet mode. diff --git a/g10/pkclist.c b/g10/pkclist.c index f805da8..e1a4428 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -837,7 +837,8 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, list. */ if (!key_present_in_pk_list (*pk_list_addr, pk)) { - log_info (_("%s: skipped: public key already present\n"), name); + if (!opt.quiet) + log_info (_("%s: skipped: public key already present\n"), name); free_public_key (pk); } else @@ -945,8 +946,9 @@ build_pk_list (ctrl_t ctrl, if (key_present_in_pk_list(pk_list, pk) == 0) { free_public_key (pk); pk = NULL; - log_info (_("%s: skipped: public key already present\n"), - rov->d); + if (!opt.quiet) + log_info (_("%s: skipped: public key already present\n"), + rov->d); } else { ----------------------------------------------------------------------- Summary of changes: g10/pkclist.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 11:52:29 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 11:52:29 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-54-gd23ec86 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 d23ec86095714d388acac14b515445fe69f019e9 (commit) via 75404e2dad668a4bad3c0f06515197bcc90e9503 (commit) via febb8ace98f093c18b3251581841b96913b3c84b (commit) from 3d78be288653f848134cad44a1413363a3014d44 (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 d23ec86095714d388acac14b515445fe69f019e9 Author: Werner Koch Date: Wed Dec 19 11:47:23 2012 +0100 gpg: Make commit 258192d4 actually work * g10/sign.c (update_keysig_packet): Use digest_algo. diff --git a/g10/sign.c b/g10/sign.c index a464bb6..6cccfed 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1504,7 +1504,8 @@ update_keysig_packet( PKT_signature **ret_sig, void *opaque ) { PKT_signature *sig; - int rc=0, digest_algo; + int rc = 0; + int digest_algo; gcry_md_hd_t md; if ((!orig_sig || !pk || !sk) @@ -1517,7 +1518,7 @@ update_keysig_packet( PKT_signature **ret_sig, else digest_algo = orig_sig->digest_algo; - if ( gcry_md_open (&md, orig_sig->digest_algo, 0 ) ) + if ( gcry_md_open (&md, digest_algo, 0 ) ) BUG (); /* Hash the public key certificate and the user id. */ commit 75404e2dad668a4bad3c0f06515197bcc90e9503 Author: Werner Koch Date: Wed Dec 19 11:21:26 2012 +0100 gpg: Suppress "public key already present" in quiet mode. * g10/pkclist.c (build_pk_list): Print two diagnostics only in non-quiet mode. -- (back-ported from commit 8325d616593187ff227853de0295e3269b96edcb) diff --git a/g10/pkclist.c b/g10/pkclist.c index c1f5333..85a8eeb 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -842,8 +842,9 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) if (key_present_in_pk_list(pk_list, pk) == 0) { free_public_key (pk); pk = NULL; - log_info (_("%s: skipped: public key already present\n"), - rov->d); + if (!opt.quiet) + log_info (_("%s: skipped: public key already present\n"), + rov->d); } else { @@ -1122,8 +1123,9 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) if (!key_present_in_pk_list(pk_list, pk)) { free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key already present\n"), - remusr->d); + if (!opt.quiet) + log_info(_("%s: skipped: public key already present\n"), + remusr->d); } else { commit febb8ace98f093c18b3251581841b96913b3c84b Author: Werner Koch Date: Wed Dec 19 11:21:26 2012 +0100 Remove trailing white space from a file -- diff --git a/g10/pkclist.c b/g10/pkclist.c index 1368bc2..c1f5333 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -159,7 +159,7 @@ show_revocation_reason( PKT_public_key *pk, int mode ) * mode: 0 = standard * 1 = Without key info and additional menu option 'm' * this does also add an option to set the key to ultimately trusted. - * Returns: + * Returns: * -2 = nothing changed - caller should show some additional info * -1 = quit operation * 0 = nothing changed @@ -195,7 +195,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, uppercase. Below you will find the matching strings which should be translated accordingly and the letter changed to match the one in the answer string. - + i = please show me more information m = back to the main menu s = skip this key @@ -203,9 +203,9 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, */ const char *ans = _("iImMqQsS"); - if( !did_help ) + if( !did_help ) { - if( !mode ) + if( !mode ) { KBNODE keyblock, un; @@ -232,7 +232,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, if (un->pkt->pkt.user_id->is_primary && !un->pkt->pkt.user_id->attrib_data ) continue; - + if((opt.verify_options&VERIFY_SHOW_PHOTOS) && un->pkt->pkt.user_id->attrib_data) show_photos(un->pkt->pkt.user_id->attribs, @@ -244,7 +244,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, tty_printf(_(" aka \"%s\"\n"),p); } - + print_fingerprint (pk, NULL, 2); tty_printf("\n"); release_kbnode (keyblock); @@ -302,7 +302,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, did_help = 0; else if( *p && p[1] ) ; - else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) + else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) { unsigned int trust; switch( *p ) @@ -328,14 +328,14 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, } #if 0 /* not yet implemented */ - else if( *p == ans[0] || *p == ans[1] ) + else if( *p == ans[0] || *p == ans[1] ) { tty_printf(_("Certificates leading to an ultimately trusted key:\n")); show = 1; break; } #endif - else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) + else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) { break ; /* back to the menu */ } @@ -354,9 +354,9 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, return show? -2: quit? -1 : changed; } -/* +/* * Display a menu to change the ownertrust of the key PK (which should - * be a primary key). + * be a primary key). * For mode values see do_edit_ownertrust () */ int @@ -413,7 +413,7 @@ do_we_trust( PKT_public_key *pk, unsigned int trustlevel ) log_error ("invalid trustlevel %u returned from validation layer\n", trustlevel); /* fall thru */ - case TRUST_UNKNOWN: + case TRUST_UNKNOWN: case TRUST_UNDEFINED: log_info(_("%s: There is no assurance this key belongs" " to the named user\n"),keystr_from_pk(pk)); @@ -463,12 +463,12 @@ do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel ) tty_printf("\n"); - + if (is_status_enabled ()) { u32 kid[2]; char *hint_str; - + keyid_from_pk (pk, kid); hint_str = get_long_user_id_string ( kid ); write_status_text ( STATUS_USERID_HINT, hint_str ); @@ -500,7 +500,7 @@ check_signatures_trust( PKT_signature *sig ) int rc=0; rc = get_pubkey( pk, sig->keyid ); - if (rc) + if (rc) { /* this should not happen */ log_error("Ooops; the key vanished - can't check the trust\n"); rc = G10ERR_NO_PUBKEY; @@ -522,7 +522,7 @@ check_signatures_trust( PKT_signature *sig ) trustlevel = get_validity (pk, NULL); - if ( (trustlevel & TRUST_FLAG_REVOKED) ) + if ( (trustlevel & TRUST_FLAG_REVOKED) ) { write_status( STATUS_KEYREVOKED ); if(pk->is_revoked==2) @@ -533,13 +533,13 @@ check_signatures_trust( PKT_signature *sig ) log_info(_(" This could mean that the signature is forged.\n")); show_revocation_reason( pk, 0 ); } - else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) + else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) { write_status( STATUS_KEYREVOKED ); log_info(_("WARNING: This subkey has been revoked by its owner!\n")); show_revocation_reason( pk, 0 ); } - + if ((trustlevel & TRUST_FLAG_DISABLED)) log_info (_("Note: This key has been disabled.\n")); @@ -572,9 +572,9 @@ check_signatures_trust( PKT_signature *sig ) "does not match DNS entry\n"), sig->pka_info->email); } - switch ( (trustlevel & TRUST_MASK) ) + switch ( (trustlevel & TRUST_MASK) ) { - case TRUST_UNKNOWN: + case TRUST_UNKNOWN: case TRUST_UNDEFINED: case TRUST_MARGINAL: if (okay && opt.verify_options&VERIFY_PKA_TRUST_INCREASE) @@ -596,18 +596,18 @@ check_signatures_trust( PKT_signature *sig ) } /* Now let the user know what up with the trustlevel. */ - switch ( (trustlevel & TRUST_MASK) ) + switch ( (trustlevel & TRUST_MASK) ) { case TRUST_EXPIRED: log_info(_("Note: This key has expired!\n")); print_fingerprint (pk, NULL, 1); break; - + default: log_error ("invalid trustlevel %u returned from validation layer\n", trustlevel); /* fall thru */ - case TRUST_UNKNOWN: + case TRUST_UNKNOWN: case TRUST_UNDEFINED: write_status( STATUS_TRUST_UNDEFINED ); log_info(_("WARNING: This key is not certified with" @@ -798,7 +798,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* Check whether there are any recipients in the list and build the * list of the encrypt-to ones (we always trust them). */ - for ( rov = remusr; rov; rov = rov->next ) + for ( rov = remusr; rov; rov = rov->next ) { if ( !(rov->flags & 1) ) { @@ -817,7 +817,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) compliance_failure(); } } - else if ( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) + else if ( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { /* Encryption has been requested and --encrypt-to has not been disabled. Check this encrypt-to key. */ @@ -827,7 +827,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* We explicitly allow encrypt-to to an disabled key; thus we pass 1for the second last argument and 1 as the last argument to disable AKL. */ - if ( (rc = get_pubkey_byname (NULL, pk, rov->d, NULL, NULL, 1, 1)) ) + if ( (rc = get_pubkey_byname (NULL, pk, rov->d, NULL, NULL, 1, 1)) ) { free_public_key ( pk ); pk = NULL; log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); @@ -835,7 +835,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) rov->d, strlen (rov->d), -1); goto fail; } - else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) ) + else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) ) { /* Skip the actual key if the key is already present * in the list. Add it to our list if not. */ @@ -867,7 +867,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) } } } - else + else { /* The public key is not usable for encryption or not available. */ @@ -882,8 +882,8 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* If we don't have any recipients yet and we are not in batch mode drop into interactive selection mode. */ - if ( !any_recipients && !opt.batch ) - { + if ( !any_recipients && !opt.batch ) + { int have_def_rec; char *answer = NULL; strlist_t backlog = NULL; @@ -895,7 +895,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) if ( !have_def_rec ) tty_printf(_("You did not specify a user ID. (you may use \"-r\")\n")); - for (;;) + for (;;) { rc = 0; xfree(answer); @@ -905,7 +905,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) answer = def_rec; def_rec = NULL; } - else if (backlog) + else if (backlog) { /* This is part of our trick to expand and display groups. */ answer = strlist_pop (&backlog); @@ -948,8 +948,8 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) trim_spaces(answer); cpr_kill_prompt(); } - - if ( !answer || !*answer ) + + if ( !answer || !*answer ) { xfree(answer); break; /* No more recipients entered - get out of loop. */ @@ -969,12 +969,12 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc = get_pubkey_byname (NULL, pk, answer, NULL, NULL, 0, 0 ); if (rc) tty_printf(_("No such user ID.\n")); - else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) ) + else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) ) { if ( have_def_rec ) { /* No validation for a default recipient. */ - if (!key_present_in_pk_list(pk_list, pk)) + if (!key_present_in_pk_list(pk_list, pk)) { free_public_key (pk); pk = NULL; log_info (_("skipped: public key " @@ -994,13 +994,13 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) else { /* Check validity of this key. */ int trustlevel; - + trustlevel = get_validity (pk, pk->user_id); - if ( (trustlevel & TRUST_FLAG_DISABLED) ) + if ( (trustlevel & TRUST_FLAG_DISABLED) ) { tty_printf (_("Public key is disabled.\n") ); } - else if ( do_we_trust_pre (pk, trustlevel) ) + else if ( do_we_trust_pre (pk, trustlevel) ) { /* Skip the actual key if the key is already * present in the list */ @@ -1032,7 +1032,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) pk = NULL; } } - else if ( !any_recipients && (def_rec = default_recipient()) ) + else if ( !any_recipients && (def_rec = default_recipient()) ) { /* We are in batch mode and have only a default recipient. */ pk = xmalloc_clear( sizeof *pk ); @@ -1043,7 +1043,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc = get_pubkey_byname (NULL, pk, def_rec, NULL, NULL, 1, 1); if (rc) log_error(_("unknown default recipient \"%s\"\n"), def_rec ); - else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) ) + else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) ) { /* Mark any_recipients here since the default recipient would have been used if it wasn't already there. It @@ -1053,7 +1053,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) if (!key_present_in_pk_list(pk_list, pk)) log_info (_("skipped: public key already set " "as default recipient\n")); - else + else { PK_LIST r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; @@ -1069,11 +1069,11 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) } xfree(def_rec); def_rec = NULL; } - else + else { /* General case: Check all keys. */ any_recipients = 0; - for (; remusr; remusr = remusr->next ) + for (; remusr; remusr = remusr->next ) { if ( (remusr->flags & 1) ) continue; /* encrypt-to keys are already handled. */ @@ -1090,13 +1090,13 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) -1); goto fail; } - else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use )) ) + else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use )) ) { /* Key found and usable. Check validity. */ int trustlevel; - + trustlevel = get_validity (pk, pk->user_id); - if ( (trustlevel & TRUST_FLAG_DISABLED) ) + if ( (trustlevel & TRUST_FLAG_DISABLED) ) { /*Key has been disabled. */ free_public_key(pk); pk = NULL; @@ -1109,7 +1109,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc=G10ERR_UNU_PUBKEY; goto fail; } - else if ( do_we_trust_pre( pk, trustlevel ) ) + else if ( do_we_trust_pre( pk, trustlevel ) ) { /* Note: do_we_trust may have changed the trustlevel */ @@ -1119,7 +1119,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* Skip the actual key if the key is already present * in the list */ - if (!key_present_in_pk_list(pk_list, pk)) + if (!key_present_in_pk_list(pk_list, pk)) { free_public_key(pk); pk = NULL; log_info(_("%s: skipped: public key already present\n"), @@ -1159,14 +1159,14 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) } } } - - if ( !rc && !any_recipients ) + + if ( !rc && !any_recipients ) { log_error(_("no valid addressees\n")); write_status_text (STATUS_NO_RECP, "0"); rc = G10ERR_NO_USER_ID; } - + fail: if ( rc ) @@ -1205,7 +1205,7 @@ algo_available( preftype_t preftype, int algo, const union pref_hint *hint) && algo != CIPHER_ALGO_3DES && algo != CIPHER_ALGO_CAST5)) return 0; - + if(PGP7 && (algo != CIPHER_ALGO_IDEA && algo != CIPHER_ALGO_3DES && algo != CIPHER_ALGO_CAST5 @@ -1411,7 +1411,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, if(result==-1) { - unsigned int best=-1; + unsigned int best=-1; /* At this point, we have not selected an algorithm due to a special request or via personal prefs. Pick the highest @@ -1469,11 +1469,11 @@ select_mdc_from_pklist (PK_LIST pk_list) if ( !pk_list ) return 0; - - for (pkr = pk_list; pkr; pkr = pkr->next) + + for (pkr = pk_list; pkr; pkr = pkr->next) { int mdc; - + if (pkr->pk->user_id) /* selected by user ID */ mdc = pkr->pk->user_id->flags.mdc; else @@ -1490,8 +1490,8 @@ void warn_missing_mdc_from_pklist (PK_LIST pk_list) { PK_LIST pkr; - - for (pkr = pk_list; pkr; pkr = pkr->next) + + for (pkr = pk_list; pkr; pkr = pkr->next) { int mdc; @@ -1509,8 +1509,8 @@ void warn_missing_aes_from_pklist (PK_LIST pk_list) { PK_LIST pkr; - - for (pkr = pk_list; pkr; pkr = pkr->next) + + for (pkr = pk_list; pkr; pkr = pkr->next) { const prefitem_t *prefs; int i; @@ -1520,7 +1520,7 @@ warn_missing_aes_from_pklist (PK_LIST pk_list) if (prefs) { for (i=0; !gotit && prefs[i].type; i++ ) - if (prefs[i].type == PREFTYPE_SYM + if (prefs[i].type == PREFTYPE_SYM && prefs[i].value == CIPHER_ALGO_AES) gotit++; } ----------------------------------------------------------------------- Summary of changes: g10/pkclist.c | 134 +++++++++++++++++++++++++++++---------------------------- g10/sign.c | 5 +- 2 files changed, 71 insertions(+), 68 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 12:45:35 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 12:45:35 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-119-gd61f740 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 d61f7402f2b0f6dd288e403ed9408fd65e617f85 (commit) from 8325d616593187ff227853de0295e3269b96edcb (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 d61f7402f2b0f6dd288e403ed9408fd65e617f85 Author: Werner Koch Date: Wed Dec 19 11:47:23 2012 +0100 gpg: Make commit 2b3cb2ee actually work * g10/sign.c (update_keysig_packet): Use digest_algo. (cherry-picked from commit d23ec86095714d388acac14b515445fe69f019e9) diff --git a/g10/sign.c b/g10/sign.c index 6238ce8..6ff7df6 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1576,7 +1576,8 @@ update_keysig_packet( PKT_signature **ret_sig, void *opaque) { PKT_signature *sig; - int rc=0, digest_algo; + int rc = 0; + int digest_algo; gcry_md_hd_t md; if ((!orig_sig || !pk || !pksk) @@ -1589,7 +1590,7 @@ update_keysig_packet( PKT_signature **ret_sig, else digest_algo = orig_sig->digest_algo; - if ( gcry_md_open (&md, orig_sig->digest_algo, 0 ) ) + if ( gcry_md_open (&md, digest_algo, 0 ) ) BUG (); /* Hash the public key certificate and the user id. */ ----------------------------------------------------------------------- Summary of changes: g10/sign.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 14:02:25 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 14:02:25 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-32-g5800434 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 58004340cc8c7124edc3c6866eec5478499b252e (commit) from f2f12f41efe5a476833295dc6c44fcd887d0abe6 (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 58004340cc8c7124edc3c6866eec5478499b252e Author: Werner Koch Date: Wed Dec 19 13:57:29 2012 +0100 Fix last commit * util/http.c (connect_server): Bump SRVINDEX and not SRV. diff --git a/util/http.c b/util/http.c index bab9796..b72489b 100644 --- a/util/http.c +++ b/util/http.c @@ -925,7 +925,7 @@ connect_server( const char *server, ushort port, unsigned int flags, #else /* !HAVE_GETADDRINFO */ - for(srvindex=0; srvindex < srvcount; srv++) + for(srvindex=0; srvindex < srvcount; srvindex++) { int i=0; struct hostent *host=NULL; ----------------------------------------------------------------------- Summary of changes: util/http.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 14:10:47 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 14:10:47 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-34-g3d56d48 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 3d56d486e1cfd7c32930a92afd6d0c558a90b77e (commit) via 550983f8fbe84ee81d3631b1dda91ad2e41b1a11 (commit) from 58004340cc8c7124edc3c6866eec5478499b252e (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 3d56d486e1cfd7c32930a92afd6d0c558a90b77e Author: Werner Koch Date: Wed Dec 19 14:05:56 2012 +0100 Remove trailing white space from some files -- diff --git a/g10/sign.c b/g10/sign.c index 462392d..6788f74 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -151,7 +151,7 @@ mk_notation_policy_etc( PKT_signature *sig, /* - * Helper to hash a user ID packet. + * Helper to hash a user ID packet. */ static void hash_uid (MD_HANDLE md, int sigversion, const PKT_user_id *uid) @@ -189,7 +189,7 @@ hash_uid (MD_HANDLE md, int sigversion, const PKT_user_id *uid) static void hash_sigversion_to_magic (MD_HANDLE md, const PKT_signature *sig) { - if (sig->version >= 4) + if (sig->version >= 4) md_putc (md, sig->version); md_putc (md, sig->sig_class); if (sig->version < 4) { @@ -202,7 +202,7 @@ hash_sigversion_to_magic (MD_HANDLE md, const PKT_signature *sig) else { byte buf[6]; size_t n; - + md_putc (md, sig->pubkey_algo); md_putc (md, sig->digest_algo); if (sig->hashed) { @@ -258,13 +258,13 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, sig->digest_algo = digest_algo; sig->digest_start[0] = dp[0]; sig->digest_start[1] = dp[1]; - if (sk->is_protected && sk->protect.s2k.mode == 1002) - { + if (sk->is_protected && sk->protect.s2k.mode == 1002) + { #ifdef ENABLE_CARD_SUPPORT unsigned char *rbuf; size_t rbuflen; char *snbuf; - + snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk); rc = agent_scd_pksign (snbuf, digest_algo, @@ -282,7 +282,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, return G10ERR_UNSUPPORTED; #endif /* ENABLE_CARD_SUPPORT */ } - else + else { frame = encode_md_value( NULL, sk, md, digest_algo ); if (!frame) @@ -492,7 +492,7 @@ print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what ) * Loop over the secret certificates in SK_LIST and build the one pass * signature packets. OpenPGP says that the data should be bracket by * the onepass-sig and signature-packet; so we build these onepass - * packet here in reverse order + * packet here in reverse order */ static int write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass ) @@ -508,7 +508,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass ) PKT_onepass_sig *ops; PACKET pkt; int i, rc; - + for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { if (++i == skcount) break; @@ -521,7 +521,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass ) ops->pubkey_algo = sk->pubkey_algo; keyid_from_sk (sk, ops->keyid); ops->last = (skcount == 1); - + init_packet(&pkt); pkt.pkttype = PKT_ONEPASS_SIG; pkt.pkt.onepass_sig = ops; @@ -611,7 +611,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, wipememory(copy_buffer,4096); /* burn buffer */ } /* fixme: it seems that we never freed pt/pkt */ - + return rc; } @@ -923,7 +923,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, there is an assumed preference for uncompressed data. Still, if it did fail, we'll also end up with the default. */ - + if((compr_algo= select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) compr_algo=default_compress_algo(); @@ -1095,7 +1095,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) outfile = NULL; errno = EPERM; } - else + else out = iobuf_create( outfile ); if( !out ) { @@ -1222,7 +1222,7 @@ sign_symencrypt_file (const char *fname, STRLIST locusr) } rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG); - if (rc) + if (rc) goto leave; /* prepare iobufs */ @@ -1234,7 +1234,7 @@ sign_symencrypt_file (const char *fname, STRLIST locusr) errno = EPERM; } if( !inp ) { - log_error(_("can't open `%s': %s\n"), + log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; @@ -1326,7 +1326,7 @@ sign_symencrypt_file (const char *fname, STRLIST locusr) create_time); if (rc) goto leave; - + /* Write the signatures */ /*(current filters: zip - encrypt - armor)*/ rc = write_signature_packets (sk_list, out, mfx.md, @@ -1482,7 +1482,7 @@ int update_keysig_packet( PKT_signature **ret_sig, PKT_signature *orig_sig, PKT_public_key *pk, - PKT_user_id *uid, + PKT_user_id *uid, PKT_public_key *subpk, PKT_secret_key *sk, int (*mksubpkt)(PKT_signature *, void *), @@ -1514,7 +1514,7 @@ update_keysig_packet( PKT_signature **ret_sig, /* create a new signature packet */ sig = copy_signature (NULL, orig_sig); - + /* We need to create a new timestamp so that new sig expiration calculations are done correctly... */ sig->timestamp=make_timestamp(); diff --git a/include/http.h b/include/http.h index 1ecdc60..38fe48d 100644 --- a/include/http.h +++ b/include/http.h @@ -53,7 +53,7 @@ typedef enum { /* put flag values into an enum, so that gdb can display them */ enum - { + { HTTP_FLAG_NO_SHUTDOWN = 1 }; diff --git a/util/http.c b/util/http.c index bfaaf1f..e5db605 100644 --- a/util/http.c +++ b/util/http.c @@ -94,7 +94,7 @@ init_sockets (void) return; if( WSAStartup( 0x0101, &wsdata ) ) { - log_error ("error initializing socket library: ec=%d\n", + log_error ("error initializing socket library: ec=%d\n", (int)WSAGetLastError () ); return; } @@ -205,7 +205,7 @@ http_wait_response( HTTP_HD hd, unsigned int *ret_status ) http_start_data( hd ); /* make sure that we are in the data */ #if 0 - hd->sock = dup( hd->sock ); + hd->sock = dup( hd->sock ); if( hd->sock == -1 ) return G10ERR_GENERAL; #endif @@ -843,9 +843,9 @@ connect_server( const char *server, ushort port, unsigned int flags, return -1; } - addr.sin_family=AF_INET; + addr.sin_family=AF_INET; addr.sin_port=htons(port); - memcpy(&addr.sin_addr,&inaddr,sizeof(inaddr)); + memcpy(&addr.sin_addr,&inaddr,sizeof(inaddr)); if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))==0) return sock; @@ -1025,7 +1025,7 @@ write_server( int sock, const char *data, size_t length ) nleft = length; while( nleft > 0 ) { -#ifdef _WIN32 +#ifdef _WIN32 int nwritten; nwritten = send (sock, data, nleft, 0); commit 550983f8fbe84ee81d3631b1dda91ad2e41b1a11 Author: Werner Koch Date: Wed Dec 19 14:03:25 2012 +0100 Adjust to GNU coding standards -- A variable definition with initialization shall have only one variable per type. diff --git a/util/http.c b/util/http.c index b72489b..bfaaf1f 100644 --- a/util/http.c +++ b/util/http.c @@ -817,8 +817,13 @@ static int connect_server( const char *server, ushort port, unsigned int flags, struct http_srv *srv ) { - int sock=-1, srvindex, srvcount=0, connected=0, hostfound=0, chosen=-1; - struct srventry *srvlist=NULL; + int sock = -1; + int srvcount = 0; + int connected = 0; + int hostfound = 0; + int chosen = -1; + struct srventry *srvlist = NULL; + int srvindex; #ifdef _WIN32 unsigned long inaddr; @@ -981,7 +986,7 @@ connect_server( const char *server, ushort port, unsigned int flags, } #endif /* !HAVE_GETADDRINFO */ - if(chosen>-1 && srv) + if(chosen > -1 && srv) { srv->used_server = strdup (srvlist[chosen].target); srv->used_port = srvlist[chosen].port; ----------------------------------------------------------------------- Summary of changes: g10/sign.c | 36 ++++++++++++++++++------------------ include/http.h | 2 +- util/http.c | 21 +++++++++++++-------- 3 files changed, 32 insertions(+), 27 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 15:35:10 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 19 Dec 2012 15:35:10 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-55-g20c95ef 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 20c95ef258f8520283406239f7c6f4729341d463 (commit) from d23ec86095714d388acac14b515445fe69f019e9 (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 20c95ef258f8520283406239f7c6f4729341d463 Author: Werner Koch Date: Wed Dec 19 15:30:17 2012 +0100 Fixed indentation and indented cpp directives -- diff --git a/common/http.c b/common/http.c index 5b67acc..755ab1b 100644 --- a/common/http.c +++ b/common/http.c @@ -150,7 +150,7 @@ static es_cookie_io_functions_t cookie_functions = cookie_close }; -struct cookie_s +struct cookie_s { int fd; /* File descriptor or -1 if already closed. */ gnutls_session_t tls_session; /* TLS session context or NULL if not used. */ @@ -176,7 +176,7 @@ typedef struct header_s *header_t; /* Our handle context. */ -struct http_context_s +struct http_context_s { unsigned int status_code; int sock; @@ -228,14 +228,14 @@ init_sockets (void) if (initialized) return; - if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) ) + if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) ) { - log_error ("error initializing socket library: ec=%d\n", + log_error ("error initializing socket library: ec=%d\n", (int)WSAGetLastError () ); return; } - if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR - || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR ) + if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR + || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR ) { log_error ("socket library version is %x.%x - but %d.%d needed\n", LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion), @@ -260,7 +260,7 @@ static char * make_header_line (const char *prefix, const char *suffix, const void *data, size_t len ) { - static unsigned char bintoasc[] = + static unsigned char bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; @@ -278,7 +278,7 @@ make_header_line (const char *prefix, const char *suffix, *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077]; *p++ = bintoasc[s[2]&077]; } - if ( len == 2 ) + if ( len == 2 ) { *p++ = bintoasc[(s[0] >> 2) & 077]; *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077]; @@ -306,7 +306,7 @@ http_register_tls_callback ( gpg_error_t (*cb) (http_t, void *, int) ) tls_callback = (gpg_error_t (*) (http_t, gnutls_session_t, int))cb; #else (void)cb; -#endif +#endif } @@ -315,13 +315,13 @@ http_register_tls_callback ( gpg_error_t (*cb) (http_t, void *, int) ) pointer for completing the the request and to wait for the response. */ gpg_error_t -http_open (http_t *r_hd, http_req_t reqtype, const char *url, +http_open (http_t *r_hd, http_req_t reqtype, const char *url, const char *auth, unsigned int flags, const char *proxy, void *tls_context, struct http_srv *srv, strlist_t headers) { gpg_error_t err; http_t hd; - + *r_hd = NULL; if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST)) @@ -339,7 +339,7 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url, err = http_parse_uri (&hd->uri, url); if (!err) err = send_request (hd, auth, proxy, srv, headers); - + if (err) { if (!hd->fp_read && !hd->fp_write && hd->sock != -1) @@ -382,7 +382,7 @@ http_wait_response (http_t hd) gpg_error_t err; /* Make sure that we are in the data. */ - http_start_data (hd); + http_start_data (hd); /* We dup the socket, to cope with the fact that fclose closes the underlying socket. In TLS mode we don't do that because we can't @@ -455,7 +455,7 @@ http_wait_response (http_t hd) be used as an HTTP proxy and any enabled $http_proxy gets ignored. */ gpg_error_t -http_open_document (http_t *r_hd, const char *document, +http_open_document (http_t *r_hd, const char *document, const char *auth, unsigned int flags, const char *proxy, void *tls_context, struct http_srv *srv, strlist_t headers) @@ -609,7 +609,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part) p++; if (*p == '/') /* There seems to be a hostname. */ - { + { p++; if ((p2 = strchr (p, '/'))) *p2++ = 0; @@ -667,7 +667,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part) return gpg_error (GPG_ERR_BAD_URI); /* Path includes a Nul. */ p = p2 ? p2 : NULL; - if (!p || !*p) + if (!p || !*p) return 0; /* We don't have a query string. Okay. */ /* Now parse the query string. */ @@ -861,7 +861,7 @@ send_request (http_t hd, const char *auth, if ( (proxy && *proxy) || ( (hd->flags & HTTP_FLAG_TRY_PROXY) - && (http_proxy = getenv (HTTP_PROXY_ENV)) + && (http_proxy = getenv (HTTP_PROXY_ENV)) && *http_proxy )) { parsed_uri_t uri; @@ -908,7 +908,7 @@ send_request (http_t hd, const char *auth, if (hd->sock == -1) { xfree (proxy_authstr); - return (save_errno + return (save_errno ? gpg_error_from_errno (save_errno) : gpg_error (GPG_ERR_NOT_FOUND)); } @@ -948,7 +948,7 @@ send_request (http_t hd, const char *auth, if (auth || hd->uri->auth) { char *myauth; - + if (auth) { myauth = xtrystrdup (auth); @@ -976,12 +976,12 @@ send_request (http_t hd, const char *auth, return gpg_error_from_syserror (); } } - + p = build_rel_path (hd->uri); if (!p) return gpg_error_from_syserror (); - request = xtrymalloc (2 * strlen (server) + request = xtrymalloc (2 * strlen (server) + strlen (p) + (authstr?strlen(authstr):0) + (proxy_authstr?strlen(proxy_authstr):0) @@ -1008,7 +1008,7 @@ send_request (http_t hd, const char *auth, else { char portstr[35]; - + if (port == 80 || (srv && srv->used_server)) *portstr = 0; else @@ -1190,7 +1190,7 @@ my_read_line ( char *p; if (!buffer) /* Must allocate a new buffer. */ - { + { length = 256; buffer = xtrymalloc (length); *addr_of_buffer = buffer; @@ -1207,7 +1207,7 @@ my_read_line ( while ((c = P_ES(getc) (fp)) != EOF) { if (nbytes == length) /* Increase the buffer. */ - { + { if (length > maxlen) /* Limit reached. */ { /* Skip the rest of the line. */ @@ -1312,7 +1312,7 @@ store_header (http_t hd, char *line) while (*p == ' ' || *p == '\t') p++; value = p; - + for (h=hd->headers; h; h = h->next) if ( !strcmp (h->name, line) ) break; @@ -1544,9 +1544,11 @@ connect_server (const char *server, unsigned short port, unsigned int flags, struct http_srv *srv) { int sock = -1; - int srvcount = 0, fakesrv = 0; + int srvcount = 0; + int fakesrv = 0; int hostfound = 0; - int srvindex, connected, chosen=-1; + int srvindex, connected; + int chosen = -1; int last_errno = 0; struct srventry *serverlist = NULL; @@ -1565,9 +1567,9 @@ connect_server (const char *server, unsigned short port, if ( inaddr != INADDR_NONE ) { struct sockaddr_in addr; - + memset(&addr,0,sizeof(addr)); - + sock = socket(AF_INET,SOCK_STREAM,0); if ( sock==INVALID_SOCKET ) { @@ -1575,9 +1577,9 @@ connect_server (const char *server, unsigned short port, return -1; } - addr.sin_family = AF_INET; + addr.sin_family = AF_INET; addr.sin_port = htons(port); - memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr)); + memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr)); if (!connect (sock,(struct sockaddr *)&addr,sizeof(addr)) ) return sock; @@ -1644,7 +1646,7 @@ connect_server (const char *server, unsigned short port, errno = save_errno; return -1; } - + if (connect (sock, ai->ai_addr, ai->ai_addrlen)) last_errno = errno; else @@ -1680,7 +1682,7 @@ connect_server (const char *server, unsigned short port, xfree (serverlist); return -1; } - + addr.sin_family = host->h_addrtype; if (addr.sin_family != AF_INET) { @@ -1714,7 +1716,7 @@ connect_server (const char *server, unsigned short port, } #endif /* !HAVE_GETADDRINFO */ - if(!fakesrv && chosen>-1 && srv) + if(!fakesrv && chosen >- 1 && srv) { srv->used_server = xstrdup (serverlist[chosen].target); srv->used_port = serverlist[chosen].port; @@ -1753,9 +1755,9 @@ write_server (int sock, const char *data, size_t length) { #ifdef HAVE_W32_SYSTEM int nwritten; - + nwritten = send (sock, data, nleft, 0); - if ( nwritten == SOCKET_ERROR ) + if ( nwritten == SOCKET_ERROR ) { log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ()); return gpg_error (GPG_ERR_NETWORK); @@ -1808,7 +1810,7 @@ cookie_read (void *cookie, void *buffer, size_t size) if (nread == GNUTLS_E_AGAIN) { struct timeval tv; - + tv.tv_sec = 0; tv.tv_usec = 50000; select (0, NULL, NULL, NULL, &tv); @@ -1829,7 +1831,7 @@ cookie_read (void *cookie, void *buffer, size_t size) #ifdef HAVE_W32_SYSTEM /* Under Windows we need to use recv for a socket. */ nread = recv (c->fd, buffer, size, 0); -#else +#else nread = read (c->fd, buffer, size); #endif } @@ -1852,7 +1854,7 @@ cookie_write (void *cookie, const void *buffer, size_t size) int nleft = size; while (nleft > 0) { - nwritten = gnutls_record_send (c->tls_session, buffer, nleft); + nwritten = gnutls_record_send (c->tls_session, buffer, nleft); if (nwritten <= 0) { if (nwritten == GNUTLS_E_INTERRUPTED) @@ -1860,7 +1862,7 @@ cookie_write (void *cookie, const void *buffer, size_t size) if (nwritten == GNUTLS_E_AGAIN) { struct timeval tv; - + tv.tv_sec = 0; tv.tv_usec = 50000; select (0, NULL, NULL, NULL, &tv); @@ -2037,7 +2039,7 @@ main (int argc, char **argv) http_release_parsed_uri (uri); uri = NULL; - rc = http_open_document (&hd, *argv, NULL, + rc = http_open_document (&hd, *argv, NULL, HTTP_FLAG_NO_SHUTDOWN | HTTP_FLAG_NEED_HEADER, NULL, tls_session); if (rc) diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index 73f5e56..ff41f97 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -36,29 +36,30 @@ #include #include #ifdef HAVE_GETOPT_H -#include +# include #endif #ifdef HAVE_LIBCURL -#include +# include /* This #define rigamarole is to enable a hack to fake DNS SRV using libcurl. It only works if we have getaddrinfo(), inet_ntop(), and a modern enough version of libcurl (7.21.3) so we can use CURLOPT_RESOLVE to feed the resolver from the outside to force libcurl to pass the right SNI. */ -#if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP) && LIBCURL_VERNUM >= 0x071503 -#include -#include -#include -#include +# if (defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP) \ + && LIBCURL_VERNUM >= 0x071503) +# include +# include +# include +# include +# else +# undef USE_DNS_SRV +# endif #else -#undef USE_DNS_SRV -#endif -#else -#include "curl-shim.h" +# include "curl-shim.h" #endif #include "util.h" #ifdef USE_DNS_SRV -#include "srv.h" +# include "srv.h" #endif #include "keyserver.h" #include "ksutil.h" @@ -73,9 +74,10 @@ static char errorbuffer[CURL_ERROR_SIZE]; static char *proto,*port; static size_t -curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream) +curl_mrindex_writer (const void *ptr,size_t size,size_t nmemb,void *stream) { - static int checked=0,swallow=0; + static int checked = 0; + static int swallow = 0; if(!checked) { @@ -367,7 +369,7 @@ get_name(const char *getkey) ret=KEYSERVER_NO_MEMORY; goto fail; } - + fprintf(output,"NAME %s BEGIN\n",getkey); if(opt->verbose>2) @@ -617,7 +619,7 @@ srv_replace(const char *srvtag, } #endif -static void +static void show_help (FILE *fp) { fprintf (fp,"-h, --help\thelp\n"); @@ -827,7 +829,7 @@ main(int argc,char *argv[]) /* We're using libcurl, so fake SRV support via our wrapper. This isn't as good as true SRV support, as we do not try all possible targets at one particular level and work our way - down the list, but it's better than nothing. */ + down the list, but it's better than nothing. */ #ifdef USE_DNS_SRV srv_replace(srvtag,&headers,&resolve); #else ----------------------------------------------------------------------- Summary of changes: common/http.c | 84 ++++++++++++++++++++++++----------------------- keyserver/gpgkeys_hkp.c | 36 ++++++++++--------- 2 files changed, 62 insertions(+), 58 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Dec 19 19:58:41 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Wed, 19 Dec 2012 19:58:41 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-36-g5c557a5 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 5c557a51cdf37d9f50b3d5d7e11d17e6ea6bb2b8 (commit) via 6c3a76cca064070d0a9e636fedc824415e710451 (commit) from 3d56d486e1cfd7c32930a92afd6d0c558a90b77e (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 5c557a51cdf37d9f50b3d5d7e11d17e6ea6bb2b8 Author: David Shaw Date: Wed Dec 19 13:54:27 2012 -0500 Issue 1447: Pass proper Host header and SNI when SRV is used with curl. * configure.ac: Check for inet_ntop. * m4/libcurl.m4: Provide a #define for the version of the curl library. * keyserver/gpgkeys_hkp.c (main, srv_replace): Call getaddrinfo() on each target. Once we find one that resolves to an address (whether IPv4 or IPv6), pass it into libcurl via CURLOPT_RESOLVE using the SRV name as the "host". Force the HTTP Host header to be the same. Backported from 6b1f71055ebab36989e2089cfde319d2ba40ada7 * keyserver/gpgkeys_hkp.c (main): Only default try-dns-srv to on if we have SRV support in the first place. Backported from 732f3d1d4786239db5f31f82cc04ec79326cc13c diff --git a/configure.ac b/configure.ac index ef0bb6e..0955eee 100644 --- a/configure.ac +++ b/configure.ac @@ -1021,7 +1021,7 @@ AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times unsetenv getpwnam getpwuid) AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime) AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale) AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo) -AC_CHECK_FUNCS(fcntl ftruncate) +AC_CHECK_FUNCS(fcntl ftruncate inet_ntop) AC_REPLACE_FUNCS(mkdtemp timegm isascii memrchr strsep) AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include ]) diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index 27d67c6..382bee5 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -36,15 +36,29 @@ #include #include #ifdef HAVE_GETOPT_H -#include +# include #endif #ifdef HAVE_LIBCURL -#include +# include +/* This #define rigamarole is to enable a hack to fake DNS SRV using + libcurl. It only works if we have getaddrinfo(), inet_ntop(), and + a modern enough version of libcurl (7.21.3) so we can use + CURLOPT_RESOLVE to feed the resolver from the outside to force + libcurl to pass the right SNI. */ +#if (defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP) \ + && LIBCURL_VERNUM >= 0x071503) +# include +# include +# include +# include #else -#include "curl-shim.h" +# undef USE_DNS_SRV +#endif +#else +# include "curl-shim.h" #endif #ifdef USE_DNS_SRV -#include "srv.h" +# include "srv.h" #endif #include "compat.h" #include "keyserver.h" @@ -62,7 +76,8 @@ static char *proto,*port; static size_t curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream) { - static int checked=0,swallow=0; + static int checked=0; + static int swallow=0; if(!checked) { @@ -496,18 +511,29 @@ fail_all(struct keylist *keylist,int err) } } -#ifdef HAVE_LIBCURL +#if defined(HAVE_LIBCURL) && defined(USE_DNS_SRV) /* If there is a SRV record, take the highest ranked possibility. - This is a hack, as we don't proceed downwards. */ + This is a hack, as we don't proceed downwards if we can't + connect(), but only if we can't getaddinfo(). All this should + ideally be replaced by actual SRV support in libcurl someday! */ + +#define HOST_HEADER "Host:" + static void -srv_replace(const char *srvtag) +srv_replace(const char *srvtag, + struct curl_slist **headers, struct curl_slist **resolve) { -#ifdef USE_DNS_SRV struct srventry *srvlist=NULL; + int srvcount, srvindex; + char *portstr; if(!srvtag) return; + portstr=malloc (MAX_PORT); + if(!portstr) + return; + if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME) { char srvname[MAXDNAME]; @@ -516,30 +542,78 @@ srv_replace(const char *srvtag) strcat(srvname,srvtag); strcat(srvname,"._tcp."); strcat(srvname,opt->host); - getsrv(srvname,&srvlist); + srvcount=getsrv(srvname,&srvlist); } - if(srvlist) + for(srvindex=0 ; srvindextarget); - newport=xtrymalloc(MAX_PORT); - if(newname && newport) + if (getaddrinfo (srvlist[srvindex].target, portstr, &hints, &res) == 0) { - free(opt->host); - free(opt->port); - opt->host=newname; - snprintf(newport,MAX_PORT,"%u",srvlist->port); - opt->port=newport; + /* Very safe */ + char ipaddr[INET_ADDRSTRLEN+INET6_ADDRSTRLEN]; + + if((res->ai_family==AF_INET + && inet_ntop (res->ai_family, + &((struct sockaddr_in *)res->ai_addr)->sin_addr, + ipaddr,sizeof(ipaddr))) + || (res->ai_family==AF_INET6 + && inet_ntop (res->ai_family, + &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, + ipaddr,sizeof(ipaddr)))) + { + char *entry,*host; + + entry=malloc (strlen(opt->host)+1 + +strlen(portstr)+1+strlen(ipaddr)+1); + + host=malloc (strlen(HOST_HEADER)+1+strlen(opt->host)+1); + + if(entry && host) + { + sprintf (entry, "%s:%s:%s", opt->host, portstr, ipaddr); + sprintf (host, "%s %s", HOST_HEADER, opt->host); + + *resolve=curl_slist_append (*resolve,entry); + *headers=curl_slist_append (*headers,host); + + if(*resolve && *headers) + { + if(curl_easy_setopt (curl, + CURLOPT_RESOLVE,*resolve)==CURLE_OK) + + { + if(opt->debug) + fprintf (console, "gpgkeys: Faking %s SRV from" + " %s to %s:%u\n", + srvtag, opt->host, + srvlist[srvindex].target, + srvlist[srvindex].port); + + free (opt->port); + opt->port=portstr; + portstr=NULL; + } + } + } + + free (entry); + free (host); + } + + freeaddrinfo (res); } else - { - free(newname); - free(newport); - } + continue; /* Not found */ } -#endif + + free (srvlist); + free (portstr); } #endif @@ -555,12 +629,20 @@ show_help (FILE *fp) int main(int argc,char *argv[]) { - int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1; + int arg,ret=KEYSERVER_INTERNAL_ERROR; char line[MAX_LINE]; int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; char *proxy=NULL; struct curl_slist *headers=NULL; + struct curl_slist *resolve=NULL; + + /* Only default this to on if we have SRV support */ +#ifdef USE_DNS_SRV + int try_srv = 1; +#else + int try_srv = 0; +#endif console=stderr; @@ -723,6 +805,13 @@ main(int argc,char *argv[]) goto fail; } + if(opt->debug) + { + fprintf(console,"gpgkeys: curl version = %s\n",curl_version()); + curl_easy_setopt(curl,CURLOPT_STDERR,console); + curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); + } + /* Only use SRV if the user does not provide a :port. The semantics of a specified port and SRV do not play well together. */ if(!opt->port && try_srv) @@ -741,8 +830,12 @@ main(int argc,char *argv[]) This isn't as good as true SRV support, as we do not try all possible targets at one particular level and work our way down the list, but it's better than nothing. */ - srv_replace(srvtag); +#ifdef USE_DNS_SRV + srv_replace(srvtag,&headers,&resolve); #else + fprintf(console,"gpgkeys: try-dns-srv was requested, but not SRV capable\n"); +#endif +#else /* !HAVE_LIBCURL */ /* We're using our internal curl shim, so we can use its (true) SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real libcurl option. It's specific to our shim. */ @@ -760,13 +853,6 @@ main(int argc,char *argv[]) if(opt->auth) curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth); - if(opt->debug) - { - fprintf(console,"gpgkeys: curl version = %s\n",curl_version()); - curl_easy_setopt(curl,CURLOPT_STDERR,console); - curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); - } - curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); @@ -968,6 +1054,7 @@ main(int argc,char *argv[]) free_ks_options(opt); curl_slist_free_all(headers); + curl_slist_free_all(resolve); if(curl) curl_easy_cleanup(curl); diff --git a/m4/libcurl.m4 b/m4/libcurl.m4 index c763146..ce02add 100644 --- a/m4/libcurl.m4 +++ b/m4/libcurl.m4 @@ -66,6 +66,11 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG], _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" + # More recent versions of curl-config have a direct --vernum + # option, but we'd like this code to work with older versions as + # well, so just convert --version. + _libcurl_vernum_parse="eval $AWK '{printf \"0x%06X\",\$NF}'" + _libcurl_try_link=yes if test -d "$_libcurl_with" ; then @@ -206,6 +211,10 @@ x=CURLOPT_VERBOSE; AC_SUBST(LIBCURL_CPPFLAGS) AC_SUBST(LIBCURL) + _libcurl_vernum=`echo $_libcurl_version | $_libcurl_vernum_parse` + + AC_DEFINE_UNQUOTED(LIBCURL_VERNUM,$_libcurl_vernum,[The version of the libcurl library in packed hex form]) + for _libcurl_feature in $_libcurl_features ; do AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes @@ -246,6 +255,7 @@ x=CURLOPT_VERBOSE; unset _libcurl_protocol unset _libcurl_protocols unset _libcurl_version + unset _libcurl_vernum unset _libcurl_ldflags fi commit 6c3a76cca064070d0a9e636fedc824415e710451 Author: David Shaw Date: Wed Dec 19 11:43:28 2012 -0500 Part of issue 1447: Pass proper Host header when SRV is used. * common/http.c (send_request, connect_server): Set proper Host header (no :port, host is that of the SRV) when SRV is used in the curl-shim. Backported from cbe98b2cb1e40ba253300e604996681ae191e363 diff --git a/util/http.c b/util/http.c index e5db605..2f630ae 100644 --- a/util/http.c +++ b/util/http.c @@ -599,16 +599,18 @@ send_request( HTTP_HD hd, const char *auth, const char *proxy, authstr?authstr:"",proxy_authstr?proxy_authstr:"" ); else { - char portstr[15]; + char portstr[35]; - if(port!=80) + if(port == 80 || (srv && srv->used_server)) + *portstr = 0; + else sprintf(portstr,":%u",port); sprintf( request, "%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", hd->req_type == HTTP_REQ_GET ? "GET" : hd->req_type == HTTP_REQ_HEAD? "HEAD": hd->req_type == HTTP_REQ_POST? "POST": "OOPS", - *p == '/'? "":"/", p, server, (port!=80)?portstr:"", + *p == '/'? "":"/", p, server, portstr, authstr?authstr:""); } @@ -822,6 +824,7 @@ connect_server( const char *server, ushort port, unsigned int flags, int connected = 0; int hostfound = 0; int chosen = -1; + int fakesrv = 0; struct srventry *srvlist = NULL; int srvindex; @@ -885,7 +888,8 @@ connect_server( const char *server, ushort port, unsigned int flags, srvlist->port=port; strncpy(srvlist->target,server,MAXDNAME); srvlist->target[MAXDNAME-1]='\0'; - srvcount=1; + srvcount = 1; + fakesrv = 1; } #ifdef HAVE_GETADDRINFO @@ -986,7 +990,7 @@ connect_server( const char *server, ushort port, unsigned int flags, } #endif /* !HAVE_GETADDRINFO */ - if(chosen > -1 && srv) + if(!fakesrv && chosen > -1 && srv) { srv->used_server = strdup (srvlist[chosen].target); srv->used_port = srvlist[chosen].port; ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 +- keyserver/gpgkeys_hkp.c | 155 ++++++++++++++++++++++++++++++++++++---------- m4/libcurl.m4 | 10 +++ util/http.c | 14 +++-- 4 files changed, 141 insertions(+), 40 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 20 09:51:21 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 20 Dec 2012 09:51:21 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-38-g3a4b96e 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 3a4b96e665fa639772854058737ee3d54ba0694e (commit) via f795a0d59e197455f8723c300eebf59e09853efa (commit) from 5c557a51cdf37d9f50b3d5d7e11d17e6ea6bb2b8 (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 3a4b96e665fa639772854058737ee3d54ba0694e Author: Werner Koch Date: Wed Dec 19 11:21:26 2012 +0100 gpg: Suppress "public key already present" in quiet mode. * g10/pkclist.c (build_pk_list): Print two diagnostics only in non-quiet mode. -- (back-ported from commit 8325d616593187ff227853de0295e3269b96edcb) diff --git a/g10/pkclist.c b/g10/pkclist.c index 158ddf0..e8167c7 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -833,8 +833,9 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) if (key_present_in_pk_list(pk_list, pk) == 0) { free_public_key (pk); pk = NULL; - log_info (_("%s: skipped: public key already present\n"), - rov->d); + if (!opt.quiet) + log_info (_("%s: skipped: public key already present\n"), + rov->d); } else { @@ -1113,8 +1114,9 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) if (!key_present_in_pk_list(pk_list, pk)) { free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key already present\n"), - remusr->d); + if (!opt.quiet) + log_info(_("%s: skipped: public key already present\n"), + remusr->d); } else { commit f795a0d59e197455f8723c300eebf59e09853efa Author: Werner Koch Date: Thu Dec 20 09:43:41 2012 +0100 Import only packets which are allowed in a keyblock. * g10/import.c (valid_keyblock_packet): New. (read_block): Store only valid packets. -- A corrupted key, which for example included a mangled public key encrypted packet, used to corrupt the keyring. This change skips all packets which are not allowed in a keyblock. GnuPG-bug-id: 1455 diff --git a/g10/import.c b/g10/import.c index 21ada41..90fc2d6 100644 --- a/g10/import.c +++ b/g10/import.c @@ -343,6 +343,27 @@ import_print_stats (void *hd) } +/* Return true if PKTTYPE is valid in a keyblock. */ +static int +valid_keyblock_packet (int pkttype) +{ + switch (pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_KEY: + case PKT_SECRET_SUBKEY: + case PKT_SIGNATURE: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + case PKT_RING_TRUST: + return 1; + default: + return 0; + } +} + + /**************** * Read the next keyblock from stream A. * PENDING_PKT should be initialzed to NULL @@ -420,7 +441,7 @@ read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ) } in_cert = 1; default: - if( in_cert ) { + if (in_cert && valid_keyblock_packet (pkt->pkttype)) { if( !root ) root = new_kbnode( pkt ); else ----------------------------------------------------------------------- Summary of changes: g10/import.c | 23 ++++++++++++++++++++++- g10/pkclist.c | 10 ++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 20 12:36:20 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 20 Dec 2012 12:36:20 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-56-g4988822 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 498882296ffac7987c644aaf2a0aa108a2925471 (commit) from 20c95ef258f8520283406239f7c6f4729341d463 (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 498882296ffac7987c644aaf2a0aa108a2925471 Author: Werner Koch Date: Thu Dec 20 09:43:41 2012 +0100 gpg: Import only packets which are allowed in a keyblock. * g10/import.c (valid_keyblock_packet): New. (read_block): Store only valid packets. -- A corrupted key, which for example included a mangled public key encrypted packet, used to corrupt the keyring. This change skips all packets which are not allowed in a keyblock. GnuPG-bug-id: 1455 (cherry-picked from commit 3a4b96e665fa639772854058737ee3d54ba0694e) diff --git a/g10/import.c b/g10/import.c index ba2439d..ad112d6 100644 --- a/g10/import.c +++ b/g10/import.c @@ -347,6 +347,27 @@ import_print_stats (void *hd) } +/* Return true if PKTTYPE is valid in a keyblock. */ +static int +valid_keyblock_packet (int pkttype) +{ + switch (pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_KEY: + case PKT_SECRET_SUBKEY: + case PKT_SIGNATURE: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + case PKT_RING_TRUST: + return 1; + default: + return 0; + } +} + + /**************** * Read the next keyblock from stream A. * PENDING_PKT should be initialzed to NULL @@ -424,7 +445,7 @@ read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ) } in_cert = 1; default: - if( in_cert ) { + if (in_cert && valid_keyblock_packet (pkt->pkttype)) { if( !root ) root = new_kbnode( pkt ); else ----------------------------------------------------------------------- Summary of changes: g10/import.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 20 14:56:24 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 20 Dec 2012 14:56:24 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-120-gf0b33b6 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 f0b33b6fb8e0586e9584a7a409dcc31263776a67 (commit) from d61f7402f2b0f6dd288e403ed9408fd65e617f85 (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 f0b33b6fb8e0586e9584a7a409dcc31263776a67 Author: Werner Koch Date: Thu Dec 20 09:43:41 2012 +0100 gpg: Import only packets which are allowed in a keyblock. * g10/import.c (valid_keyblock_packet): New. (read_block): Store only valid packets. -- A corrupted key, which for example included a mangled public key encrypted packet, used to corrupt the keyring. This change skips all packets which are not allowed in a keyblock. GnuPG-bug-id: 1455 (cherry-picked from commit f795a0d59e197455f8723c300eebf59e09853efa) diff --git a/g10/import.c b/g10/import.c index bfe02eb..a57b32e 100644 --- a/g10/import.c +++ b/g10/import.c @@ -384,6 +384,27 @@ import_print_stats (void *hd) } +/* Return true if PKTTYPE is valid in a keyblock. */ +static int +valid_keyblock_packet (int pkttype) +{ + switch (pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_KEY: + case PKT_SECRET_SUBKEY: + case PKT_SIGNATURE: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + case PKT_RING_TRUST: + return 1; + default: + return 0; + } +} + + /**************** * Read the next keyblock from stream A. * PENDING_PKT should be initialzed to NULL @@ -461,7 +482,7 @@ read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ) } in_cert = 1; default: - if( in_cert ) { + if (in_cert && valid_keyblock_packet (pkt->pkttype)) { if( !root ) root = new_kbnode( pkt ); else ----------------------------------------------------------------------- Summary of changes: g10/import.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Dec 20 21:30:07 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 20 Dec 2012 21:30:07 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.13-1-gfaf2174 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 faf217497902e6176c64e6db0191f35ccef97c57 (commit) from 0bd168bf8eecf4ec11c147edada0f08bebdc6cc0 (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 faf217497902e6176c64e6db0191f35ccef97c57 Author: Werner Koch Date: Thu Dec 20 21:25:07 2012 +0100 Post release updates -- diff --git a/NEWS b/NEWS index 0f3bee6..110de6d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.4.14 (unreleased) +------------------------------------------------- + + Noteworthy changes in version 1.4.13 (2012-12-20) ------------------------------------------------- diff --git a/configure.ac b/configure.ac index 85c0df6..c23cab2 100644 --- a/configure.ac +++ b/configure.ac @@ -25,8 +25,8 @@ min_automake_version="1.9.3" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh --force" right before creating a distribution. -m4_define([my_version], [1.4.13]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.4.14]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) ----------------------------------------------------------------------- Summary of changes: NEWS | 4 ++++ configure.ac | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Dec 21 00:15:55 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Fri, 21 Dec 2012 00:15:55 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-57-g8c32d4d 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 8c32d4de57b8b0b5e1be3022d4056a854c568745 (commit) from 498882296ffac7987c644aaf2a0aa108a2925471 (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 8c32d4de57b8b0b5e1be3022d4056a854c568745 Author: David Shaw Date: Thu Dec 20 18:12:29 2012 -0500 Make sure srvcount is initialized. * keyserver/gpgkeys_hkp.c (srv_replace): Initialize srvcount. diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index ff41f97..d90027a 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -547,6 +547,8 @@ srv_replace(const char *srvtag, strcat(srvname,opt->host); srvcount=getsrv(srvname,&srvlist); } + else + srvcount = 0; for(srvindex=0 ; srvindex 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 09ac5d87d11aa0b1fa0e0a4184ab03b3671a73e2 (commit) via d842eea55e22c05da3959a7a4422b5fcd7884f60 (commit) from efd7002188e6d50013e4d9a920a8b9afa9d210e5 (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 09ac5d87d11aa0b1fa0e0a4184ab03b3671a73e2 Author: Werner Koch Date: Fri Dec 21 17:26:06 2012 +0100 Prepare for hardware feature detection on other platforms. * configure.ac (GCRYPT_HWF_MODULES): New. (HAVE_CPU_ARCH_X86, HAVE_CPU_ARCH_ALPHA, HAVE_CPU_ARCH_SPARC) (HAVE_CPU_ARCH_MIPS, HAVE_CPU_ARCH_M68K, HAVE_CPU_ARCH_PPC) (HAVE_CPU_ARCH_ARM): New AC_DEFINEs. * mpi/config.links (mpi_cpu_arch): New. * src/global.c (print_config): Print new tag "cpu-arch". * src/Makefile.am (libgcrypt_la_SOURCES): Add hwf-common.h (EXTRA_libgcrypt_la_SOURCES): New. (gcrypt_hwf_modules): New. (libgcrypt_la_DEPENDENCIES, libgcrypt_la_LIBADD): Add that one. * src/hwfeatures.c: Factor most code out to ... * src/hwf-x86.c: New file. (detect_x86_gnuc): Return the feature vector. (_gcry_hwf_detect_x86): New. * src/hwf-common.h: New. * src/hwfeatures.c (_gcry_detect_hw_features): Dispatch using HAVE_CPU_ARCH_ macros. Signed-off-by: Werner Koch diff --git a/configure.ac b/configure.ac index 7d162a2..5e57868 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,7 @@ # Configure.ac script for Libgcrypt # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, # 2007, 2008, 2009, 2011 Free Software Foundation, Inc. +# Copyright (C) 2012 g10 Code GmbH # # This file is part of Libgcrypt. # @@ -958,6 +959,9 @@ fi # # Setup assembler stuff. # +# Note that config.links also defines mpi_cpu_arch, which is required +# later on. +# GNUPG_SYS_SYMBOL_UNDERSCORE() AC_ARG_ENABLE(mpi-path, AC_HELP_STRING([--enable-mpi-path=EXTRA_PATH], @@ -1269,6 +1273,38 @@ AC_DEFINE_UNQUOTED(LIBGCRYPT_DIGESTS, "$tmp", [List of available digest algorithms]) +# +# Define conditional sources depending on the used hardware platform. +# Note that all possible modules must also be listed in +# src/Makefile.am (EXTRA_libgcrypt_la_SOURCES). +# +GCRYPT_HWF_MODULES= +case "$mpi_cpu_arch" in + x86) + AC_DEFINE(HAVE_CPU_ARCH_X86, 1, [Defined for the x86 platforms]) + GCRYPT_HWF_MODULES="hwf-x86.lo" + ;; + alpha) + AC_DEFINE(HAVE_CPU_ARCH_ALPHA, 1, [Defined for Alpha platforms]) + ;; + sparc) + AC_DEFINE(HAVE_CPU_ARCH_SPARC, 1, [Defined for SPARC platforms]) + ;; + mips) + AC_DEFINE(HAVE_CPU_ARCH_MIPS, 1, [Defined for MIPS platforms]) + ;; + m68k) + AC_DEFINE(HAVE_CPU_ARCH_M68K, 1, [Defined for M68k platforms]) + ;; + ppc) + AC_DEFINE(HAVE_CPU_ARCH_PPC, 1, [Defined for PPC platforms]) + ;; + arm) + AC_DEFINE(HAVE_CPU_ARCH_ARM, 1, [Defined for ARM platforms]) + ;; +esac +AC_SUBST([GCRYPT_HWF_MODULES]) + # Generate extended version information for W32. if test "$have_w32_system" = yes; then @@ -1304,11 +1340,16 @@ tests/Makefile ]) AC_OUTPUT + +detection_module="${GCRYPT_HWF_MODULES%.lo}" +test -n "$detection_module" || detection_module="none" + # Give some feedback echo " Libgcrypt v${VERSION} has been configured as follows: Platform: $PRINTABLE_OS_NAME ($host) + Hardware detection module: $detection_module Enabled cipher algorithms: $enabled_ciphers Enabled digest algorithms: $enabled_digests Enabled pubkey algorithms: $enabled_pubkey_ciphers diff --git a/mpi/config.links b/mpi/config.links index 7e910ee..bcc6e3e 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -1,5 +1,6 @@ # config.links - helper for ../configure -*- mode: sh -*- # Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +# Copyright (C) 2012 g10 Code GmbH # # This file is part of Libgcrypt. # @@ -23,6 +24,7 @@ mpi_sflags= mpi_extra_modules= +mpi_cpu_arch= test -d ./mpi || mkdir ./mpi @@ -44,6 +46,7 @@ case "${host}" in i[34567]86*-*-openbsd3.[0123]*) echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h path="" + mpi_cpu_arch="x86" ;; i[3467]86*-*-openbsd* | \ i[3467]86*-*-freebsd*-elf | \ @@ -54,6 +57,7 @@ case "${host}" in echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i386" + mpi_cpu_arch="x86" ;; i586*-*-openbsd* | \ i586*-*-freebsd*-elf | \ @@ -66,11 +70,13 @@ case "${host}" in echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i586 i386" + mpi_cpu_arch="x86" ;; i[34]86*-*-bsdi4*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i386" + mpi_cpu_arch="x86" ;; i[3467]86*-*-linuxaout* | \ i[3467]86*-*-linuxoldld* | \ @@ -79,6 +85,7 @@ case "${host}" in echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i386" + mpi_cpu_arch="x86" ;; i586*-*-linuxaout* | \ i586*-*-linuxoldld* | \ @@ -87,23 +94,27 @@ case "${host}" in echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i586 i386" + mpi_cpu_arch="x86" ;; i[3467]86*-msdosdjgpp* | \ i[34]86*-apple-darwin*) echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i386" + mpi_cpu_arch="x86" ;; i586*-msdosdjgpp* | \ i[567]86*-apple-darwin*) echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i586 i386" + mpi_cpu_arch="x86" ;; i[3467]86*-*-*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i386" + mpi_cpu_arch="x86" ;; i586*-*-* | \ pentium-*-* | \ @@ -111,16 +122,19 @@ case "${host}" in echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="i586 i386" + mpi_cpu_arch="x86" ;; x86_64-*-*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h path="amd64" + mpi_cpu_arch="x86" ;; alpha*-*-*) echo '/* configured for alpha */' >>./mpi/asm-syntax.h path="alpha" mpi_extra_modules="udiv-qrnnd" + mpi_cpu_arch="alpha" ;; hppa7000*-*-*) echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h @@ -140,49 +154,59 @@ case "${host}" in sparc64-*-linux-gnu) echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h path="" + mpi_cpu_arch="sparc" ;; sparc64-sun-solaris2*) echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h path="" + mpi_cpu_arch="sparc" ;; sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*) # There are no sparc64 assembler modules that work on the # *BSDs, so use the generic C functions. echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h path="" + mpi_cpu_arch="sparc" ;; sparc64*-*-*) echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h path="" + mpi_cpu_arch="sparc" ;; sparc9*-*-* | \ ultrasparc*-*-* ) echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h path="sparc32v8 sparc32" + mpi_cpu_arch="sparc" ;; sparc8*-*-* | \ microsparc*-*-*) echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h path="sparc32v8 sparc32" + mpi_cpu_arch="sparc" ;; supersparc*-*-*) echo '/* configured for supersparc */' >>./mpi/asm-syntax.h path="supersparc sparc32v8 sparc32" mpi_extra_modules="udiv" + mpi_cpu_arch="sparc" ;; sparc*-*-*) echo '/* configured for sparc */' >>./mpi/asm-syntax.h path="sparc32" mpi_extra_modules="udiv" + mpi_cpu_arch="sparc" ;; mips[34]*-*-* | \ mips*-*-irix6*) echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h path="mips3" + mpi_cpu_arch="mips" ;; mips*-*-*) echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h path="mips2" + mpi_cpu_arch="mips" ;; # Motorola 68k configurations. Let m68k mean 68020-68040. @@ -192,38 +216,45 @@ case "${host}" in echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h path="m68k/mc68020 m68k" + mpi_cpu_arch="m68k" ;; m68060*-*-linuxaout*) echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h path="m68k" + mpi_cpu_arch="m68k" ;; m680[234]0*-*-linux* | \ m68k*-*-linux*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + mpi_cpu_arch="m68k" ;; m68060*-*-linux*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h path="m68k" + mpi_cpu_arch="m68k" ;; m68k-atari-mint) echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h path="m68k/mc68020 m68k" + mpi_cpu_arch="m68k" ;; m68000*-*-* | \ m68060*-*-*) echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h path="m68k/mc68000" + mpi_cpu_arch="m68k" ;; m680[234]0*-*-* | \ m68k*-*-*) echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h path="m68k/mc68020 m68k" + mpi_cpu_arch="m68k" ;; powerpc*-*-netbsd* | powerpc*-*-openbsd*) @@ -232,18 +263,21 @@ case "${host}" in cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h mpi_sflags="-Wa,-mppc" path="powerpc32" + mpi_cpu_arch="ppc" ;; ppc620-*-* | \ powerpc64*-*-*) mpi_sflags="-Wa,-mppc" path="powerpc64" + mpi_cpu_arch="ppc" ;; powerpc*-*-linux*) echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h path="powerpc32" + mpi_cpu_arch="ppc" ;; rs6000-*-aix[456789]* | \ @@ -258,6 +292,7 @@ case "${host}" in mpi_sflags="-Wa,-mppc" path="power" mpi_extra_modules="udiv-w-sdiv" + mpi_cpu_arch="ppc" ;; powerpc-ibm-aix4.2.* ) # I am not sure about this one but a machine identified by @@ -265,18 +300,22 @@ case "${host}" in mpi_sflags="-Wa,-mpwr" path="power" mpi_extra_modules="udiv-w-sdiv" + mpi_cpu_arch="ppc" ;; ppc601-*-*) mpi_sflags="-Wa,-mppc" path="power powerpc32" + mpi_cpu_arch="ppc" ;; ppc60[234]*-*-*) mpi_sflags="-Wa,-mppc" path="powerpc32" + mpi_cpu_arch="ppc" ;; powerpc*-*-*) mpi_sflags="-Wa,-mppc" path="powerpc32" + mpi_cpu_arch="ppc" ;; *) echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h diff --git a/src/Makefile.am b/src/Makefile.am index 2a07067..cdfe0c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,12 +54,16 @@ endif libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS) libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \ cipher.h cipher-proto.h gcrypt-module.h \ - misc.c global.c sexp.c hwfeatures.c \ + misc.c global.c sexp.c hwfeatures.c hwf-common.h \ stdmem.c stdmem.h secmem.c secmem.h \ mpi.h missing-string.c module.c fips.c \ hmac256.c hmac256.h \ ath.h ath.c +EXTRA_libgcrypt_la_SOURCES = hwf-x86.c +gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@ + + if HAVE_W32_SYSTEM RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ @@ -101,12 +105,14 @@ libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \ $(libgcrypt_version_script_cmd) -version-info \ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ libgcrypt_la_DEPENDENCIES = \ + $(gcrypt_hwf_modules) ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ ../compat/libcompat.la \ $(srcdir)/libgcrypt.vers $(gcrypt_deps) libgcrypt_la_LIBADD = $(gcrypt_res) \ + $(gcrypt_hwf_modules) \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ diff --git a/src/global.c b/src/global.c index 2428e21..b701dfc 100644 --- a/src/global.c +++ b/src/global.c @@ -299,6 +299,23 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp) "w32:" #endif "\n"); + fnc (fp, "cpu-arch:" +#if defined(HAVE_CPU_ARCH_X86) + "x86" +#elif defined(HAVE_CPU_ARCH_ALPHA) + "alpha" +#elif defined(HAVE_CPU_ARCH_SPARC) + "sparc" +#elif defined(HAVE_CPU_ARCH_MIPS) + "mips" +#elif defined(HAVE_CPU_ARCH_M68K) + "m68k" +#elif defined(HAVE_CPU_ARCH_PPC) + "ppc" +#elif defined(HAVE_CPU_ARCH_ARM) + "arm" +#endif + ":\n"); fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ()); fnc (fp, "threads:%s:\n", ath_get_model (NULL)); hwf = _gcry_get_hw_features (); diff --git a/src/hwf-common.h b/src/hwf-common.h new file mode 100644 index 0000000..974f47d --- /dev/null +++ b/src/hwf-common.h @@ -0,0 +1,26 @@ +/* hwf-common.h - Declarations for hwf-CPU.c modules + * Copyright (C) 2012 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 . + */ + +#ifndef HWF_COMMON_H +#define HWF_COMMON_H + +unsigned int _gcry_hwf_detect_x86 (void); + + +#endif /*HWF_COMMON_H*/ diff --git a/src/hwfeatures.c b/src/hwf-x86.c similarity index 81% copy from src/hwfeatures.c copy to src/hwf-x86.c index 62600aa..b50b4b0 100644 --- a/src/hwfeatures.c +++ b/src/hwf-x86.c @@ -1,5 +1,6 @@ -/* hwfeatures.c - Detect hardware features. - * Copyright (C) 2007, 2011 Free Software Foundation, Inc. +/* hwf-x86.c - Detect hardware features - x86 part + * Copyright (C) 2007, 2011, 2012 Free Software Foundation, Inc. + * Copyright (C) 2012 Jussi Kivilinna * * This file is part of Libgcrypt. * @@ -25,25 +26,18 @@ #include #include "g10lib.h" +#include "hwf-common.h" -/* A bit vector describing the hardware features currently - available. */ -static unsigned int hw_features; - - -/* Return a bit vector describing the available hardware features. - The HWF_ constants are used to test for them. */ -unsigned int -_gcry_get_hw_features (void) -{ - return hw_features; -} - +#if !defined (__i386__) && !defined (__x86_64__) +# error Module build for wrong CPU. +#endif +/* We use the next macro to decide whether we can test for certain + features. */ #undef HAS_X86_CPUID #if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__) -#define HAS_X86_CPUID 1 +# define HAS_X86_CPUID 1 static int is_cpuid_available(void) @@ -104,7 +98,7 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, #if defined (__x86_64__) && defined (__GNUC__) -#define HAS_X86_CPUID 1 +# define HAS_X86_CPUID 1 static int is_cpuid_available(void) @@ -138,14 +132,15 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, #ifdef HAS_X86_CPUID -static void +static unsigned int detect_x86_gnuc (void) { char vendor_id[12+1]; unsigned int features; + unsigned int result = 0; if (!is_cpuid_available()) - return; + return 0; get_cpuid(0, NULL, (unsigned int *)&vendor_id[0], @@ -171,21 +166,21 @@ detect_x86_gnuc (void) /* Test bits 2 and 3 to see whether the RNG exists and is enabled. */ if ((features & 0x0C) == 0x0C) - hw_features |= HWF_PADLOCK_RNG; + result |= HWF_PADLOCK_RNG; /* Test bits 6 and 7 to see whether the ACE exists and is enabled. */ if ((features & 0xC0) == 0xC0) - hw_features |= HWF_PADLOCK_AES; + result |= HWF_PADLOCK_AES; /* Test bits 10 and 11 to see whether the PHE exists and is enabled. */ if ((features & 0xC00) == 0xC00) - hw_features |= HWF_PADLOCK_SHA; + result |= HWF_PADLOCK_SHA; /* Test bits 12 and 13 to see whether the MONTMUL exists and is enabled. */ if ((features & 0x3000) == 0x3000) - hw_features |= HWF_PADLOCK_MMUL; + result |= HWF_PADLOCK_MMUL; } } #endif /*ENABLE_PADLOCK_SUPPORT*/ @@ -207,34 +202,25 @@ detect_x86_gnuc (void) #ifdef ENABLE_AESNI_SUPPORT /* Test bit 25 for AES-NI. */ if (features & 0x02000000) - hw_features |= HWF_INTEL_AESNI; + result |= HWF_INTEL_AESNI; #endif /*ENABLE_AESNI_SUPPORT*/ #ifdef ENABLE_DRNG_SUPPORT /* Test bit 30 for RDRAND. */ if (features & 0x40000000) - hw_features |= HWF_INTEL_RDRAND; + result |= HWF_INTEL_RDRAND; #endif /*ENABLE_DRNG_SUPPORT*/ + return result; } #endif /* HAS_X86_CPUID */ -/* Detect the available hardware features. This function is called - once right at startup and we assume that no other threads are - running. */ -void -_gcry_detect_hw_features (unsigned int disabled_features) +unsigned int +_gcry_hwf_detect_x86 (void) { - hw_features = 0; - - if (fips_mode ()) - return; /* Hardware support is not to be evaluated. */ - -#if HAS_X86_CPUID - { - detect_x86_gnuc (); - } -#endif /* HAS_X86_CPUID */ - - hw_features &= ~disabled_features; +#if defined (HAS_X86_CPUID) + return detect_x86_gnuc (); +#else + return 0; +#endif } diff --git a/src/hwfeatures.c b/src/hwfeatures.c index 62600aa..87d05d8 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -1,5 +1,6 @@ /* hwfeatures.c - Detect hardware features. * Copyright (C) 2007, 2011 Free Software Foundation, Inc. + * Copyright (C) 2012 g10 Code GmbH * * This file is part of Libgcrypt. * @@ -25,6 +26,8 @@ #include #include "g10lib.h" +#include "hwf-common.h" + /* A bit vector describing the hardware features currently available. */ @@ -40,185 +43,6 @@ _gcry_get_hw_features (void) } -#undef HAS_X86_CPUID - -#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__) -#define HAS_X86_CPUID 1 - -static int -is_cpuid_available(void) -{ - int has_cpuid = 0; - - /* Detect the CPUID feature by testing some undefined behaviour (16 - vs 32 bit pushf/popf). */ - asm volatile - ("pushf\n\t" /* Copy flags to EAX. */ - "popl %%eax\n\t" - "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */ - "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */ - "pushl %%eax\n\t" - "popf\n\t" - "pushf\n\t" /* Copy changed flags again to EAX. */ - "popl %%eax\n\t" - "pushl %%ecx\n\t" /* Restore flags from ECX. */ - "popf\n\t" - "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */ - "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */ - "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */ - ".Lno_cpuid%=:\n\t" - : "+r" (has_cpuid) - : - : "%eax", "%ecx", "cc" - ); - - return has_cpuid; -} - -static void -get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - unsigned int regs[4]; - - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "cpuid\n\t" - "movl %%ebx, %1\n\t" - "popl %%ebx\n\t" /* Restore GOT register. */ - : "=a" (regs[0]), "=r" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) - : "0" (in) - : "cc" - ); - - if (eax) - *eax = regs[0]; - if (ebx) - *ebx = regs[1]; - if (ecx) - *ecx = regs[2]; - if (edx) - *edx = regs[3]; -} -#endif /* i386 && GNUC */ - - -#if defined (__x86_64__) && defined (__GNUC__) -#define HAS_X86_CPUID 1 - -static int -is_cpuid_available(void) -{ - return 1; -} - -static void -get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - unsigned int regs[4]; - - asm volatile - ("cpuid\n\t" - : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) - : "0" (in) - : "cc" - ); - - if (eax) - *eax = regs[0]; - if (ebx) - *ebx = regs[1]; - if (ecx) - *ecx = regs[2]; - if (edx) - *edx = regs[3]; -} -#endif /* x86-64 && GNUC */ - - -#ifdef HAS_X86_CPUID -static void -detect_x86_gnuc (void) -{ - char vendor_id[12+1]; - unsigned int features; - - if (!is_cpuid_available()) - return; - - get_cpuid(0, NULL, - (unsigned int *)&vendor_id[0], - (unsigned int *)&vendor_id[8], - (unsigned int *)&vendor_id[4]); - vendor_id[12] = 0; - - if (0) - ; /* Just to make "else if" and ifdef macros look pretty. */ -#ifdef ENABLE_PADLOCK_SUPPORT - else if (!strcmp (vendor_id, "CentaurHauls")) - { - /* This is a VIA CPU. Check what PadLock features we have. */ - - /* Check for extended centaur (EAX). */ - get_cpuid(0xC0000000, &features, NULL, NULL, NULL); - - /* Has extended centaur features? */ - if (features > 0xC0000000) - { - /* Ask for the extended feature flags (EDX). */ - get_cpuid(0xC0000001, NULL, NULL, NULL, &features); - - /* Test bits 2 and 3 to see whether the RNG exists and is enabled. */ - if ((features & 0x0C) == 0x0C) - hw_features |= HWF_PADLOCK_RNG; - - /* Test bits 6 and 7 to see whether the ACE exists and is enabled. */ - if ((features & 0xC0) == 0xC0) - hw_features |= HWF_PADLOCK_AES; - - /* Test bits 10 and 11 to see whether the PHE exists and is - enabled. */ - if ((features & 0xC00) == 0xC00) - hw_features |= HWF_PADLOCK_SHA; - - /* Test bits 12 and 13 to see whether the MONTMUL exists and is - enabled. */ - if ((features & 0x3000) == 0x3000) - hw_features |= HWF_PADLOCK_MMUL; - } - } -#endif /*ENABLE_PADLOCK_SUPPORT*/ - else if (!strcmp (vendor_id, "GenuineIntel")) - { - /* This is an Intel CPU. */ - } - else if (!strcmp (vendor_id, "AuthenticAMD")) - { - /* This is an AMD CPU. */ - } - - /* Detect Intel features, that might also be supported by other - vendors. */ - - /* Get CPU info and Intel feature flags (ECX). */ - get_cpuid(1, NULL, NULL, &features, NULL); - -#ifdef ENABLE_AESNI_SUPPORT - /* Test bit 25 for AES-NI. */ - if (features & 0x02000000) - hw_features |= HWF_INTEL_AESNI; -#endif /*ENABLE_AESNI_SUPPORT*/ -#ifdef ENABLE_DRNG_SUPPORT - /* Test bit 30 for RDRAND. */ - if (features & 0x40000000) - hw_features |= HWF_INTEL_RDRAND; -#endif /*ENABLE_DRNG_SUPPORT*/ - -} -#endif /* HAS_X86_CPUID */ - - /* Detect the available hardware features. This function is called once right at startup and we assume that no other threads are running. */ @@ -230,11 +54,11 @@ _gcry_detect_hw_features (unsigned int disabled_features) if (fips_mode ()) return; /* Hardware support is not to be evaluated. */ -#if HAS_X86_CPUID +#if defined (HAVE_CPU_ARCH_X86) { - detect_x86_gnuc (); + hw_features = _gcry_hwf_detect_x86 (); } -#endif /* HAS_X86_CPUID */ +#endif /* HAVE_CPU_ARCH_X86 */ hw_features &= ~disabled_features; } commit d842eea55e22c05da3959a7a4422b5fcd7884f60 Author: Jussi Kivilinna Date: Thu Dec 20 15:46:57 2012 +0200 Clean up i386/x86-64 cpuid usage in hwfeatures.c * src/hwfeatures.c [__i386__ && __GNUC__] (detect_ia32_gnuc): Remove. [__x86_64__ && __GNUC__] (detect_x86_64_gnuc): Remove. [__i386__ && __GNUC__] (is_cpuid_available, get_cpuid) (HAS_X86_CPUID): New. [__x86_64__ && __GNUC__] (is_cpuid_available, get_cpuid) (HAS_X86_CPUID): New. [HAS_X86_CPUID] (detect_x86_gnuc): New. (_gcry_detect_hw_features) [__i386__ && GNUC]: Remove detect_ia32_gnuc call. (_gcry_detect_hw_features) [__x86_64__ && GNUC]: Remove detect_x86_64_gnuc call. (_gcry_detect_hw_features) [HAS_X86_CPUID]: Add detect_x86_gnuc call. -- For hwfeatures.c clean up, merge i386/x86-64 hardware detection and move i386/x86-64 spesific assembler to separate functions, is_cpuid_available() and get_cpuid(). Signed-off-by: Jussi Kivilinna diff --git a/src/hwfeatures.c b/src/hwfeatures.c index e89c825..62600aa 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -40,126 +40,15 @@ _gcry_get_hw_features (void) } -#if defined (__x86_64__) && defined (__GNUC__) -static void -detect_x86_64_gnuc (void) -{ - /* The code here is only useful for the PadLock engine thus we don't - build it if that support has been disabled. */ - char vendor_id[12+1]; - - asm volatile - ("xorl %%eax, %%eax\n\t" /* 0 -> EAX. */ - "cpuid\n\t" /* Get vendor ID. */ - "movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */ - "movl %%edx, 4(%0)\n\t" - "movl %%ecx, 8(%0)\n\t" - : - : "S" (&vendor_id[0]) - : "%eax", "%ebx", "%ecx", "%edx", "cc" - ); - vendor_id[12] = 0; - - if (0) - ; /* Just to make "else if" and ifdef macros look pretty. */ -#ifdef ENABLE_PADLOCK_SUPPORT - else if (!strcmp (vendor_id, "CentaurHauls")) - { - /* This is a VIA CPU. Check what PadLock features we have. */ - asm volatile - ("movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */ - "cpuid\n\t" /* feature flags. */ - "cmpl $0xC0000001, %%eax\n\t" - "jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */ - - "movl $0xC0000001, %%eax\n\t" /* Ask for the extended */ - "cpuid\n\t" /* feature flags. */ - - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */ - "cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */ - "jnz .Lno_rng%=\n\t" - "orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */ - - ".Lno_rng%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */ - "cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */ - "jnz .Lno_ace%=\n\t" - "orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */ - - ".Lno_ace%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */ - "cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */ - "jnz .Lno_phe%=\n\t" - "orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */ - - ".Lno_phe%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */ - "cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */ - "jnz .Lready%=\n\t" - "orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */ - - ".Lready%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ebx", "%ecx", "%edx", "cc" - ); - } -#endif /*ENABLE_PADLOCK_SUPPORT*/ - else if (!strcmp (vendor_id, "GenuineIntel")) - { - /* This is an Intel CPU. */ - } - else if (!strcmp (vendor_id, "AuthenticAMD")) - { - /* This is an AMD CPU. */ - } - - /* Detect Intel features, that might also be supported by other - vendors. */ -#ifdef ENABLE_AESNI_SUPPORT - asm volatile - ("movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ - "jz .Lno_aes%=\n\t" /* No AES support. */ - "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ - - ".Lno_aes%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ebx", "%ecx", "%edx", "cc" - ); -#endif /*#ifdef ENABLE_AESNI_SUPPORT*/ -#ifdef ENABLE_DRNG_SUPPORT - asm volatile - ("movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "testl $0x40000000, %%ecx\n\t" /* Test bit 30. */ - "jz .Lno_rdrand%=\n\t" /* No RDRAND support. */ - "orl $512, %0\n" /* Set our HWF_INTEL_RDRAND bit. */ - - ".Lno_rdrand%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ebx", "%ecx", "%edx", "cc" - ); -#endif /* #ifdef ENABLE_DRNG_SUPPORT */ - -} -#endif /* __x86_64__ && __GNUC__ */ +#undef HAS_X86_CPUID #if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__) -static void -detect_ia32_gnuc (void) +#define HAS_X86_CPUID 1 + +static int +is_cpuid_available(void) { - /* The code here is only useful for the PadLock engine thus we don't - build it if that support has been disabled. */ int has_cpuid = 0; - char vendor_id[12+1]; /* Detect the CPUID feature by testing some undefined behaviour (16 vs 32 bit pushf/popf). */ @@ -183,21 +72,85 @@ detect_ia32_gnuc (void) : "%eax", "%ecx", "cc" ); - if (!has_cpuid) - return; /* No way. */ + return has_cpuid; +} + +static void +get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + unsigned int regs[4]; asm volatile ("pushl %%ebx\n\t" /* Save GOT register. */ - "xorl %%eax, %%eax\n\t" /* 0 -> EAX. */ - "cpuid\n\t" /* Get vendor ID. */ - "movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */ - "movl %%edx, 4(%0)\n\t" - "movl %%ecx, 8(%0)\n\t" - "popl %%ebx\n" - : - : "S" (&vendor_id[0]) - : "%eax", "%ecx", "%edx", "cc" + "cpuid\n\t" + "movl %%ebx, %1\n\t" + "popl %%ebx\n\t" /* Restore GOT register. */ + : "=a" (regs[0]), "=r" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) + : "0" (in) + : "cc" ); + + if (eax) + *eax = regs[0]; + if (ebx) + *ebx = regs[1]; + if (ecx) + *ecx = regs[2]; + if (edx) + *edx = regs[3]; +} +#endif /* i386 && GNUC */ + + +#if defined (__x86_64__) && defined (__GNUC__) +#define HAS_X86_CPUID 1 + +static int +is_cpuid_available(void) +{ + return 1; +} + +static void +get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) +{ + unsigned int regs[4]; + + asm volatile + ("cpuid\n\t" + : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) + : "0" (in) + : "cc" + ); + + if (eax) + *eax = regs[0]; + if (ebx) + *ebx = regs[1]; + if (ecx) + *ecx = regs[2]; + if (edx) + *edx = regs[3]; +} +#endif /* x86-64 && GNUC */ + + +#ifdef HAS_X86_CPUID +static void +detect_x86_gnuc (void) +{ + char vendor_id[12+1]; + unsigned int features; + + if (!is_cpuid_available()) + return; + + get_cpuid(0, NULL, + (unsigned int *)&vendor_id[0], + (unsigned int *)&vendor_id[8], + (unsigned int *)&vendor_id[4]); vendor_id[12] = 0; if (0) @@ -206,51 +159,34 @@ detect_ia32_gnuc (void) else if (!strcmp (vendor_id, "CentaurHauls")) { /* This is a VIA CPU. Check what PadLock features we have. */ - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */ - "cpuid\n\t" /* feature flags. */ - "popl %%ebx\n\t" /* Restore GOT register. */ - "cmpl $0xC0000001, %%eax\n\t" - "jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */ - - "pushl %%ebx\n\t" /* Save GOT register. */ - "movl $0xC0000001, %%eax\n\t" /* Ask for the extended */ - "cpuid\n\t" /* feature flags. */ - "popl %%ebx\n\t" /* Restore GOT register. */ - - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */ - "cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */ - "jnz .Lno_rng%=\n\t" - "orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */ - - ".Lno_rng%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */ - "cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */ - "jnz .Lno_ace%=\n\t" - "orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */ - - ".Lno_ace%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */ - "cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */ - "jnz .Lno_phe%=\n\t" - "orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */ - - ".Lno_phe%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */ - "cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */ - "jnz .Lready%=\n\t" - "orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */ - - ".Lready%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ecx", "%edx", "cc" - ); + + /* Check for extended centaur (EAX). */ + get_cpuid(0xC0000000, &features, NULL, NULL, NULL); + + /* Has extended centaur features? */ + if (features > 0xC0000000) + { + /* Ask for the extended feature flags (EDX). */ + get_cpuid(0xC0000001, NULL, NULL, NULL, &features); + + /* Test bits 2 and 3 to see whether the RNG exists and is enabled. */ + if ((features & 0x0C) == 0x0C) + hw_features |= HWF_PADLOCK_RNG; + + /* Test bits 6 and 7 to see whether the ACE exists and is enabled. */ + if ((features & 0xC0) == 0xC0) + hw_features |= HWF_PADLOCK_AES; + + /* Test bits 10 and 11 to see whether the PHE exists and is + enabled. */ + if ((features & 0xC00) == 0xC00) + hw_features |= HWF_PADLOCK_SHA; + + /* Test bits 12 and 13 to see whether the MONTMUL exists and is + enabled. */ + if ((features & 0x3000) == 0x3000) + hw_features |= HWF_PADLOCK_MMUL; + } } #endif /*ENABLE_PADLOCK_SUPPORT*/ else if (!strcmp (vendor_id, "GenuineIntel")) @@ -260,46 +196,27 @@ detect_ia32_gnuc (void) else if (!strcmp (vendor_id, "AuthenticAMD")) { /* This is an AMD CPU. */ - } /* Detect Intel features, that might also be supported by other vendors. */ + + /* Get CPU info and Intel feature flags (ECX). */ + get_cpuid(1, NULL, NULL, &features, NULL); + #ifdef ENABLE_AESNI_SUPPORT - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "popl %%ebx\n\t" /* Restore GOT register. */ - "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ - "jz .Lno_aes%=\n\t" /* No AES support. */ - "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ - - ".Lno_aes%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ecx", "%edx", "cc" - ); + /* Test bit 25 for AES-NI. */ + if (features & 0x02000000) + hw_features |= HWF_INTEL_AESNI; #endif /*ENABLE_AESNI_SUPPORT*/ #ifdef ENABLE_DRNG_SUPPORT - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "popl %%ebx\n\t" /* Restore GOT register. */ - "testl $0x40000000, %%ecx\n\t" /* Test bit 30. */ - "jz .Lno_rdrand%=\n\t" /* No RDRAND support. */ - "orl $512, %0\n" /* Set our HWF_INTEL_RDRAND bit. */ - - ".Lno_rdrand%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ecx", "%edx", "cc" - ); + /* Test bit 30 for RDRAND. */ + if (features & 0x40000000) + hw_features |= HWF_INTEL_RDRAND; #endif /*ENABLE_DRNG_SUPPORT*/ } -#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ +#endif /* HAS_X86_CPUID */ /* Detect the available hardware features. This function is called @@ -313,24 +230,11 @@ _gcry_detect_hw_features (unsigned int disabled_features) if (fips_mode ()) return; /* Hardware support is not to be evaluated. */ -#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 -# ifdef __GNUC__ - { - detect_ia32_gnuc (); - } -# endif -#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8 -# ifdef __GNUC__ - { - } -# endif -#elif defined (__x86_64__) -# ifdef __GNUC__ +#if HAS_X86_CPUID { - detect_x86_64_gnuc (); + detect_x86_gnuc (); } -# endif -#endif +#endif /* HAS_X86_CPUID */ hw_features &= ~disabled_features; } ----------------------------------------------------------------------- Summary of changes: configure.ac | 41 +++++ mpi/config.links | 39 +++++ src/Makefile.am | 8 +- src/global.c | 17 ++ compat/libcompat.h => src/hwf-common.h | 23 +-- src/hwf-x86.c | 226 +++++++++++++++++++++++++ src/hwfeatures.c | 284 +------------------------------- 7 files changed, 342 insertions(+), 296 deletions(-) copy compat/libcompat.h => src/hwf-common.h (63%) create mode 100644 src/hwf-x86.c hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Dec 28 17:24:38 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 28 Dec 2012 17:24:38 +0100 Subject: [git] GnuPG - branch, key-storage-work, created. gnupg-2.1.0beta3-125-g79f08fb 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, key-storage-work has been created at 79f08fb0699f4a065e3a29bc7676a90534d7ba60 (commit) - Log ----------------------------------------------------------------- commit 79f08fb0699f4a065e3a29bc7676a90534d7ba60 Author: Werner Koch Date: Fri Dec 28 17:17:56 2012 +0100 gpg: Add signature cache support to the keybox. * g10/keydb.c (parse_keyblock_image): Add arg SIGSTATUS. (keydb_get_keyblock): Handle it. (build_keyblock_image): Add arg SIGSTATUS. (keydb_insert_keyblock): Handle it. * kbx/keybox-blob.c (pgp_create_sig_part): Add arg SIGSTATUS. (_keybox_create_openpgp_blob): Ditto. * kbx/kbxutil.c (import_openpgp): Adjust for above change. * kbx/keybox.h (KEYBOX_FLAG_SIG_INFO): New. * kbx/keybox-search.c (_keybox_get_flag_location): Handle new flag. (keybox_get_keyblock): Add arg R_SIGSTATUS. * kbx/keybox-update.c (keybox_insert_keyblock): Add arg SIGSTATUS. -- With this change a key listing using the keybox format is now double as fast as using a keyring. The memory use dropped as well. Measured with about 1500 keys. diff --git a/g10/keydb.c b/g10/keydb.c index acd7f8a..dff58cc 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -617,13 +617,14 @@ unlock_all (KEYDB_HANDLE hd) static gpg_error_t -parse_keyblock_image (iobuf_t iobuf, kbnode_t *r_keyblock) +parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock) { gpg_error_t err; PACKET *pkt; kbnode_t keyblock = NULL; - kbnode_t node; + kbnode_t node, *tail; int in_cert, save_mode; + u32 n_sigs; *r_keyblock = NULL; @@ -633,6 +634,8 @@ parse_keyblock_image (iobuf_t iobuf, kbnode_t *r_keyblock) init_packet (pkt); save_mode = set_packet_list_mode (0); in_cert = 0; + n_sigs = 0; + tail = NULL; while ((err = parse_packet (iobuf, pkt)) != -1) { if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET) @@ -665,25 +668,57 @@ parse_keyblock_image (iobuf_t iobuf, kbnode_t *r_keyblock) if (!in_cert && pkt->pkttype != PKT_PUBLIC_KEY) { - log_error ("error: first packet in a keybox blob is not a " - "public key packet\n"); + log_error ("parse_keyblock_image: first packet in a keybox blob " + "is not a public key packet\n"); err = gpg_error (GPG_ERR_INV_KEYRING); break; } if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY || pkt->pkttype == PKT_SECRET_KEY)) { - log_error ("error: multiple keyblocks in a keybox blob\n"); + log_error ("parse_keyblock_image: " + "multiple keyblocks in a keybox blob\n"); err = gpg_error (GPG_ERR_INV_KEYRING); break; } in_cert = 1; + if (pkt->pkttype == PKT_SIGNATURE && sigstatus) + { + PKT_signature *sig = pkt->pkt.signature; + + n_sigs++; + if (n_sigs > sigstatus[0]) + { + log_error ("parse_keyblock_image: " + "more signatures than found in the meta data\n"); + err = gpg_error (GPG_ERR_INV_KEYRING); + break; + + } + if (sigstatus[n_sigs]) + { + sig->flags.checked = 1; + if (sigstatus[n_sigs] == 1 ) + ; /* missing key */ + else if (sigstatus[n_sigs] == 2 ) + ; /* bad signature */ + else if (sigstatus[n_sigs] < 0x10000000) + ; /* bad flag */ + else + { + sig->flags.valid = 1; + /* Fixme: Shall we set the expired flag here? */ + } + } + } + node = new_kbnode (pkt); if (!keyblock) keyblock = node; else - add_kbnode (keyblock, node); + *tail = node; + tail = &node->next; pkt = xtrymalloc (sizeof *pkt); if (!pkt) { @@ -697,6 +732,12 @@ parse_keyblock_image (iobuf_t iobuf, kbnode_t *r_keyblock) if (err == -1 && keyblock) err = 0; /* Got the entire keyblock. */ + if (!err && sigstatus && n_sigs != sigstatus[0]) + { + log_error ("parse_keyblock_image: signature count does not match\n"); + err = gpg_error (GPG_ERR_INV_KEYRING); + } + if (err) release_kbnode (keyblock); else @@ -737,11 +778,14 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) case KEYDB_RESOURCE_TYPE_KEYBOX: { iobuf_t iobuf; + u32 *sigstatus; - err = keybox_get_keyblock (hd->active[hd->found].u.kb, &iobuf); + err = keybox_get_keyblock (hd->active[hd->found].u.kb, + &iobuf, &sigstatus); if (!err) { - err = parse_keyblock_image (iobuf, ret_kb); + err = parse_keyblock_image (iobuf, sigstatus, ret_kb); + xfree (sigstatus); iobuf_close (iobuf); } } @@ -753,18 +797,33 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) /* Build a keyblock image from KEYBLOCK. Returns 0 on success and - only then stores a new iobuf object at R_IOBUF. */ + only then stores a new iobuf object at R_IOBUF and a signature + status vecotor at R_SIGSTATUS. */ static gpg_error_t -build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf) +build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus) { gpg_error_t err; iobuf_t iobuf; kbnode_t kbctx, node; + u32 n_sigs; + u32 *sigstatus; *r_iobuf = NULL; + *r_sigstatus = NULL; + + /* Allocate a vector for the signature cache. This is an array of + u32 values with the first value giving the number of elements to + follow and each element descriping the cache status of the + signature. */ + for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));) + if (node->pkt->pkttype == PKT_SIGNATURE) + n_sigs++; + sigstatus = xtrycalloc (1+n_sigs, sizeof *sigstatus); + if (!sigstatus) + return gpg_error_from_syserror (); iobuf = iobuf_temp (); - for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) + for (kbctx = NULL, n_sigs = 0; (node = walk_kbnode (keyblock, &kbctx, 0));) { /* Make sure to use only packets valid on a keyblock. */ switch (node->pkt->pkttype) @@ -787,9 +846,34 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf) iobuf_close (iobuf); return err; } + + /* Build signature status vector. */ + if (node->pkt->pkttype == PKT_SIGNATURE) + { + PKT_signature *sig = node->pkt->pkt.signature; + + n_sigs++; + /* Fixme: Detect tye "missing key" status. */ + if (sig->flags.checked) + { + if (sig->flags.valid) + { + if (!sig->expiredate) + sigstatus[n_sigs] = 0xffffffff; + else if (sig->expiredate < 0x1000000) + sigstatus[n_sigs] = 0x10000000; + else + sigstatus[n_sigs] = sig->expiredate; + } + else + sigstatus[n_sigs] = 0x00000002; /* Bad signature. */ + } + } } + sigstatus[0] = n_sigs; *r_iobuf = iobuf; + *r_sigstatus = sigstatus; return 0; } @@ -876,13 +960,16 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) included in the keybox code. Eventually we can change this kludge to have the caller pass the image. */ iobuf_t iobuf; + u32 *sigstatus; - err = build_keyblock_image (kb, &iobuf); + err = build_keyblock_image (kb, &iobuf, &sigstatus); if (!err) { err = keybox_insert_keyblock (hd->active[idx].u.kb, iobuf_get_temp_buffer (iobuf), - iobuf_get_temp_length (iobuf)); + iobuf_get_temp_length (iobuf), + sigstatus); + xfree (sigstatus); iobuf_close (iobuf); } } diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index cd9d120..8b2b900 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -411,7 +411,8 @@ import_openpgp (const char *filename, int dryrun) dump_openpgp_key (&info, p); else { - err = _keybox_create_openpgp_blob (&blob, &info, p, nparsed, 0); + err = _keybox_create_openpgp_blob (&blob, &info, p, nparsed, + NULL, 0); if (err) { fflush (stdout); diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index c4a8982..855deaf 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -408,13 +408,13 @@ pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) static void -pgp_create_sig_part (KEYBOXBLOB blob) +pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus) { int n; for (n=0; n < blob->nsigs; n++) { - blob->sigs[n] = 0; /* FIXME: check the signature here */ + blob->sigs[n] = sigstatus? sigstatus[n+1] : 0; } } @@ -658,12 +658,14 @@ create_blob_finish (KEYBOXBLOB blob) return 0; } + gpg_error_t _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, keybox_openpgp_info_t info, const unsigned char *image, size_t imagelen, + u32 *sigstatus, int as_ephemeral) { gpg_error_t err; @@ -674,6 +676,11 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, if (!info->nuids || !info->nsigs) return gpg_error (GPG_ERR_BAD_PUBKEY); + /* If we have a signature status vector, check that the number of + elements matches the actual number of signatures. */ + if (sigstatus && sigstatus[0] != info->nsigs) + return gpg_error (GPG_ERR_INTERNAL); + blob = xtrycalloc (1, sizeof *blob); if (!blob) return gpg_error_from_syserror (); @@ -704,7 +711,7 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, if (err) goto leave; pgp_create_uid_part (blob, info); - pgp_create_sig_part (blob); + pgp_create_sig_part (blob, sigstatus); init_membuf (&blob->bufbuf, 1024); blob->buf = &blob->bufbuf; diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 8fdc54d..ad8e49d 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -160,6 +160,7 @@ gpg_error_t _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, keybox_openpgp_info_t info, const unsigned char *image, size_t imagelen, + u32 *sigstatus, int as_ephemeral); #ifdef KEYBOX_WITH_X509 int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 1e36be9..d683e14 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -102,7 +102,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, size_t nkeys, keyinfolen; size_t nuids, uidinfolen; size_t nserial; - size_t nsigs, siginfolen; + size_t nsigs, siginfolen, siginfooff; switch (what) { @@ -116,6 +116,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, case KEYBOX_FLAG_OWNERTRUST: case KEYBOX_FLAG_VALIDITY: case KEYBOX_FLAG_CREATED_AT: + case KEYBOX_FLAG_SIG_INFO: if (length < 20) return GPG_ERR_INV_OBJ; /* Key info. */ @@ -140,6 +141,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, if (pos+4 > length) return GPG_ERR_INV_OBJ ; /* Out of bounds. */ /* Signature info. */ + siginfooff = pos; nsigs = get16 (buffer + pos); pos += 2; siginfolen = get16 (buffer + pos); pos += 2; if (siginfolen < 4 ) @@ -158,6 +160,10 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, *flag_size = 4; *flag_off += 1+2+4+4+4; break; + case KEYBOX_FLAG_SIG_INFO: + *flag_size = siginfolen * nsigs; + *flag_off = siginfooff; + break; default: break; } @@ -961,15 +967,20 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) /* Return the last found keyblock. Returns 0 on success and stores a - new iobuf at R_IOBUF in that case. */ + new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS + in that case. */ gpg_error_t -keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf) +keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus) { - const unsigned char *buffer; + gpg_error_t err; + const unsigned char *buffer, *p; size_t length; size_t image_off, image_len; + size_t siginfo_off, siginfo_len; + u32 *sigstatus, n, n_sigs, sigilen; *r_iobuf = NULL; + *r_sigstatus = NULL; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -987,6 +998,21 @@ keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf) if (image_off+image_len > length) return gpg_error (GPG_ERR_TOO_SHORT); + err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO, + &siginfo_off, &siginfo_len); + if (err) + return err; + n_sigs = get16 (buffer + siginfo_off); + sigilen = get16 (buffer + siginfo_off + 2); + p = buffer + siginfo_off + 4; + sigstatus = xtrymalloc ((1+n_sigs) * sizeof *sigstatus); + if (!sigstatus) + return gpg_error_from_syserror (); + sigstatus[0] = n_sigs; + for (n=1; n <= n_sigs; n++, p += sigilen) + sigstatus[n] = get32 (p); + + *r_sigstatus = sigstatus; *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len); return 0; } diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index a4eedeb..6428bb2 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -371,9 +371,12 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, } -/* Insert the OpenPGP keyblock {IMAGE,IMAGELEN} into HD. */ +/* Insert the OpenPGP keyblock {IMAGE,IMAGELEN} into HD. SIGSTATUS is + a vector describing the status of the signatures; its first element + gives the number of following elements. */ gpg_error_t -keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) +keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen, + u32 *sigstatus) { gpg_error_t err; const char *fname; @@ -400,7 +403,7 @@ keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) return err; assert (nparsed <= imagelen); err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen, - hd->ephemeral); + sigstatus, hd->ephemeral); _keybox_destroy_openpgp_info (&info); if (!err) { diff --git a/kbx/keybox.h b/kbx/keybox.h index 15f05ed..03a9245 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -54,7 +54,8 @@ typedef enum KEYBOX_FLAG_UID, /* The user ID flags; requires an uid index. */ KEYBOX_FLAG_UID_VALIDITY,/* The validity of a specific uid, requires an uid index. */ - KEYBOX_FLAG_CREATED_AT /* The date the block was created. */ + KEYBOX_FLAG_CREATED_AT, /* The date the block was created. */ + KEYBOX_FLAG_SIG_INFO, /* The signature info block. */ } keybox_flag_t; /* Flag values used with KEYBOX_FLAG_BLOB. */ @@ -80,7 +81,8 @@ int keybox_lock (KEYBOX_HANDLE hd, int yes); int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ -gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf); +gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, + iobuf_t *r_iobuf, u32 **sigstatus); #ifdef KEYBOX_WITH_X509 int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); #endif /*KEYBOX_WITH_X509*/ @@ -92,7 +94,8 @@ int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc); /*-- keybox-update.c --*/ gpg_error_t keybox_insert_keyblock (KEYBOX_HANDLE hd, - const void *image, size_t imagelen); + const void *image, size_t imagelen, + u32 *sigstatus); gpg_error_t keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen); commit 564d10ea5cd29685a00a4096d69ae2476b60506f Author: Werner Koch Date: Fri Dec 28 17:07:37 2012 +0100 kbxutil: Improve format of the Sig-Expire lines. * kbx/keybox-dump.c (_keybox_dump_blob): Print the expirate timestamp. diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index ab31085..b603814 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -324,9 +324,9 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) else if (sflags < 0x10000000) fprintf (fp, "[bad flag %0lx]", sflags); else if (sflags == 0xffffffff) - fputs ("0", fp ); + fputs ("[good - does not expire]", fp ); else - fputs ("a time"/*strtimestamp( sflags )*/, fp ); + fprintf (fp, "[good - expires at %lu]", sflags); putc ('\n', fp ); } if (in_range) commit a9863834244fc2a58d8950977243702d12e420a1 Author: Werner Koch Date: Fri Dec 28 14:03:16 2012 +0100 gpg: First working support for keyboxes. * g10/getkey.c (get_pubkey_fast): Improve the assertion. * kbx/keybox.h: Include iobuf.h. * kbx/keybox-blob.c (keyboxblob_uid): Add field OFF. (KEYBOX_WITH_OPENPGP): Remove use of this macro. (pgp_create_key_part_single): New. (pgp_temp_store_kid): Change to use the keybox-openpgp parser. (pgp_create_key_part): Ditto. (pgp_create_uid_part): Ditto. (pgp_create_sig_part): Ditto. (pgp_create_blob_keyblock): Ditto. (_keybox_create_openpgp_blob): Ditto. * kbx/keybox-search.c (keybox_get_keyblock): New. * kbx/keybox-update.c (keybox_insert_keyblock): New. * g10/keydb.c (parse_keyblock_image): (keydb_get_keyblock): Support keybox. (build_keyblock_image): New. (keydb_insert_keyblock): Support keybox. * kbx/kbxutil.c (import_openpgp, main): Add option --dry-run and print a kbx file to stdout. * kbx/keybox-file.c (_keybox_read_blob2): Allow keyblocks up to 10^6 bytes. -- Import and key listing does now work with the keybox format. It is still quite slow and signature caching is completely missing. Increasing the maximum allowed length for a keyblock was required due to a 700k keyblock which inhibited kbxutil to list the file. kbxutil's option name --import-openpgp is not quite appropriate because it only creates KBX blobs from OpenPGP data. diff --git a/g10/getkey.c b/g10/getkey.c index 9294273..002a2be 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -444,8 +444,9 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid) return G10ERR_NO_PUBKEY; } - assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY); + assert (keyblock && keyblock->pkt + && (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY)); keyid_from_pk (keyblock->pkt->pkt.public_key, pkid); if (keyid[0] == pkid[0] && keyid[1] == pkid[1]) diff --git a/g10/keydb.c b/g10/keydb.c index ab727b6..acd7f8a 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -616,6 +616,97 @@ unlock_all (KEYDB_HANDLE hd) } +static gpg_error_t +parse_keyblock_image (iobuf_t iobuf, kbnode_t *r_keyblock) +{ + gpg_error_t err; + PACKET *pkt; + kbnode_t keyblock = NULL; + kbnode_t node; + int in_cert, save_mode; + + *r_keyblock = NULL; + + pkt = xtrymalloc (sizeof *pkt); + if (!pkt) + return gpg_error_from_syserror (); + init_packet (pkt); + save_mode = set_packet_list_mode (0); + in_cert = 0; + while ((err = parse_packet (iobuf, pkt)) != -1) + { + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET) + { + free_packet (pkt); + init_packet (pkt); + continue; + } + if (err) + { + log_error ("parse_keyblock_image: read error: %s\n", + gpg_strerror (err)); + err = gpg_error (GPG_ERR_INV_KEYRING); + break; + } + if (pkt->pkttype == PKT_COMPRESSED) + { + log_error ("skipped compressed packet in keybox blob\n"); + free_packet(pkt); + init_packet(pkt); + continue; + } + if (pkt->pkttype == PKT_RING_TRUST) + { + log_info ("skipped ring trust packet in keybox blob\n"); + free_packet(pkt); + init_packet(pkt); + continue; + } + + if (!in_cert && pkt->pkttype != PKT_PUBLIC_KEY) + { + log_error ("error: first packet in a keybox blob is not a " + "public key packet\n"); + err = gpg_error (GPG_ERR_INV_KEYRING); + break; + } + if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY + || pkt->pkttype == PKT_SECRET_KEY)) + { + log_error ("error: multiple keyblocks in a keybox blob\n"); + err = gpg_error (GPG_ERR_INV_KEYRING); + break; + } + in_cert = 1; + + node = new_kbnode (pkt); + if (!keyblock) + keyblock = node; + else + add_kbnode (keyblock, node); + pkt = xtrymalloc (sizeof *pkt); + if (!pkt) + { + err = gpg_error_from_syserror (); + break; + } + init_packet (pkt); + } + set_packet_list_mode (save_mode); + + if (err == -1 && keyblock) + err = 0; /* Got the entire keyblock. */ + + if (err) + release_kbnode (keyblock); + else + *r_keyblock = keyblock; + free_packet (pkt); + xfree (pkt); + return err; +} + + /* * Return the last found keyring. Caller must free it. * The returned keyblock has the kbode flag bit 0 set for the node with @@ -627,6 +718,8 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) { gpg_error_t err = 0; + *ret_kb = NULL; + if (!hd) return gpg_error (GPG_ERR_INV_ARG); @@ -641,16 +734,66 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) case KEYDB_RESOURCE_TYPE_KEYRING: err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); break; - /* case KEYDB_RESOURCE_TYPE_KEYBOX: */ - /* err = keybox_get_keyblock (hd->active[hd->found].u.kb, ret_kb); */ - /* if (!err) */ - /* err = parse_keyblock (image, imagelen) */ - /* break; */ + case KEYDB_RESOURCE_TYPE_KEYBOX: + { + iobuf_t iobuf; + + err = keybox_get_keyblock (hd->active[hd->found].u.kb, &iobuf); + if (!err) + { + err = parse_keyblock_image (iobuf, ret_kb); + iobuf_close (iobuf); + } + } + break; } return err; } + +/* Build a keyblock image from KEYBLOCK. Returns 0 on success and + only then stores a new iobuf object at R_IOBUF. */ +static gpg_error_t +build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf) +{ + gpg_error_t err; + iobuf_t iobuf; + kbnode_t kbctx, node; + + *r_iobuf = NULL; + + iobuf = iobuf_temp (); + for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) + { + /* Make sure to use only packets valid on a keyblock. */ + switch (node->pkt->pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_SIGNATURE: + case PKT_USER_ID: + case PKT_ATTRIBUTE: + /* Note that we don't want the ring trust packets. They are + not useful. */ + break; + default: + continue; + } + + err = build_packet (iobuf, node->pkt); + if (err) + { + iobuf_close (iobuf); + return err; + } + } + + *r_iobuf = iobuf; + return 0; +} + + /* * Update the current keyblock with the keyblock KB */ @@ -699,7 +842,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb) gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) { - int rc; + gpg_error_t err; int idx; if (!hd) @@ -715,27 +858,39 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) else return gpg_error (GPG_ERR_GENERAL); - rc = lock_all (hd); - if (rc) - return rc; + err = lock_all (hd); + if (err) + return err; switch (hd->active[idx].type) { case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); /* oops */ + err = gpg_error (GPG_ERR_GENERAL); /* oops */ break; case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb); + err = keyring_insert_keyblock (hd->active[idx].u.kr, kb); + break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + { /* We need to turn our kbnode_t list of packets into a proper + keyblock first. This is required by the OpenPGP key parser + included in the keybox code. Eventually we can change this + kludge to have the caller pass the image. */ + iobuf_t iobuf; + + err = build_keyblock_image (kb, &iobuf); + if (!err) + { + err = keybox_insert_keyblock (hd->active[idx].u.kb, + iobuf_get_temp_buffer (iobuf), + iobuf_get_temp_length (iobuf)); + iobuf_close (iobuf); + } + } break; - /* case KEYDB_RESOURCE_TYPE_KEYBOX: */ - /* rc = build_keyblock (kb, &image, &imagelen); */ - /* if (!rc) */ - /* rc = keybox_insert_keyblock (hd->active[idx].u.kb, image, imagelen); */ - /* break; */ } unlock_all (hd); - return rc; + return err; } diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index fee5570..cd9d120 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -371,13 +371,14 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) static void -import_openpgp (const char *filename) +import_openpgp (const char *filename, int dryrun) { gpg_error_t err; char *buffer; size_t buflen, nparsed; unsigned char *p; struct _keybox_openpgp_info info; + KEYBOXBLOB blob; buffer = read_file (filename, &buflen); if (!buffer) @@ -406,7 +407,30 @@ import_openpgp (const char *filename) } else { - dump_openpgp_key (&info, p); + if (dryrun) + dump_openpgp_key (&info, p); + else + { + err = _keybox_create_openpgp_blob (&blob, &info, p, nparsed, 0); + if (err) + { + fflush (stdout); + log_error ("%s: failed to create OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + else + { + err = _keybox_write_blob (blob, stdout); + _keybox_release_blob (blob); + if (err) + { + fflush (stdout); + log_error ("%s: failed to write OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + } + } + _keybox_destroy_openpgp_info (&info); } p += nparsed; @@ -424,6 +448,7 @@ main( int argc, char **argv ) ARGPARSE_ARGS pargs; enum cmd_and_opt_values cmd = 0; unsigned long from = 0, to = ULONG_MAX; + int dry_run = 0; set_strusage( my_strusage ); gcry_control (GCRYCTL_DISABLE_SECMEM); @@ -481,6 +506,8 @@ main( int argc, char **argv ) case oFrom: from = pargs.r.ret_ulong; break; case oTo: to = pargs.r.ret_ulong; break; + case oDryRun: dry_run = 1; break; + default: pargs.err = 2; break; @@ -537,11 +564,11 @@ main( int argc, char **argv ) else if (cmd == aImportOpenPGP) { if (!argc) - import_openpgp ("-"); + import_openpgp ("-", dry_run); else { for (; argc; argc--, argv++) - import_openpgp (*argv); + import_openpgp (*argv, dry_run); } } #if 0 diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 998a770..c4a8982 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -47,7 +47,7 @@ X.509 specific are noted like [X.509: xxx] byte Blob type (2) [X509: 3] byte version number of this blob type (1) u16 Blob flags - bit 0 = contains secret key material + bit 0 = contains secret key material (not used) bit 1 = ephemeral blob (e.g. used while quering external resources) u32 offset to the OpenPGP keyblock or X509 DER encoded certificate @@ -119,9 +119,6 @@ X.509 specific are noted like [X.509: xxx] #include "keybox-defs.h" #include -#ifdef KEYBOX_WITH_OPENPGP -/* include stuff to parse the packets */ -#endif #ifdef KEYBOX_WITH_X509 #include #endif @@ -156,6 +153,7 @@ struct keyboxblob_key { u16 flags; }; struct keyboxblob_uid { + u32 off; ulong off_addr; char *name; /* used only with x509 */ u32 len; @@ -311,33 +309,24 @@ add_fixup (KEYBOXBLOB blob, u32 off, u32 val) -#ifdef KEYBOX_WITH_OPENPGP /* OpenPGP specific stuff */ -/* - We must store the keyid at some place because we can't calculate the - offset yet. This is only used for v3 keyIDs. Function returns an - index value for later fixup or -1 for out of core. The value must be - a non-zero value */ +/* We must store the keyid at some place because we can't calculate + the offset yet. This is only used for v3 keyIDs. Function returns + an index value for later fixup or -1 for out of core. The value + must be a non-zero value. */ static int -pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) +pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo) { struct keyid_list *k, *r; k = xtrymalloc (sizeof *k); if (!k) return -1; - k->kid[0] = pk->keyid[0] >> 24 ; - k->kid[1] = pk->keyid[0] >> 16 ; - k->kid[2] = pk->keyid[0] >> 8 ; - k->kid[3] = pk->keyid[0] ; - k->kid[4] = pk->keyid[0] >> 24 ; - k->kid[5] = pk->keyid[0] >> 16 ; - k->kid[6] = pk->keyid[0] >> 8 ; - k->kid[7] = pk->keyid[0] ; + memcpy (k->kid, kinfo->keyid, 8); k->seqno = 0; k->next = blob->temp_kids; blob->temp_kids = k; @@ -347,124 +336,108 @@ pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) return k->seqno; } -static int -pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock) + +/* Helper for pgp_create_key_part. */ +static gpg_error_t +pgp_create_key_part_single (KEYBOXBLOB blob, int n, + struct _keybox_openpgp_key_info *kinfo) { - KBNODE node; size_t fprlen; - int n; + int off; - for (n=0, node = keyblock; node; node = node->next) + fprlen = kinfo->fprlen; + if (fprlen > 20) + fprlen = 20; + memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen); + if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */ { - if ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - char tmp[20]; - - fingerprint_from_pk (pk, tmp , &fprlen); - memcpy (blob->keys[n].fpr, tmp, 20); - if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/ - { - assert (fprlen == 16); - memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16); - memset (blob->keys[n].fpr, 0, 4); - blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk); - } - else - { - blob->keys[n].off_kid = 0; /* will be fixed up later */ - } - blob->keys[n].flags = 0; - n++; - } - else if ( node->pkt->pkttype == PKT_SECRET_KEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - { - never_reached (); /* actually not yet implemented */ - } + memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen); + memset (blob->keys[n].fpr, 0, 20 - fprlen); + off = pgp_temp_store_kid (blob, kinfo); + if (off == -1) + return gpg_error_from_syserror (); + blob->keys[n].off_kid = off; } + else + blob->keys[n].off_kid = 0; /* Will be fixed up later */ + blob->keys[n].flags = 0; + return 0; +} + + +static gpg_error_t +pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) +{ + gpg_error_t err; + int n = 0; + struct _keybox_openpgp_key_info *kinfo; + + err = pgp_create_key_part_single (blob, n++, &info->primary); + if (err) + return err; + if (info->nsubkeys) + for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next) + if ((err=pgp_create_key_part_single (blob, n++, kinfo))) + return err; + assert (n == blob->nkeys); return 0; } -static int -pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock) + +static void +pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) { - KBNODE node; - int n; + int n = 0; + struct _keybox_openpgp_uid_info *u; - for (n=0, node = keyblock; node; node = node->next) + if (info->nuids) { - if (node->pkt->pkttype == PKT_USER_ID) + for (u = &info->uids; u; u = u->next) { - PKT_user_id *u = node->pkt->pkt.user_id; - + blob->uids[n].off = u->off; blob->uids[n].len = u->len; blob->uids[n].flags = 0; blob->uids[n].validity = 0; n++; - } + } } + assert (n == blob->nuids); - return 0; } -static int -pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock) + +static void +pgp_create_sig_part (KEYBOXBLOB blob) { - KBNODE node; int n; - for (n=0, node = keyblock; node; node = node->next) + for (n=0; n < blob->nsigs; n++) { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - PKT_signature *sig = node->pkt->pkt.signature; - - blob->sigs[n] = 0; /* FIXME: check the signature here */ - n++; - } + blob->sigs[n] = 0; /* FIXME: check the signature here */ } - assert( n == blob->nsigs ); - return 0; } + static int -pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock) +pgp_create_blob_keyblock (KEYBOXBLOB blob, + const unsigned char *image, size_t imagelen) { struct membuf *a = blob->buf; - KBNODE node; - int rc; int n; u32 kbstart = a->len; - add_fixup (blob, kbstart); + add_fixup (blob, 8, kbstart); - for (n = 0, node = keyblock; node; node = node->next) - { - rc = build_packet ( a, node->pkt ); - if ( rc ) { - gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n", - node->pkt->pkttype, gpg_errstr(rc) ); - return GPGERR_WRITE_FILE; - } - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *u = node->pkt->pkt.user_id; - /* build_packet has set the offset of the name into u ; - * now we can do the fixup */ - add_fixup (blob, blob->uids[n].off_addr, u->stored_at); - n++; - } - } - assert (n == blob->nuids); + for (n = 0; n < blob->nuids; n++) + add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off); + + put_membuf (a, image, imagelen); - add_fixup (blob, a->len - kbstart); + add_fixup (blob, 12, a->len - kbstart); return 0; } -#endif /*KEYBOX_WITH_OPENPGP*/ #ifdef KEYBOX_WITH_X509 @@ -686,87 +659,78 @@ create_blob_finish (KEYBOXBLOB blob) } -#ifdef KEYBOX_WITH_OPENPGP - -int -_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) +gpg_error_t +_keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, + keybox_openpgp_info_t info, + const unsigned char *image, + size_t imagelen, + int as_ephemeral) { - int rc = 0; - KBNODE node; + gpg_error_t err; KEYBOXBLOB blob; *r_blob = NULL; + + if (!info->nuids || !info->nsigs) + return gpg_error (GPG_ERR_BAD_PUBKEY); + blob = xtrycalloc (1, sizeof *blob); if (!blob) return gpg_error_from_syserror (); - /* fixme: Do some sanity checks on the keyblock */ - - /* count userids and keys so that we can allocate the arrays */ - for (node = keyblock; node; node = node->next) + blob->nkeys = 1 + info->nsubkeys; + blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); + if (!blob->keys) { - switch (node->pkt->pkttype) - { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: blob->nkeys++; break; - case PKT_USER_ID: blob->nuids++; break; - case PKT_SIGNATURE: blob->nsigs++; break; - default: break; - } + err = gpg_error_from_syserror (); + goto leave; } - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); + blob->nuids = info->nuids; blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); + if (!blob->uids) + { + err = gpg_error_from_syserror (); + goto leave; + } + blob->nsigs = info->nsigs; blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) + if (!blob->sigs) { - rc = gpg_error (GPG_ERR_ENOMEM); + err = gpg_error_from_syserror (); goto leave; } - rc = pgp_create_key_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_uid_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_sig_part ( blob, keyblock ); - if (rc) + err = pgp_create_key_part (blob, info); + if (err) goto leave; + pgp_create_uid_part (blob, info); + pgp_create_sig_part (blob); init_membuf (&blob->bufbuf, 1024); blob->buf = &blob->bufbuf; - rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral); - if (rc) + err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral); + if (err) goto leave; - rc = pgp_create_blob_keyblock (blob, keyblock); - if (rc) + err = pgp_create_blob_keyblock (blob, image, imagelen); + if (err) goto leave; - rc = create_blob_trailer (blob); - if (rc) + err = create_blob_trailer (blob); + if (err) goto leave; - rc = create_blob_finish ( blob ); - if (rc) + err = create_blob_finish (blob); + if (err) goto leave; - leave: release_kid_list (blob->temp_kids); blob->temp_kids = NULL; - if (rc) - { - keybox_release_blob (blob); - *r_blob = NULL; - } + if (err) + _keybox_release_blob (blob); else - { - *r_blob = blob; - } - return rc; + *r_blob = blob; + return err; } -#endif /*KEYBOX_WITH_OPENPGP*/ + #ifdef KEYBOX_WITH_X509 diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index c588016..8fdc54d 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -156,9 +156,11 @@ void _keybox_close_file (KEYBOX_HANDLE hd); /*-- keybox-blob.c --*/ -#ifdef KEYBOX_WITH_OPENPGP - /* fixme */ -#endif /*KEYBOX_WITH_OPENPGP*/ +gpg_error_t _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, + keybox_openpgp_info_t info, + const unsigned char *image, + size_t imagelen, + int as_ephemeral); #ifdef KEYBOX_WITH_X509 int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, unsigned char *sha1_digest, int as_ephemeral); diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index ecfdfbe..027bcf8 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -74,7 +74,7 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted) } imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4; - if (imagelen > 500000) /* Sanity check. */ + if (imagelen > 1000000) /* Sanity check. */ return gpg_error (GPG_ERR_TOO_LARGE); if (imagelen < 5) diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index ef5cd95..1e36be9 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -1,5 +1,5 @@ /* keybox-search.c - Search operations - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -958,6 +958,40 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) Functions to return a certificate or a keyblock. To be used after a successful search operation. */ + + +/* Return the last found keyblock. Returns 0 on success and stores a + new iobuf at R_IOBUF in that case. */ +gpg_error_t +keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf) +{ + const unsigned char *buffer; + size_t length; + size_t image_off, image_len; + + *r_iobuf = NULL; + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + + if (blob_get_type (hd->found.blob) != BLOBTYPE_PGP) + return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); + + buffer = _keybox_get_blob_image (hd->found.blob, &length); + if (length < 40) + return gpg_error (GPG_ERR_TOO_SHORT); + image_off = get32 (buffer+8); + image_len = get32 (buffer+12); + if (image_off+image_len > length) + return gpg_error (GPG_ERR_TOO_SHORT); + + *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len); + return 0; +} + + #ifdef KEYBOX_WITH_X509 /* Return the last found cert. Caller must free it. diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index 0d052c9..a4eedeb 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -1,5 +1,5 @@ /* keybox-update.c - keybox update operations - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -24,6 +24,7 @@ #include #include #include +#include #include "keybox-defs.h" #include "../common/sysutils.h" @@ -370,6 +371,62 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, } +/* Insert the OpenPGP keyblock {IMAGE,IMAGELEN} into HD. */ +gpg_error_t +keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) +{ + gpg_error_t err; + const char *fname; + KEYBOXBLOB blob; + size_t nparsed; + struct _keybox_openpgp_info info; + + if (!hd) + return gpg_error (GPG_ERR_INV_HANDLE); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + + /* Close this one otherwise we will mess up the position for a next + search. Fixme: it would be better to adjust the position after + the write operation. */ + _keybox_close_file (hd); + + err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info); + if (err) + return err; + assert (nparsed <= imagelen); + err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen, + hd->ephemeral); + _keybox_destroy_openpgp_info (&info); + if (!err) + { + err = blob_filecopy (1, fname, blob, hd->secret, 0); + _keybox_release_blob (blob); + /* if (!rc && !hd->secret && kb_offtbl) */ + /* { */ + /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ + /* } */ + } + return err; +} + + +/* Update the current key at HD with the given OpenPGP keyblock in + {IMAGE,IMAGELEN}. */ +gpg_error_t +keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) +{ + (void)hd; + (void)image; + (void)imagelen; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} + + #ifdef KEYBOX_WITH_X509 int diff --git a/kbx/keybox.h b/kbx/keybox.h index 52c1638..15f05ed 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -1,5 +1,5 @@ /* keybox.h - Keybox operations - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -26,6 +26,7 @@ extern "C" { #endif #endif +#include "../common/iobuf.h" #include "keybox-search-desc.h" #define KEYBOX_WITH_OPENPGP 1 @@ -79,6 +80,7 @@ int keybox_lock (KEYBOX_HANDLE hd, int yes); int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ +gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf); #ifdef KEYBOX_WITH_X509 int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); #endif /*KEYBOX_WITH_X509*/ @@ -89,6 +91,11 @@ int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc); /*-- keybox-update.c --*/ +gpg_error_t keybox_insert_keyblock (KEYBOX_HANDLE hd, + const void *image, size_t imagelen); +gpg_error_t keybox_update_keyblock (KEYBOX_HANDLE hd, + const void *image, size_t imagelen); + #ifdef KEYBOX_WITH_X509 int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, unsigned char *sha1_digest); commit f7495f1004071a0ceac394007bb37f88d7a3467f Author: Werner Koch Date: Fri Dec 28 13:45:41 2012 +0100 kbxutil: Print algo number and fold similar lines. * kbx/keybox-defs.h (_keybox_openpgp_key_info): Add field ALGO. * kbx/keybox-openpgp.c (parse_key): Store algo. * kbx/kbxutil.c (dump_openpgp_key): Print algo number. * kbx/keybox-dump.c (_keybox_dump_blob): Print identical Sig-Expire value lines with a range of indices. diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 62e3dbe..fee5570 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -332,7 +332,8 @@ dump_fpr (const unsigned char *buffer, size_t len) static void dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) { - printf ("pub %02X%02X%02X%02X", + printf ("pub %2d %02X%02X%02X%02X", + info->primary.algo, info->primary.keyid[4], info->primary.keyid[5], info->primary.keyid[6], info->primary.keyid[7] ); dump_fpr (info->primary.fpr, info->primary.fprlen); @@ -344,7 +345,8 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) k = &info->subkeys; do { - printf ("sub %02X%02X%02X%02X", + printf ("sub %2d %02X%02X%02X%02X", + k->algo, k->keyid[4], k->keyid[5], k->keyid[6], k->keyid[7] ); dump_fpr (k->fpr, k->fprlen); diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 890e4dd..c588016 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -111,6 +111,7 @@ struct keybox_handle { struct _keybox_openpgp_key_info { struct _keybox_openpgp_key_info *next; + int algo; unsigned char keyid[8]; int fprlen; /* Either 16 or 20 */ unsigned char fpr[20]; diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index c5f518e..ab31085 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -291,27 +291,50 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen ); /* fixme: check bounds */ p += 4; - for (n=0; n < nsigs; n++, p += siginfolen) - { - ulong sflags; - - sflags = get32 (p); - fprintf (fp, "Sig-Expire[%lu]: ", n ); - if (!sflags) - fputs ("[not checked]", fp); - else if (sflags == 1 ) - fputs ("[missing key]", fp); - else if (sflags == 2 ) - fputs ("[bad signature]", fp); - else if (sflags < 0x10000000) - fprintf (fp, "[bad flag %0lx]", sflags); - else if (sflags == 0xffffffff) - fputs ("0", fp ); - else - fputs ("a time"/*strtimestamp( sflags )*/, fp ); - putc ('\n', fp ); - } - + { + int in_range = 0; + ulong first = 0; + + for (n=0; n < nsigs; n++, p += siginfolen) + { + ulong sflags; + + sflags = get32 (p); + if (!in_range && !sflags) + { + in_range = 1; + first = n; + continue; + } + if (in_range && !sflags) + continue; + if (in_range) + { + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); + in_range = 0; + } + + fprintf (fp, "Sig-Expire[%lu]: ", n ); + if (!sflags) + fputs ("[not checked]", fp); + else if (sflags == 1 ) + fputs ("[missing key]", fp); + else if (sflags == 2 ) + fputs ("[bad signature]", fp); + else if (sflags < 0x10000000) + fprintf (fp, "[bad flag %0lx]", sflags); + else if (sflags == 0xffffffff) + fputs ("0", fp ); + else + fputs ("a time"/*strtimestamp( sflags )*/, fp ); + putc ('\n', fp ); + } + if (in_range) + { + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); + in_range = 0; + } + } fprintf (fp, "Ownertrust: %d\n", p[0] ); fprintf (fp, "All-Validity: %d\n", p[1] ); p += 4; diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 37e2771..82bc934 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -223,6 +223,8 @@ parse_key (const unsigned char *data, size_t datalen, return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); } + ki->algo = algorithm; + for (i=0; i < npkey; i++ ) { unsigned int nbits, nbytes; commit 91e61d52539b1808e209c43e51465c76cebb06f9 Author: Werner Koch Date: Thu Dec 27 15:04:29 2012 +0100 gpg: First patches to support a keybox storage backend. * kbx/keybox-defs.h (_keybox_write_header_blob): Move prototype to .. * kbx/keybox.h: here. * kbx/keybox-init.c (keybox_lock): Add dummy function * g10/keydb.c: Include keybox.h. (KeydbResourceType): Add KEYDB_RESOURCE_TYPE_KEYBOX. (struct resource_item): Add field kb. (maybe_create_keyring_or_box): Add error descriptions to diagnostics. Add arg IS_BOX. Write a header for a new keybox file. (keydb_add_resource): No more need for the force flag. Rename the local variable "force" to "create". Add URL scheme "gnupg-kbx". Add magic test to detect a keybox file. Add basic support for keybox. (keydb_new, keydb_get_resource_name, keydb_delete_keyblock) (keydb_locate_writable, keydb_search_reset, keydb_search2): Add support for keybox. (lock_all, unlock_all): Ditto. * g10/Makefile.am (needed_libs): Add libkeybox.a. (gpg2_LDADD, gpgv2_LDADD): Add KSBA_LIBS as a workaround. * g10/keydb.h (KEYDB_RESOURCE_FLAG_PRIMARY) KEYDB_RESOURCE_FLAG_DEFAULT, KEYDB_RESOURCE_FLAG_READONLY): New. * g10/gpg.c, g10/gpgv.c (main): Use new constants. -- I did most of these changes back in 2011 and only cleaned them up now. More to follow soon. diff --git a/g10/Makefile.am b/g10/Makefile.am index e9f69b3..899677c 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -27,7 +27,7 @@ include $(top_srcdir)/am/cmacros.am AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) -needed_libs = $(libcommon) ../gl/libgnu.a +needed_libs = ../kbx/libkeybox.a $(libcommon) ../gl/libgnu.a bin_PROGRAMS = gpg2 if !HAVE_W32CE_SYSTEM @@ -120,13 +120,18 @@ gpgv2_SOURCES = gpgv.c \ # ks-db.h \ # $(common_source) +# FIXME: Libkeybox.a links to libksba thus we need to add libksba +# here, even that it is not used by gpg. A proper solution would +# either to split up libkeybox.a or to use a separate keybox daemon. LDADD = $(needed_libs) ../common/libgpgrl.a \ $(ZLIBS) $(DNSLIBS) $(LIBREADLINE) \ $(LIBINTL) $(CAPLIBS) $(NETLIBS) -gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ +gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \ + $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ $(LIBICONV) $(extra_sys_libs) gpg2_LDFLAGS = $(extra_bin_ldflags) -gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ +gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \ + $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ $(LIBICONV) $(extra_sys_libs) gpgv2_LDFLAGS = $(extra_bin_ldflags) diff --git a/g10/gpg.c b/g10/gpg.c index b614a94..5773d5e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2249,8 +2249,8 @@ main (int argc, char **argv) case oAnswerNo: opt.answer_no = 1; break; case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oPrimaryKeyring: - sl=append_to_strlist( &nrings, pargs.r.ret_str); - sl->flags=2; + sl = append_to_strlist (&nrings, pargs.r.ret_str); + sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY; break; case oShowKeyring: deprecated_warning(configname,configlineno,"--show-keyring", @@ -3398,11 +3398,7 @@ main (int argc, char **argv) if( opt.verbose > 1 ) set_packet_list_mode(1); - /* Add the keyrings, but not for some special commands. Also - avoid adding the secret keyring for a couple of commands to - avoid unneeded access in case the secrings are stored on a - floppy. - + /* Add the keyrings, but not for some special commands. We always need to add the keyrings if we are running under SELinux, this is so that the rings are added to the list of secured files. */ @@ -3410,7 +3406,8 @@ main (int argc, char **argv) || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) ) { if (!nrings || default_keyring) /* Add default ring. */ - keydb_add_resource ("pubring" EXTSEP_S "gpg", 4); + keydb_add_resource ("pubring" EXTSEP_S "gpg", + KEYDB_RESOURCE_FLAG_DEFAULT); for (sl = nrings; sl; sl = sl->next ) keydb_add_resource (sl->d, sl->flags); } diff --git a/g10/gpgv.c b/g10/gpgv.c index 07e4a2e..5cb9c55 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -196,11 +196,12 @@ main( int argc, char **argv ) if (opt.verbose > 1) set_packet_list_mode(1); - /* Note: We open all keyrings in read-only mode (flag value: 8). */ + /* Note: We open all keyrings in read-only mode. */ if (!nrings) /* No keyring given: use default one. */ - keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 8); + keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", + KEYDB_RESOURCE_FLAG_READONLY); for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, 8); + keydb_add_resource (sl->d, KEYDB_RESOURCE_FLAG_READONLY); FREE_STRLIST (nrings); diff --git a/g10/keydb.c b/g10/keydb.c index 75c036c..ab727b6 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -34,6 +34,7 @@ #include "main.h" /*try_make_homedir ()*/ #include "packet.h" #include "keyring.h" +#include "../kbx/keybox.h" #include "keydb.h" #include "i18n.h" @@ -42,7 +43,8 @@ static int active_handles; typedef enum { KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYRING + KEYDB_RESOURCE_TYPE_KEYRING, + KEYDB_RESOURCE_TYPE_KEYBOX } KeydbResourceType; #define MAX_KEYDB_RESOURCES 40 @@ -51,6 +53,7 @@ struct resource_item KeydbResourceType type; union { KEYRING_HANDLE kr; + KEYBOX_HANDLE kb; } u; void *token; }; @@ -73,12 +76,12 @@ static int lock_all (KEYDB_HANDLE hd); static void unlock_all (KEYDB_HANDLE hd); -/* Handle the creation of a keyring if it does not yet exist. Take - into acount that other processes might have the keyring already - locked. This lock check does not work if the directory itself is - not yet available. */ +/* Handle the creation of a keyring or a keybox if it does not yet + exist. Take into acount that other processes might have the + keyring/keybox already locked. This lock check does not work if + the directory itself is not yet available. */ static int -maybe_create_keyring (char *filename, int force) +maybe_create_keyring_or_box (char *filename, int is_box, int force) { dotlock_t lockhd = NULL; IOBUF iobuf; @@ -139,29 +142,31 @@ maybe_create_keyring (char *filename, int force) lockhd = dotlock_create (filename, 0); if (!lockhd) { + rc = gpg_error_from_syserror (); /* A reason for this to fail is that the directory is not writable. However, this whole locking stuff does not make sense if this is the case. An empty non-writable directory with no keyring is not really useful at all. */ if (opt.verbose) - log_info ("can't allocate lock for '%s'\n", filename ); + log_info ("can't allocate lock for '%s': %s\n", + filename, gpg_strerror (rc)); if (!force) return gpg_error (GPG_ERR_ENOENT); else - return gpg_error (GPG_ERR_GENERAL); + return rc; } if ( dotlock_take (lockhd, -1) ) { + rc = gpg_error_from_syserror (); /* This is something bad. Probably a stale lockfile. */ - log_info ("can't lock '%s'\n", filename ); - rc = G10ERR_GENERAL; + log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc)); goto leave; } /* Now the real test while we are locked. */ - if (!access(filename, F_OK)) + if (!access (filename, F_OK)) { rc = 0; /* Okay, we may access the file now. */ goto leave; @@ -180,17 +185,51 @@ maybe_create_keyring (char *filename, int force) if (!iobuf) { rc = gpg_error_from_syserror (); - log_error ( _("error creating keyring '%s': %s\n"), - filename, strerror(errno)); + if (is_box) + log_error (_("error creating keybox '%s': %s\n"), + filename, gpg_strerror (rc)); + else + log_error (_("error creating keyring '%s': %s\n"), + filename, gpg_strerror (rc)); goto leave; } - if (!opt.quiet) - log_info (_("keyring '%s' created\n"), filename); - iobuf_close (iobuf); /* Must invalidate that ugly cache */ iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename); + + /* Make sure that at least one record is in a new keybox file, so + that the detection magic will work the next time it is used. */ + if (is_box) + { + FILE *fp = fopen (filename, "w"); + if (!fp) + rc = gpg_error_from_syserror (); + else + { + rc = _keybox_write_header_blob (fp); + fclose (fp); + } + if (rc) + { + if (is_box) + log_error (_("error creating keybox '%s': %s\n"), + filename, gpg_strerror (rc)); + else + log_error (_("error creating keyring '%s': %s\n"), + filename, gpg_strerror (rc)); + goto leave; + } + } + + if (!opt.quiet) + { + if (is_box) + log_info (_("keybox '%s' created\n"), filename); + else + log_info (_("keyring '%s' created\n"), filename); + } + rc = 0; leave: @@ -204,51 +243,49 @@ maybe_create_keyring (char *filename, int force) /* - * Register a resource (which currently may only be a keyring file). - * The first keyring which is added by this function is - * created if it does not exist. - * Note: this function may be called before secure memory is - * available. - * Flag 1 - Force. - * Flag 2 - Mark resource as primary. - * Flag 4 - This is a default resources. - * Flag 8 - Open as read-only. + * Register a resource (keyring or aeybox). The first keyring or + * keybox which is added by this function is created if it does not + * exist. FLAGS are a combination of the KEYDB_RESOURCE_FLAG_ + * constants as defined in keydb.h. */ gpg_error_t -keydb_add_resource (const char *url, int flags) +keydb_add_resource (const char *url, unsigned int flags) { - static int any_public; + static int any_registered; const char *resname = url; char *filename = NULL; - int force = (flags&1); - int read_only = !!(flags&8); + int create; + int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY); int rc = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; void *token; - if (read_only) - force = 0; + /* Create the resource if it is the first registered one. */ + create = (!read_only && !any_registered); /* Do we have an URL? - * gnupg-ring:filename := this is a plain keyring + * gnupg-ring:filename := this is a plain keyring. + * gnupg-kbx:filename := this is a keybox file. * filename := See what is is, but create as plain keyring. */ - if (strlen (resname) > 11) + if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) ) { - if (!strncmp( resname, "gnupg-ring:", 11) ) - { - rt = KEYDB_RESOURCE_TYPE_KEYRING; - resname += 11; - } + rt = KEYDB_RESOURCE_TYPE_KEYRING; + resname += 11; + } + else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) ) + { + rt = KEYDB_RESOURCE_TYPE_KEYBOX; + resname += 10; + } #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) - else if (strchr (resname, ':')) - { - log_error ("invalid key resource URL '%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } -#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ + else if (strchr (resname, ':')) + { + log_error ("invalid key resource URL '%s'\n", url ); + rc = gpg_error (GPG_ERR_GENERAL); + goto leave; } +#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ if (*resname != DIRSEP_C ) { @@ -261,9 +298,6 @@ keydb_add_resource (const char *url, int flags) else filename = xstrdup (resname); - if (!force && !read_only) - force = !any_public; - /* See whether we can determine the filetype. */ if (rt == KEYDB_RESOURCE_TYPE_NONE) { @@ -273,20 +307,25 @@ keydb_add_resource (const char *url, int flags) { u32 magic; - if (fread( &magic, 4, 1, fp) == 1 ) + if (fread (&magic, 4, 1, fp) == 1 ) { if (magic == 0x13579ace || magic == 0xce9a5713) ; /* GDBM magic - not anymore supported. */ + else if (fread (&magic, 4, 1, fp) == 1 + && !memcmp (&magic, "\x01", 1) + && fread (&magic, 4, 1, fp) == 1 + && !memcmp (&magic, "KBXf", 4)) + rt = KEYDB_RESOURCE_TYPE_KEYBOX; else rt = KEYDB_RESOURCE_TYPE_KEYRING; } else /* Maybe empty: assume keyring. */ rt = KEYDB_RESOURCE_TYPE_KEYRING; - fclose( fp ); + fclose (fp); } - else /* No file yet: create keyring. */ - rt = KEYDB_RESOURCE_TYPE_KEYRING; + else /* No file yet: create keybox. */ + rt = KEYDB_RESOURCE_TYPE_KEYBOX; } switch (rt) @@ -297,7 +336,7 @@ keydb_add_resource (const char *url, int flags) goto leave; case KEYDB_RESOURCE_TYPE_KEYRING: - rc = maybe_create_keyring (filename, force); + rc = maybe_create_keyring_or_box (filename, create, 0); if (rc) goto leave; @@ -307,7 +346,7 @@ keydb_add_resource (const char *url, int flags) rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { - if (flags&2) + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) primary_keyring = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kr = NULL; /* Not used here */ @@ -320,24 +359,61 @@ keydb_add_resource (const char *url, int flags) /* This keyring was already registered, so ignore it. However, we can still mark it as primary even if it was already registered. */ - if (flags&2) + if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) primary_keyring = token; } break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + { + rc = maybe_create_keyring_or_box (filename, create, 1); + if (rc) + goto leave; + + /* FIXME: How do we register a read-only keybox? */ + token = keybox_register_file (filename, 0); + if (token) + { + if (used_resources >= MAX_KEYDB_RESOURCES) + rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); + else + { + /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */ + /* primary_keyring = token; */ + all_resources[used_resources].type = rt; + all_resources[used_resources].u.kb = NULL; /* Not used here */ + all_resources[used_resources].token = token; + + /* FIXME: Do a compress run if needed and no other + user is currently using the keybox. */ + + used_resources++; + } + } + else + { + /* Already registered. We will mark it as the primary key + if requested. */ + /* FIXME: How to do that? Change the keybox interface? */ + /* if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) */ + /* primary_keyring = token; */ + } + } + break; + default: log_error ("resource type of '%s' not supported\n", url); rc = gpg_error (GPG_ERR_GENERAL); goto leave; } - /* fixme: check directory permissions and print a warning */ + /* fixme: check directory permissions and print a warning */ leave: if (rc) log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (rc)); else - any_public = 1; + any_registered = 1; xfree (filename); return rc; } @@ -371,6 +447,17 @@ keydb_new (void) } j++; break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + hd->active[j].type = all_resources[i].type; + hd->active[j].token = all_resources[i].token; + hd->active[j].u.kb = keybox_new (all_resources[i].token, 0); + if (!hd->active[j].u.kb) + { + xfree (hd); + return NULL; /* fixme: release all previously allocated handles*/ + } + j++; + break; } } hd->used = j; @@ -399,6 +486,9 @@ keydb_release (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: keyring_release (hd->active[i].u.kr); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + keybox_release (hd->active[i].u.kb); + break; } } @@ -438,6 +528,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: s = keyring_get_resource_name (hd->active[idx].u.kr); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + s = keybox_get_resource_name (hd->active[idx].u.kb); + break; } return s? s: ""; @@ -450,6 +543,13 @@ lock_all (KEYDB_HANDLE hd) { int i, rc = 0; + /* Fixme: This locking scheme may lead to a deadlock if the resources + are not added in the same order by all processes. We are + currently only allowing one resource so it is not a problem. + [Oops: Who claimed the latter] + + To fix this we need to use a lock file to protect lock_all. */ + for (i=0; !rc && i < hd->used; i++) { switch (hd->active[i].type) @@ -459,12 +559,15 @@ lock_all (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_lock (hd->active[i].u.kr, 1); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + rc = keybox_lock (hd->active[i].u.kb, 1); + break; } } if (rc) { - /* Revert the already set locks. */ + /* Revert the already taken locks. */ for (i--; i >= 0; i--) { switch (hd->active[i].type) @@ -474,6 +577,9 @@ lock_all (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: keyring_lock (hd->active[i].u.kr, 0); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + rc = keybox_lock (hd->active[i].u.kb, 0); + break; } } } @@ -501,6 +607,9 @@ unlock_all (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: keyring_lock (hd->active[i].u.kr, 0); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + keybox_lock (hd->active[i].u.kb, 0); + break; } } hd->locked = 0; @@ -532,6 +641,11 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) case KEYDB_RESOURCE_TYPE_KEYRING: err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); break; + /* case KEYDB_RESOURCE_TYPE_KEYBOX: */ + /* err = keybox_get_keyblock (hd->active[hd->found].u.kb, ret_kb); */ + /* if (!err) */ + /* err = parse_keyblock (image, imagelen) */ + /* break; */ } return err; @@ -566,6 +680,12 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb) case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb); break; + /* case KEYDB_RESOURCE_TYPE_KEYRING: */ + /* rc = build_keyblock (kb, &image, &imagelen); */ + /* if (!rc) */ + /* rc = keybox_update_keyblock (hd->active[hd->found].u.kb, */ + /* image, imagelen); */ + /* break; */ } unlock_all (hd); @@ -607,6 +727,11 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb); break; + /* case KEYDB_RESOURCE_TYPE_KEYBOX: */ + /* rc = build_keyblock (kb, &image, &imagelen); */ + /* if (!rc) */ + /* rc = keybox_insert_keyblock (hd->active[idx].u.kb, image, imagelen); */ + /* break; */ } unlock_all (hd); @@ -643,6 +768,9 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_delete_keyblock (hd->active[hd->found].u.kr); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + rc = keybox_delete (hd->active[hd->found].u.kb); + break; } unlock_all (hd); @@ -700,6 +828,10 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) if (keyring_is_writable (hd->active[hd->current].token)) return 0; /* found (hd->current is set to it) */ break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + if (keybox_is_writable (hd->active[hd->current].token)) + return 0; /* found (hd->current is set to it) */ + break; } } @@ -758,6 +890,9 @@ keydb_search_reset (KEYDB_HANDLE hd) case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_search_reset (hd->active[i].u.kr); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + rc = keybox_search_reset (hd->active[i].u.kb); + break; } } return rc; @@ -792,6 +927,9 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, rc = keyring_search (hd->active[hd->current].u.kr, desc, ndesc, descindex); break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + rc = keybox_search (hd->active[hd->current].u.kb, desc, ndesc); + break; } if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) { diff --git a/g10/keydb.h b/g10/keydb.h index 22c2b67..3ba9573 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -128,11 +128,12 @@ union pref_hint /*-- keydb.c --*/ -/* - Flag 1 == force - Flag 2 == default -*/ -gpg_error_t keydb_add_resource (const char *url, int flags); +#define KEYDB_RESOURCE_FLAG_PRIMARY 2 /* The primary resource. */ +#define KEYDB_RESOURCE_FLAG_DEFAULT 4 /* The default one. */ +#define KEYDB_RESOURCE_FLAG_READONLY 8 /* Open in read only mode. */ + +gpg_error_t keydb_add_resource (const char *url, unsigned int flags); + KEYDB_HANDLE keydb_new (void); void keydb_release (KEYDB_HANDLE hd); const char *keydb_get_resource_name (KEYDB_HANDLE hd); diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index ee48ca3..890e4dd 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -182,7 +182,6 @@ void _keybox_destroy_openpgp_info (keybox_openpgp_info_t info); int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp); int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted); int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer, diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 60594e3..d329941 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -200,3 +200,20 @@ _keybox_close_file (KEYBOX_HANDLE hd) } assert (!hd->fp); } + + +/* + * Lock the keybox at handle HD, or unlock if YES is false. Note that + * we currently ignore the handle and lock all registered keyboxes. + */ +int +keybox_lock (KEYBOX_HANDLE hd, int yes) +{ + /* FIXME: We need to implement it before we can use it with gpg. + gpgsm does the locking in its local keydb.c driver; this should + be changed as well. */ + + (void)hd; + (void)yes; + return 0; +} diff --git a/kbx/keybox.h b/kbx/keybox.h index 52bbe21..52c1638 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -71,6 +71,12 @@ void keybox_release (KEYBOX_HANDLE hd); const char *keybox_get_resource_name (KEYBOX_HANDLE hd); int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); +int keybox_lock (KEYBOX_HANDLE hd, int yes); + +/*-- keybox-file.c --*/ +/* Fixme: This function does not belong here: Provide a better + interface to create a new keybox file. */ +int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ #ifdef KEYBOX_WITH_X509 @@ -98,7 +104,6 @@ int keybox_compress (KEYBOX_HANDLE hd); /*-- --*/ #if 0 -int keybox_lock (KEYBOX_HANDLE hd, int yes); int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); int keybox_locate_writable (KEYBOX_HANDLE hd); int keybox_search_reset (KEYBOX_HANDLE hd); ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Dec 29 16:31:58 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Sat, 29 Dec 2012 16:31:58 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-63-gf484d8b 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 f484d8b28bccce7652362fa7940e53af04a412c8 (commit) from b87265cd30e24dc8c196331175b2838caf767cdc (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 f484d8b28bccce7652362fa7940e53af04a412c8 Author: NIIBE Yutaka Date: Sun Dec 30 00:24:20 2012 +0900 Update Japanese Translation * po/ja.po: Fix terms and expressions. diff --git a/po/ja.po b/po/ja.po index c2712b3..caa3a31 100644 --- a/po/ja.po +++ b/po/ja.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: GNU gnupg 2.0.20\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2012-12-29 20:51+0900\n" +"PO-Revision-Date: 2012-12-30 00:20+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: Japanese \n" "Language: ja\n" @@ -54,16 +54,19 @@ msgid "" "Please enter your PIN, so that the secret key can be unlocked for this " "session" msgstr "" -"????PIN?????????(" -"????????????????????????????)" +"????PIN?????????(???????????????????????" +"?????)" msgid "" "Please enter your passphrase, so that the secret key can be unlocked for " "this session" msgstr "" -"???????????????????(" -"????????????????????????????)" +"???????????????????(???????????????????" +"?????????)" +#. TRANSLATORS: The string is appended to an error message in +#. the pinentry. The %s is the actual error message, the +#. two %d give the current and maximum number of tries. #, c-format msgid "SETERROR %s (try %d of %d)" msgstr "SETERROR %s (?? %d / ?? %d)" @@ -123,14 +126,15 @@ msgstr "??????????????: %s\n" #, c-format msgid "error writing key: %s\n" -msgstr "????????: %s\n" +msgstr "?????????: %s\n" #, c-format msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " "allow this?" msgstr "" -"ssh???????????????????:%%0A %s%%0A (%s)%%0A???????????" +"ssh???????????????????:%%0A %s%%0A (%s)%%0A??????" +"?????" msgid "Allow" msgstr "????" @@ -150,8 +154,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"????????????????" -"gpg-agent?????????????%%0A %s%%0A %s%%0A???????" +"????????????????gpg-agent?????????????%%0A %s" +"%%0A %s%%0A???????" msgid "does not match - try again" msgstr "?????? - ????" @@ -199,7 +203,7 @@ msgstr "PUK???????????????????" msgid "PIN not correctly repeated; try again" msgstr "PIN???????????????????" -#, c-format +#, c-format msgid "Please enter the PIN%s%s%s to unlock the card" msgstr "???????????????PIN%s%s%s?????????" @@ -209,7 +213,7 @@ msgstr "????????????: %s\n" #, c-format msgid "error writing to temporary file: %s\n" -msgstr "?????????????: %s\n" +msgstr "??????????????: %s\n" msgid "Enter new passphrase" msgstr "??????????????????" @@ -225,7 +229,8 @@ msgid_plural "" "Warning: You have entered an insecure passphrase.%%0AA passphrase should be " "at least %u characters long." msgstr[0] "" -"??: ???????????????????????%%0A?????????%u??????????" +"??: ???????????????????????%%0A?????????%u" +"??????????" #, c-format msgid "" @@ -235,14 +240,16 @@ msgid_plural "" "Warning: You have entered an insecure passphrase.%%0AA passphrase should " "contain at least %u digits or%%0Aspecial characters." msgstr[0] "" -"??: ???????????????????????%%0A?????????%u?????????%%0A????????????" +"??: ???????????????????????%%0A?????????%u" +"?????????%%0A????????????" #, c-format msgid "" "Warning: You have entered an insecure passphrase.%%0AA passphrase may not be " "a known term or match%%0Acertain pattern." msgstr "" -"??: ???????????????????????%%0A????????????????????%%0A???????????????????????" +"??: ???????????????????????%%0A??????????" +"??????????%%0A???????????????????????" #, c-format msgid "" @@ -255,15 +262,15 @@ msgid "" "You have not entered a passphrase - this is in general a bad idea!%0APlease " "confirm that you do not want to have any protection on your key." msgstr "" -"????????????????? - ?????????????!%0A" -"???????????????????????" +"????????????????? - ?????????????!%0A?????" +"??????????????????" msgid "Yes, protection is not needed" msgstr "?????????????" #, c-format -msgid "Please enter the passphrase to%0Ato protect your new key" -msgstr "????????????????%0A?????????????????" +msgid "Please enter the passphrase to%0Aprotect your new key" +msgstr "?????????????%0A????????????????" msgid "Please enter the new passphrase" msgstr "??????????????????" @@ -285,7 +292,7 @@ msgid "verbose" msgstr "??" msgid "be somewhat more quiet" -msgstr "???????" +msgstr "?????????" msgid "sh-style command output" msgstr "sh-?????????" @@ -367,7 +374,7 @@ msgstr "%s ?????? (%s ?????? %s)\n" #, c-format msgid "NOTE: no default option file `%s'\n" -msgstr "??: ?????????????????%s???????\n" +msgstr "*??*: ?????????????????%s???????\n" #, c-format msgid "option file `%s': %s\n" @@ -504,13 +511,15 @@ msgid "Please enter the passphrase to unprotect the PKCS#12 object." msgstr "????????????????PKCS#12?????????????" msgid "Please enter the passphrase to protect the new PKCS#12 object." -msgstr "???????????????????PKCS#12?????????????" +msgstr "" +"???????????????????PKCS#12?????????????" msgid "" "Please enter the passphrase to protect the imported object within the GnuPG " "system." msgstr "" -"GnuPG??????????????????????????????????????????" +"GnuPG????????????????????????????????????" +"??????" msgid "" "Please enter the passphrase or the PIN\n" @@ -572,8 +581,7 @@ msgstr "???????????????????????\n" msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" -msgstr "" -"??????????%%0A \"%s\"%%0A?????????????????" +msgstr "??????????%%0A \"%s\"%%0A?????????????????" msgid "Yes" msgstr "??" @@ -594,7 +602,8 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"????????????:%%0A \"%s\"%%0A?????????????????:%%0A %s" +"????????????:%%0A \"%s\"%%0A?????????????????:" +"%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The @@ -614,7 +623,8 @@ msgid "" "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s. Please change " "it now." msgstr "" -"?????????%.4s-%.2s-%.2s????????????%%0A???????????" +"?????????%.4s-%.2s-%.2s????????????%%0A????????" +"???" msgid "Change passphrase" msgstr "???????????" @@ -946,8 +956,8 @@ msgstr "?????: ?????%d?????????\n" msgid "" "quoted printable character in armor - probably a buggy MTA has been used\n" msgstr "" -"?????quoted printable?????????????????\n" -"MTA?????????\n" +"?????quoted printable?????????????????MTA???????" +"???\n" msgid "" "a notation name must have only printable characters or spaces, and end with " @@ -965,7 +975,7 @@ msgid "a notation value must not use any control characters\n" msgstr "????????????????????\n" msgid "WARNING: invalid notation data found\n" -msgstr "??: ???????????\n" +msgstr "*??*: ???????????\n" msgid "not human readable" msgstr "????????" @@ -988,7 +998,7 @@ msgid "Reset Code not or not anymore available\n" msgstr "Reset Code?(???)???????????\n" msgid "Your selection? " -msgstr "??????? " +msgstr "???????? " msgid "[not set]" msgstr "[???]" @@ -1044,7 +1054,7 @@ msgstr "?%s?????????: %s\n" #, c-format msgid "error writing `%s': %s\n" -msgstr "?%s????????: %s\n" +msgstr "?%s?????????: %s\n" msgid "Login data (account name): " msgstr "???????? (??????): " @@ -1061,13 +1071,13 @@ msgid "Error: Private DO too long (limit is %d characters).\n" msgstr "???: ?????? DO?????? (??%d??)?\n" msgid "Language preferences: " -msgstr "?????: " +msgstr "???????: " msgid "Error: invalid length of preference string.\n" -msgstr "???: ??????????????\n" +msgstr "???: ?????????????????\n" msgid "Error: invalid characters in preference string.\n" -msgstr "???: ?????????????????\n" +msgstr "???: ????????????????????\n" msgid "Sex ((M)ale, (F)emale or space): " msgstr "?? ((M)??(F)????): " @@ -1100,9 +1110,9 @@ msgid "" " If the key generation does not succeed, please check the\n" " documentation of your card to see what sizes are allowed.\n" msgstr "" -"??: ????????????????????????????????\n" -" ????????????????????????????????\n" -" ??????????????????\n" +"*??*: ????????????????????????????????\n" +" ????????????????????????????????\n" +" ??????????????????\n" #, c-format msgid "What keysize do you want for the Signature key? (%u) " @@ -1136,10 +1146,10 @@ msgid "Make off-card backup of encryption key? (Y/n) " msgstr "?????????????????????? (Y/n) " msgid "NOTE: keys are already stored on the card!\n" -msgstr "??: ??????????????????!\n" +msgstr "*??*: ??????????????????!\n" msgid "Replace existing keys? (y/N) " -msgstr "???????????? (y/N) " +msgstr "????????????? (y/N) " #, c-format msgid "" @@ -1180,7 +1190,7 @@ msgstr "??????????????????\n" #, c-format msgid "error writing key to card: %s\n" -msgstr "???????????: %s\n" +msgstr "????????????: %s\n" msgid "quit this menu" msgstr "?????????" @@ -1198,7 +1208,7 @@ msgid "change card holder's name" msgstr "????????????" msgid "change URL to retrieve key" -msgstr "??????URL???" +msgstr "??????URL???" msgid "fetch the key specified in the card URL" msgstr "???URL????????????" @@ -1207,7 +1217,7 @@ msgid "change the login name" msgstr "????????" msgid "change the language preferences" -msgstr "???????" +msgstr "??????????" msgid "change card holder's sex" msgstr "????????????" @@ -1264,7 +1274,7 @@ msgid "(unless you specify the key by fingerprint)\n" msgstr "(????????????????????)\n" msgid "can't do this in batch mode without \"--yes\"\n" -msgstr "\"--yes\"?????????????????\n" +msgstr "\"--yes\"?????????????????\n" msgid "Delete this key from the keyring? (y/N) " msgstr "????????????????? (y/N) " @@ -1303,7 +1313,7 @@ msgstr "?%s??????????\n" #, c-format msgid "WARNING: `%s' is an empty file\n" -msgstr "??: ?%s??????????\n" +msgstr "*??*: ?%s??????????\n" msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n" msgstr "--pgp2?????2048??????RSA????????????\n" @@ -1319,17 +1329,19 @@ msgstr "???????????????IDEA??????? #, c-format msgid "" "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n" -msgstr "??: ??????? %s (%d) ?????????????????\n" +msgstr "" +"*??*: ??????? %s (%d) ???????????????????\n" #, c-format msgid "" "WARNING: forcing compression algorithm %s (%d) violates recipient " "preferences\n" -msgstr "??: ???????? %s (%d) ?????????????????\n" +msgstr "" +"*??*: ???????? %s (%d) ???????????????????\n" #, c-format msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" -msgstr "??????? %s (%d) ?????????????????\n" +msgstr "??????? %s (%d) ???????????????????\n" #, c-format msgid "you may not use %s while in %s mode\n" @@ -1349,7 +1361,7 @@ msgstr "?????????%d??????\n" msgid "" "WARNING: message was encrypted with a weak key in the symmetric cipher.\n" -msgstr "??: ????????????????????????????\n" +msgstr "*??*: ????????????????????????????\n" msgid "problem handling encrypted packet\n" msgstr "??????????????\n" @@ -1387,15 +1399,15 @@ msgstr "???????????????\n" #, c-format msgid "unable to read external program response: %s\n" -msgstr "??????????????????: %s\n" +msgstr "??????????????????: %s\n" #, c-format msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n" -msgstr "??: ?????????????? (%s) ?%s?: %s\n" +msgstr "*??*: ?????????????? (%s) ?%s?: %s\n" #, c-format msgid "WARNING: unable to remove temp directory `%s': %s\n" -msgstr "??: ?????????%s?????????: %s\n" +msgstr "*??*: ?????????%s?????????: %s\n" msgid "export signatures that are marked as local-only" msgstr "????????????????????????" @@ -1404,7 +1416,7 @@ msgid "export attribute user IDs (generally photo IDs)" msgstr "???ID???(?????ID)??????????" msgid "export revocation keys marked as \"sensitive\"" -msgstr "\"sensitive\"???????????????????" +msgstr "\"sensitive\"(??)???????????????????" msgid "remove the passphrase from exported subkeys" msgstr "???????????????????????" @@ -1442,10 +1454,10 @@ msgstr "???????????????????: %s\n" #, c-format msgid "WARNING: secret key %s does not have a simple SK checksum\n" -msgstr "??: ???%s??????SK????????????\n" +msgstr "*??*: ???%s??????SK????????????\n" msgid "WARNING: nothing exported\n" -msgstr "??: ??????????????\n" +msgstr "*??*: ??????????????\n" msgid "too many entries in pk cache - disabled\n" msgstr "pk????????????????? - ????\n" @@ -1559,7 +1571,7 @@ msgid "import/merge keys" msgstr "???????/???" msgid "print the card status" -msgstr "????????" +msgstr "????????????" msgid "change data on a card" msgstr "??????????" @@ -1634,8 +1646,8 @@ msgstr "???: gpg [?????] [????] (???? -h)" msgid "" "Syntax: gpg [options] [files]\n" -"sign, check, encrypt or decrypt\n" -"default operation depends on the input data\n" +"Sign, check, encrypt or decrypt\n" +"Default operation depends on the input data\n" msgstr "" "??: gpg [?????] [????]\n" "????????????\n" @@ -1672,53 +1684,57 @@ msgstr "=???????????%s??????????\n" #, c-format msgid "WARNING: unsafe ownership on homedir `%s'\n" -msgstr "??: homedir ?%s??????????\n" +msgstr "*??*: homedir ?%s??????????\n" #, c-format msgid "WARNING: unsafe ownership on configuration file `%s'\n" -msgstr "??: ????????????????%s??????????\n" +msgstr "*??*: ????????????????%s??????????\n" #, c-format msgid "WARNING: unsafe ownership on extension `%s'\n" -msgstr "??: ???%s??????????\n" +msgstr "*??*: ???%s??????????\n" #, c-format msgid "WARNING: unsafe permissions on homedir `%s'\n" -msgstr "??: homedir ?%s?????????\n" +msgstr "*??*: homedir ?%s?????????\n" #, c-format msgid "WARNING: unsafe permissions on configuration file `%s'\n" -msgstr "??: ????????????????%s?????????\n" +msgstr "*??*: ????????????????%s?????????\n" #, c-format msgid "WARNING: unsafe permissions on extension `%s'\n" -msgstr "??: ???%s?????????\n" +msgstr "*??*: ???%s?????????\n" #, c-format msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n" -msgstr "??: homedir ?%s??????????????????\n" +msgstr "*??*: homedir ?%s??????????????????\n" #, c-format msgid "" "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n" -msgstr "??: ????????????????%s??????????????????\n" +msgstr "" +"*??*: ????????????????%s?????????????????" +"?\n" #, c-format msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n" -msgstr "??: ???%s??????????????????\n" +msgstr "*??*: ???%s??????????????????\n" #, c-format msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n" -msgstr "??: homedir ?%s?????????????????\n" +msgstr "*??*: homedir ?%s?????????????????\n" #, c-format msgid "" "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n" -msgstr "??: ????????????????%s?????????????????\n" +msgstr "" +"*??*: ????????????????%s????????????????" +"?\n" #, c-format msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n" -msgstr "??: ???%s?????????????????\n" +msgstr "*??*: ???%s?????????????????\n" #, c-format msgid "unknown configuration item `%s'\n" @@ -1740,7 +1756,7 @@ msgid "show user-supplied notations during signature listings" msgstr "?????????????????" msgid "show preferred keyserver URLs during signature listings" -msgstr "?????????????URL?????" +msgstr "????????????URL?????" msgid "show user ID validity during key listings" msgstr "????????ID?????????" @@ -1759,7 +1775,8 @@ msgstr "??????????????????" #, c-format msgid "NOTE: old default options file `%s' ignored\n" -msgstr "??: ?????????????????????%s?????????\n" +msgstr "" +"*??*: ?????????????????????%s?????????\n" #, c-format msgid "libgcrypt is too old (need %s, have %s)\n" @@ -1767,7 +1784,7 @@ msgstr "libgcrypt ?????? (?? %s, ?? %s)\n" #, c-format msgid "NOTE: %s is not for normal use!\n" -msgstr "??: ??%s??????!\n" +msgstr "*??*: ??%s??????!\n" #, c-format msgid "`%s' is not a valid signature expiration\n" @@ -1824,7 +1841,7 @@ msgid "show user-supplied notations during signature verification" msgstr "??????????????????" msgid "show preferred keyserver URLs during signature verification" -msgstr "??????????????URL?????" +msgstr "?????????????URL?????" msgid "show user ID validity during signature verification" msgstr "??????????ID?????????" @@ -1860,11 +1877,11 @@ msgid "invalid auto-key-locate list\n" msgstr "??? auto-key-locate ?????\n" msgid "WARNING: program may create a core file!\n" -msgstr "??: ????????????????????????!\n" +msgstr "*??*: ????????????????????????!\n" #, c-format msgid "WARNING: %s overrides %s\n" -msgstr "??: %s?%s????\n" +msgstr "*??*: %s?%s????\n" #, c-format msgid "%s not allowed with %s!\n" @@ -1918,22 +1935,22 @@ msgid "invalid min-cert-level; must be 1, 2, or 3\n" msgstr "???min-cert-level?0?1?2?3??????????\n" msgid "NOTE: simple S2K mode (0) is strongly discouraged\n" -msgstr "??: ???S2K???(0)????????????\n" +msgstr "*??*: ???S2K???(0)????????????\n" msgid "invalid S2K mode; must be 0, 1 or 3\n" msgstr "???S2K????0?1?3??????????\n" msgid "invalid default preferences\n" -msgstr "???????????\n" +msgstr "?????????????\n" msgid "invalid personal cipher preferences\n" -msgstr "?????????????\n" +msgstr "???????????????\n" msgid "invalid personal digest preferences\n" -msgstr "???????????????\n" +msgstr "?????????????????\n" msgid "invalid personal compress preferences\n" -msgstr "???????????\n" +msgstr "?????????????\n" #, c-format msgid "%s does not yet work with %s\n" @@ -1956,7 +1973,7 @@ msgid "failed to initialize the TrustDB: %s\n" msgstr "???????????????????: %s\n" msgid "WARNING: recipients (-r) given without using public key encryption\n" -msgstr "??: ?????????????? (-r) ????????\n" +msgstr "*??*: ?????????????? (-r) ????????\n" msgid "--store [filename]" msgstr "--store [?????]" @@ -2057,13 +2074,13 @@ msgid "Go ahead and type your message ...\n" msgstr "??????????????????? ...\n" msgid "the given certification policy URL is invalid\n" -msgstr "?????????????URL?????\n" +msgstr "????????????URL?????\n" msgid "the given signature policy URL is invalid\n" -msgstr "????????????URL?????\n" +msgstr "???????????URL?????\n" msgid "the given preferred keyserver URL is invalid\n" -msgstr "???????????URL?????\n" +msgstr "???????????URL?????\n" msgid "|FILE|take the keys from the keyring FILE" msgstr "|FILE|????FILE???????" @@ -2072,7 +2089,7 @@ msgid "make timestamp conflicts only a warning" msgstr "??????????????" msgid "|FD|write status info to this FD" -msgstr "|FD|??FD?????????????" +msgstr "|FD|??FD?????????????" msgid "Usage: gpgv [options] [files] (-h for help)" msgstr "???: gpgv [?????] [????] (???? -h)" @@ -2114,7 +2131,7 @@ msgstr "??????????????????" #, c-format msgid "skipping block of type %d\n" -msgstr "?%d???????????\n" +msgstr "?%d?????????????\n" #, c-format msgid "%lu keys processed so far\n" @@ -2158,7 +2175,7 @@ msgstr " ???????: %lu\n" #, c-format msgid " secret keys read: %lu\n" -msgstr " ???????: %lu\n" +msgstr " ????????: %lu\n" #, c-format msgid " secret keys imported: %lu\n" @@ -2185,29 +2202,30 @@ msgid "" "WARNING: key %s contains preferences for unavailable\n" "algorithms on these user IDs:\n" msgstr "" -"??: ?%s??????????ID???????????????????????\n" +"*??*: ?%s??????????ID?????????????????????" +"????\n" #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" -msgstr " \"%s\": ??????????? %s\n" +msgstr " \"%s\": ????????????? %s\n" #, c-format msgid " \"%s\": preference for digest algorithm %s\n" -msgstr " \"%s\": ???????????????? %s\n" +msgstr " \"%s\": ?????????????????? %s\n" #, c-format msgid " \"%s\": preference for compression algorithm %s\n" -msgstr " \"%s\": ??????????? %s\n" +msgstr " \"%s\": ????????????? %s\n" msgid "it is strongly suggested that you update your preferences and\n" -msgstr "???????????????????????????????\n" +msgstr "?????????????????????????????????\n" msgid "re-distribute this key to avoid potential algorithm mismatch problems\n" -msgstr "?????????????????????????????\n" +msgstr "??????????????????????????????\n" #, c-format msgid "you can update your preferences with: gpg --edit-key %s updpref save\n" -msgstr "?????????????: gpg --edit-key %s updpref save\n" +msgstr "???????????????: gpg --edit-key %s updpref save\n" #, c-format msgid "key %s: no user ID\n" @@ -2238,15 +2256,15 @@ msgstr "?%s: ?????? - ???????\n" #, c-format msgid "no writable keyring found: %s\n" -msgstr "??????????????????: %s\n" +msgstr "???????????????????: %s\n" #, c-format msgid "writing to `%s'\n" -msgstr "?%s??????\n" +msgstr "?%s???????\n" #, c-format msgid "error writing keyring `%s': %s\n" -msgstr "?????%s????????: %s\n" +msgstr "?????%s?????????: %s\n" #, c-format msgid "key %s: public key \"%s\" imported\n" @@ -2262,7 +2280,7 @@ msgstr "?%s: ?????????????????: %s\n" #, c-format msgid "key %s: can't read original keyblock: %s\n" -msgstr "?%s: ???????????????: %s\n" +msgstr "?%s: ???????????????: %s\n" #, c-format msgid "key %s: \"%s\" 1 new user ID\n" @@ -2421,11 +2439,11 @@ msgstr "?%s: ???????ID??? - ???\n" #, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" -msgstr "??: ?%s??????????: ???%s?????\n" +msgstr "*??*: ?%s??????????: ???%s?????\n" #, c-format msgid "WARNING: key %s may be revoked: revocation key %s not present.\n" -msgstr "??: ?%s??????????: ???%s????\n" +msgstr "*??*: ?%s??????????: ???%s????\n" #, c-format msgid "key %s: \"%s\" revocation certificate added\n" @@ -2436,13 +2454,13 @@ msgid "key %s: direct key signature added\n" msgstr "?%s: ????????\n" msgid "NOTE: a key's S/N does not match the card's one\n" -msgstr "??: ??????????????????????\n" +msgstr "*??*: ??????????????????????\n" msgid "NOTE: primary key is online and stored on card\n" -msgstr "??: ?????????????????\n" +msgstr "*??*: ?????????????????\n" msgid "NOTE: secondary key is online and stored on card\n" -msgstr "??: ??????????????????\n" +msgstr "*??*: ??????????????????\n" #, c-format msgid "error creating keyring `%s': %s\n" @@ -2501,7 +2519,8 @@ msgid "" "etc.)\n" msgstr "" "????????????????????????????????????\n" -"(?????????????????????????????????????????)\n" +"(??????????????????????????????????????" +"???)\n" #, c-format msgid " %d = I trust marginally\n" @@ -2567,7 +2586,7 @@ msgstr "" "????????\n" msgid "Do you want to issue a new signature to replace the expired one? (y/N) " -msgstr "?????????????????????????? (y/N) " +msgstr "??????????????????????????? (y/N) " #, c-format msgid "" @@ -2652,10 +2671,10 @@ msgid "This will be a self-signature.\n" msgstr "????????????\n" msgid "WARNING: the signature will not be marked as non-exportable.\n" -msgstr "??: ?????????????????????\n" +msgstr "*??*: ?????????????????????\n" msgid "WARNING: the signature will not be marked as non-revocable.\n" -msgstr "??: ?????????????????\n" +msgstr "*??*: ?????????????????\n" msgid "The signature will be marked as non-exportable.\n" msgstr "????????????????????\n" @@ -2680,7 +2699,9 @@ msgid "signing failed: %s\n" msgstr "?????????: %s\n" msgid "Key has only stub or on-card key items - no passphrase to change.\n" -msgstr "???????????????????????? - ???????????????\n" +msgstr "" +"???????????????????????? - ?????????????" +"??\n" msgid "This key is not protected.\n" msgstr "??????????????\n" @@ -2792,16 +2813,16 @@ msgid "toggle between the secret and public key listings" msgstr "?????????????" msgid "list preferences (expert)" -msgstr "????? (??????)" +msgstr "??????? (??????)" msgid "list preferences (verbose)" -msgstr "????? (??)" +msgstr "??????? (??)" msgid "set preference list for the selected user IDs" -msgstr "???????ID?????????" +msgstr "???????ID???????????" msgid "set the preferred keyserver URL for the selected user IDs" -msgstr "???????ID????????URI???" +msgstr "???????ID????????URI???" msgid "set a notation for the selected user IDs" msgstr "???????ID????????" @@ -2857,7 +2878,8 @@ msgid "" msgstr "" "* `sign' ????? `l' ?????????????? (lsign)?\n" " `t' ????????? (tsign)?`nr' ???????????\n" -" (nrsign)?????????????? (ltsign, tnrsign, ????)??????\n" +" (nrsign)?????????????? (ltsign, tnrsign, ????)????" +"??\n" msgid "Key is revoked." msgstr "????????????" @@ -2932,16 +2954,17 @@ msgid "Do you really want to revoke this subkey? (y/N) " msgstr "??????????????? (y/N) " msgid "Owner trust may not be set while using a user provided trust database\n" -msgstr "???????????????????????????????????\n" +msgstr "" +"???????????????????????????????????\n" msgid "Set preference list to:\n" -msgstr "????????:\n" +msgstr "??????????:\n" msgid "Really update the preferences for the selected user IDs? (y/N) " -msgstr "???????ID?????????????? (y/N) " +msgstr "???????ID???????????????? (y/N) " msgid "Really update the preferences? (y/N) " -msgstr "????????????? (y/N) " +msgstr "??????????????? (y/N) " msgid "Save changes? (y/N) " msgstr "?????????? (y/N) " @@ -2967,16 +2990,16 @@ msgid "Features: " msgstr "??: " msgid "Keyserver no-modify" -msgstr "???????" +msgstr "???? ?????" msgid "Preferred keyserver: " -msgstr "??????: " +msgstr "??????: " msgid "Notations: " msgstr "??: " msgid "There are no preferences on a PGP 2.x-style user ID.\n" -msgstr "PGP 2.x?????ID???????????\n" +msgstr "PGP 2.x?????ID?????????????\n" #, c-format msgid "The following key was revoked on %s by %s key %s\n" @@ -2987,7 +3010,7 @@ msgid "This key may be revoked by %s key %s" msgstr "?????%s?%s?????????????" msgid "(sensitive)" -msgstr "(?????)" +msgstr "(????)" #, c-format msgid "created: %s" @@ -3040,7 +3063,7 @@ msgid "" "WARNING: no user ID has been marked as primary. This command may\n" " cause a different user ID to become the assumed primary.\n" msgstr "" -"??: ??????ID?????????????????\n" +"*??*: ??????ID?????????????????\n" " ???ID??????????????????\n" msgid "" @@ -3048,7 +3071,8 @@ msgid "" "versions\n" " of PGP to reject this key.\n" msgstr "" -"??: ???PGP2??????????ID??????????????PGP???\n" +"*??*: ???PGP2??????????ID??????????????PGP?" +"??\n" " ????????????????\n" msgid "Are you sure you still want to add it? (y/N) " @@ -3108,7 +3132,8 @@ msgid "" "cause\n" " some versions of PGP to reject this key.\n" msgstr "" -"??: ???PGP 2.x??????????????????????????PGP???\n" +"*??*: ???PGP 2.x??????????????????????????PGP" +"???\n" " ????????????????\n" msgid "You may not add a designated revoker to a PGP 2.x-style key.\n" @@ -3127,7 +3152,7 @@ msgid "this key has already been designated as a revoker\n" msgstr "????????????????????\n" msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n" -msgstr "??: ???????????????????????!\n" +msgstr "*??*: ???????????????????????!\n" msgid "" "Are you sure you want to appoint this key as a designated revoker? (y/N) " @@ -3164,13 +3189,13 @@ msgstr "???ID?????????????????\n" #, c-format msgid "skipping v3 self-signature on user ID \"%s\"\n" -msgstr "???ID\"%s\"?v3??????????\n" +msgstr "???ID\"%s\"?v3????????????\n" msgid "Enter your preferred keyserver URL: " -msgstr "??????URL?????????: " +msgstr "??????URL?????????: " msgid "Are you sure you want to replace it? (y/N) " -msgstr "???????????? (y/N) " +msgstr "????????????? (y/N) " msgid "Are you sure you want to delete it? (y/N) " msgstr "???????????? (y/N) " @@ -3243,7 +3268,7 @@ msgstr "???ID\"%s\"????????????\n" #, c-format msgid "WARNING: a user ID signature is dated %d seconds in the future\n" -msgstr "??: ???ID????%d?????\n" +msgstr "*??*: ???ID????%d?????\n" #, c-format msgid "Key %s is already revoked.\n" @@ -3259,20 +3284,20 @@ msgstr "%s (???%ld) ??%s (uid %d) ????ID?????\n" #, c-format msgid "preference `%s' duplicated\n" -msgstr "???%s????\n" +msgstr "?????%s????\n" msgid "too many cipher preferences\n" -msgstr "??????????\n" +msgstr "???????????????\n" msgid "too many digest preferences\n" -msgstr "????????????\n" +msgstr "?????????????????\n" msgid "too many compression preferences\n" -msgstr "????????\n" +msgstr "?????????????\n" #, c-format msgid "invalid item `%s' in preference string\n" -msgstr "????????????%s??????\n" +msgstr "???????????????%s??????\n" msgid "writing direct signature\n" msgstr "???????????\n" @@ -3294,7 +3319,8 @@ msgstr "???%u????????\n" msgid "" "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n" msgstr "" -"??: ?????OpenPGP????????????????DSA????????????\n" +"*??*: ?????OpenPGP????????????????DSA????????" +"????\n" msgid "Sign" msgstr "Sign" @@ -3330,15 +3356,15 @@ msgstr "??????????: " #, c-format msgid " (%c) Toggle the sign capability\n" -msgstr " (%c) ??????????\n" +msgstr " (%c) ?????????\n" #, c-format msgid " (%c) Toggle the encrypt capability\n" -msgstr " (%c) ??????????\n" +msgstr " (%c) ?????????\n" #, c-format msgid " (%c) Toggle the authenticate capability\n" -msgstr " (%c) ??????????\n" +msgstr " (%c) ?????????\n" #, c-format msgid " (%c) Finished\n" @@ -3565,8 +3591,8 @@ msgid "" "Please enter a passphrase to protect the off-card backup of the new " "encryption key." msgstr "" -"?????????????????????????????????????????" -"??????????" +"??????????????????????????????????????" +"?????????????" #, c-format msgid "%s.\n" @@ -3578,9 +3604,9 @@ msgid "" "using this program with the option \"--edit-key\".\n" "\n" msgstr "" -"???????????????????????????????????!\n" -"??????????????????????????????????????????\n" -"?\"--edit-key\"?????????????????\n" +"??????????????????????????????????!\n" +"???????????????????????????????????\n" +"????????\"--edit-key\"?????????????????\n" "\n" msgid "" @@ -3589,8 +3615,10 @@ msgid "" "disks) during the prime generation; this gives the random number\n" "generator a better chance to gain enough entropy.\n" msgstr "" -"??????????????????????????????????????\n" -"???????????????????????????????????????\n" +"?????????????????????????????????????" +"??\n" +"?????????????????????????????????????" +"?\n" "????????????????????????????\n" msgid "Key generation canceled.\n" @@ -3610,19 +3638,19 @@ msgstr "?%s????????????\n" #, c-format msgid "no writable public keyring found: %s\n" -msgstr "????????????????????: %s\n" +msgstr "?????????????????????: %s\n" #, c-format msgid "no writable secret keyring found: %s\n" -msgstr "????????????????????: %s\n" +msgstr "?????????????????????: %s\n" #, c-format msgid "error writing public keyring `%s': %s\n" -msgstr "???????%s????????: %s\n" +msgstr "???????%s?????????: %s\n" #, c-format msgid "error writing secret keyring `%s': %s\n" -msgstr "???????%s????????: %s\n" +msgstr "???????%s?????????: %s\n" msgid "public and secret key created and signed.\n" msgstr "???????????????????\n" @@ -3641,15 +3669,15 @@ msgstr "???????????: %s\n" #, c-format msgid "" "key has been created %lu second in future (time warp or clock problem)\n" -msgstr "??%lu????????? (??????????????)\n" +msgstr "??%lu????????? (??????????????)\n" #, c-format msgid "" "key has been created %lu seconds in future (time warp or clock problem)\n" -msgstr "??%lu????????? (??????????????)\n" +msgstr "??%lu????????? (??????????????)\n" msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n" -msgstr "??: v3?????????OpenPGP???????\n" +msgstr "*??*: v3????????????OpenPGP???????\n" msgid "Really create? (y/N) " msgstr "?????????? (y/N) " @@ -3664,19 +3692,19 @@ msgstr "????????????%s?????????: %s\n" #, c-format msgid "NOTE: backup of card key saved to `%s'\n" -msgstr "??: ?????????????%s????????\n" +msgstr "*??*: ?????????????%s????????\n" msgid "never " msgstr "??? " msgid "Critical signature policy: " -msgstr "?????????????: " +msgstr "????????????: " msgid "Signature policy: " -msgstr "??????: " +msgstr "?????: " msgid "Critical preferred keyserver: " -msgstr "?????????: " +msgstr "?????????????: " msgid "Critical signature notation: " msgstr "???????????: " @@ -3702,17 +3730,17 @@ msgid " Subkey fingerprint:" msgstr "????????????:" msgid " Key fingerprint =" -msgstr " ?????????? =" +msgstr " ?????????? =" msgid " Card serial no. =" -msgstr " ?????????? =" +msgstr " ?????????? =" #, c-format msgid "renaming `%s' to `%s' failed: %s\n" msgstr "?%s????%s?????????: %s\n" msgid "WARNING: 2 files with confidential information exists.\n" -msgstr "??: ????????2?????????????\n" +msgstr "*??*: ?????????????2???????\n" #, c-format msgid "%s is the unchanged one\n" @@ -3723,7 +3751,7 @@ msgid "%s is the new one\n" msgstr "%s???????\n" msgid "Please fix this possible security flaw\n" -msgstr "?????????????????????\n" +msgstr "????????????????????\n" #, c-format msgid "caching keyring `%s'\n" @@ -3757,7 +3785,7 @@ msgid "automatically retrieve keys when verifying signatures" msgstr "?????????????????" msgid "honor the preferred keyserver URL set on the key" -msgstr "??????????????URL????" +msgstr "?????????????URL????" msgid "honor the PKA record set on a key when retrieving keys" msgstr "???????PKA??????????????" @@ -3765,10 +3793,10 @@ msgstr "???????PKA??????????????" #, c-format msgid "WARNING: keyserver option `%s' is not used on this platform\n" msgstr "" -"??: ???????????%s???????????????????\n" +"*??*: ???????????%s????????????????????\n" msgid "disabled" -msgstr "disabled" +msgstr "????" msgid "Enter number(s), N)ext, or Q)uit > " msgstr "??(s)?N)?????Q)??????????? >" @@ -3821,7 +3849,7 @@ msgstr "????????????????!\n" #, c-format msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n" -msgstr "??: ?? (%s) ?GnuPG??????????\n" +msgstr "*??*: ????????GnuPG?????????? (%s)\n" msgid "keyserver did not send VERSION\n" msgstr "?????VERSION??????????\n" @@ -3856,11 +3884,11 @@ msgstr "?????????: %s\n" #, c-format msgid "\"%s\" not a key ID: skipping\n" -msgstr "\"%s\"?ID???????: ?????\n" +msgstr "\"%s\"?ID???????: ???????\n" #, c-format msgid "WARNING: unable to refresh key %s via %s: %s\n" -msgstr "??: ?%s?%s??????????: %s\n" +msgstr "*??*: ?%s?%s??????????: %s\n" #, c-format msgid "refreshing 1 key from %s\n" @@ -3872,11 +3900,11 @@ msgstr "%d????%s????\n" #, c-format msgid "WARNING: unable to fetch URI %s: %s\n" -msgstr "??: URI %s ???????????: %s\n" +msgstr "*??*: URI %s ???????????: %s\n" #, c-format msgid "WARNING: unable to parse URI %s\n" -msgstr "??: URI %s ????????\n" +msgstr "*??*: URI %s ????????\n" #, c-format msgid "weird size for an encrypted session key (%d)\n" @@ -3932,31 +3960,31 @@ msgid "decryption okay\n" msgstr "?????\n" msgid "WARNING: message was not integrity protected\n" -msgstr "??: ???????????????????\n" +msgstr "*??*: ???????????????????\n" msgid "WARNING: encrypted message has been manipulated!\n" -msgstr "??: ????????????????????!\n" +msgstr "*??*: ????????????????????!\n" #, c-format msgid "cleared passphrase cached with ID: %s\n" -msgstr "?????????????????????? ID: %s\n" +msgstr "?????????????????? ID: %s\n" #, c-format msgid "decryption failed: %s\n" msgstr "?????????: %s\n" msgid "NOTE: sender requested \"for-your-eyes-only\"\n" -msgstr "??: ????\"?????\"?????????\n" +msgstr "*??*: ????\"?????\"?????????\n" #, c-format msgid "original file name='%.*s'\n" msgstr "???????='%.*s'\n" msgid "WARNING: multiple plaintexts seen\n" -msgstr "??: ?????????????????\n" +msgstr "*??*: ?????????????????\n" msgid "standalone revocation - use \"gpg --import\" to apply\n" -msgstr "???? - \"gpg --import\"????????????\n" +msgstr "????????? - \"gpg --import\"????????????\n" msgid "no signature found\n" msgstr "??????????\n" @@ -3984,7 +4012,7 @@ msgstr "?????????: " #, c-format msgid "BAD signature from \"%s\"" -msgstr "\"%s\"??? ??? ??" +msgstr "\"%s\"???*???*??" #, c-format msgid "Expired signature from \"%s\"" @@ -4014,7 +4042,7 @@ msgid "%s signature, digest algorithm %s\n" msgstr "%s???????????????? %s\n" msgid "binary" -msgstr "?????" +msgstr "????" msgid "textmode" msgstr "???????" @@ -4031,11 +4059,11 @@ msgstr "??????????\n" msgid "" "WARNING: multiple signatures detected. Only the first will be checked.\n" -msgstr "??: ?????????????????????\n" +msgstr "*??*: ?????????????????????\n" #, c-format msgid "standalone signature of class 0x%02x\n" -msgstr "???0x%02x?????\n" +msgstr "???0x%02x??????????\n" msgid "old style (PGP 2.x) signature\n" msgstr "???? (PGP 2.x) ???\n" @@ -4053,22 +4081,22 @@ msgstr "fstat(%d)?%s???????: %s\n" #, c-format msgid "WARNING: using experimental public key algorithm %s\n" -msgstr "??: ????????????%s??????\n" +msgstr "*??*: ????????????%s??????\n" msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n" -msgstr "??: Elgamal??+?????????????\n" +msgstr "*??*: Elgamal??+?????????????\n" #, c-format msgid "WARNING: using experimental cipher algorithm %s\n" -msgstr "??: ??????????? %s ??????\n" +msgstr "*??*: ??????????? %s ??????\n" #, c-format msgid "WARNING: using experimental digest algorithm %s\n" -msgstr "??: ???????????????? %s???\n" +msgstr "*??*: ???????????????? %s???\n" #, c-format msgid "WARNING: digest algorithm %s is deprecated\n" -msgstr "??: ????????????? %s ?????????\n" +msgstr "*??*: ????????????? %s ?????????\n" msgid "the IDEA cipher plugin is not present\n" msgstr "IDEA????????????????\n" @@ -4083,7 +4111,7 @@ msgstr "%s:%d: ??????????\"%s\"\n" #, c-format msgid "WARNING: \"%s\" is a deprecated option\n" -msgstr "??: \"%s\"??????????????\n" +msgstr "*??*: \"%s\"??????????????\n" #, c-format msgid "please use \"%s%s\" instead\n" @@ -4091,15 +4119,17 @@ msgstr "\"%s%s\"????????????\n" #, c-format msgid "WARNING: \"%s\" is a deprecated command - do not use it\n" -msgstr "??: \"%s\" ??????????????? - ?????????\n" +msgstr "*??*: \"%s\" ??????????????? - ?????????\n" #, c-format msgid "%s:%u: obsolete option \"%s\" - it has no effect\n" -msgstr "%s:%u: \"%s\"????????????????? - ???????????\n" +msgstr "" +"%s:%u: \"%s\"????????????????? - ???????????\n" #, c-format msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n" -msgstr "??: \"%s\"????????????????? - ???????????\n" +msgstr "" +"*??*: \"%s\"????????????????? - ???????????\n" msgid "Uncompressed" msgstr "???" @@ -4147,14 +4177,14 @@ msgstr "???????????????????%s???? #, c-format msgid "WARNING: options in `%s' are not yet active during this run\n" -msgstr "??: ?%s?????????????????????????\n" +msgstr "*??*: ?%s?????????????????????????\n" #, c-format msgid "can't handle public key algorithm %d\n" msgstr "??????????%d?????????\n" msgid "WARNING: potentially insecure symmetrically encrypted session key\n" -msgstr "??: ?????????????????????????\n" +msgstr "*??*: ?????????????????????????\n" #, c-format msgid "subpacket of type %d has critical bit set\n" @@ -4176,7 +4206,8 @@ msgid "" "%u-bit %s key, ID %s,\n" "created %s%s.\n" msgstr "" -"OpenPGP??????????????????????????????????:\n" +"OpenPGP?????????????????????????????????" +"?:\n" "\"%.*s\"\n" "%u??? %s ?, ID %s,\n" "???? %s%s?\n" @@ -4261,6 +4292,16 @@ msgstr "????: " msgid "revocation comment: " msgstr "???????: " +#. TRANSLATORS: These are the allowed answers in lower and +#. uppercase. Below you will find the matching strings which +#. should be translated accordingly and the letter changed to +#. match the one in the answer string. +#. +#. i = please show me more information +#. m = back to the main menu +#. s = skip this key +#. q = quit +#. msgid "iImMqQsS" msgstr "iImMqQsS" @@ -4339,22 +4380,22 @@ msgid "Use this key anyway? (y/N) " msgstr "?????????????? (y/N) " msgid "WARNING: Using untrusted key!\n" -msgstr "??: ??????????????!\n" +msgstr "*??*: ??????????????!\n" msgid "WARNING: this key might be revoked (revocation key not present)\n" -msgstr "??: ????????????? (??????)\n" +msgstr "*??*: ????????????? (??????)\n" msgid "WARNING: This key has been revoked by its designated revoker!\n" -msgstr "??: ?????????????????????!\n" +msgstr "*??*: ?????????????????????!\n" msgid "WARNING: This key has been revoked by its owner!\n" -msgstr "??: ???????????????????!\n" +msgstr "*??*: ???????????????????!\n" msgid " This could mean that the signature is forged.\n" msgstr " ????????????????????\n" msgid "WARNING: This subkey has been revoked by its owner!\n" -msgstr "??: ????????????????????!\n" +msgstr "*??*: ????????????????????!\n" msgid "Note: This key has been disabled.\n" msgstr "??: ??????????????????\n" @@ -4377,21 +4418,21 @@ msgid "Note: This key has expired!\n" msgstr "??: ??????????!\n" msgid "WARNING: This key is not certified with a trusted signature!\n" -msgstr "??: ?????????????????????!\n" +msgstr "*??*: ?????????????????????!\n" msgid "" " There is no indication that the signature belongs to the owner.\n" msgstr " ???????????????????????????\n" msgid "WARNING: We do NOT trust this key!\n" -msgstr "??: ???????????!\n" +msgstr "*??*: ???????????!\n" msgid " The signature is probably a FORGERY.\n" msgstr " ????????? ?? ???\n" msgid "" "WARNING: This key is not certified with sufficiently trusted signatures!\n" -msgstr "??: ????????????????????????!\n" +msgstr "*??*: ????????????????????????!\n" msgid " It is not certain that the signature belongs to the owner.\n" msgstr " ???????????????????????\n" @@ -4446,10 +4487,11 @@ msgstr "??: ?%s?? %s ?????????\n" #, c-format msgid "Note: key %s has no preference for %s\n" -msgstr "??: ?%s??%s????????????\n" +msgstr "??: ?%s??%s??????????????\n" msgid "data not saved; use option \"--output\" to save it\n" -msgstr "??????????????????\"--output\"?????????????\n" +msgstr "" +"??????????????????\"--output\"?????????????\n" msgid "Detached signature.\n" msgstr "?????\n" @@ -4487,14 +4529,14 @@ msgstr "????????%d%s??????????\n" #, c-format msgid "WARNING: cipher algorithm %s not found in recipient preferences\n" -msgstr "??: ????????%s???????????????\n" +msgstr "*??*: ????????%s?????????????????\n" #, c-format msgid "NOTE: secret key %s expired at %s\n" -msgstr "??: ???%s?%s??????????\n" +msgstr "*??*: ???%s?%s??????????\n" msgid "NOTE: key has been revoked" -msgstr "??: ????????" +msgstr "*??*: ????????" #, c-format msgid "build_packet failed: %s\n" @@ -4508,7 +4550,7 @@ msgid "To be revoked by:\n" msgstr "???:\n" msgid "(This is a sensitive revocation key)\n" -msgstr "(???????????????)\n" +msgstr "(??????????????)\n" msgid "Create a designated revocation certificate for this key? (y/N) " msgstr "??????????????????????? (y/N) " @@ -4545,7 +4587,7 @@ msgid "unknown protection algorithm\n" msgstr "?????????????\n" msgid "NOTE: This key is not protected!\n" -msgstr "??: ?????????????!\n" +msgstr "*??*: ?????????????!\n" msgid "" "Revocation certificate created.\n" @@ -4558,10 +4600,13 @@ msgid "" msgstr "" "?????????????\n" "\n" -"??????????????????????????????????????\n" +"????????????????????????????_??_???????" +"?\n" "?????????????????????????????\n" -"????????????????????????????????????????\n" -"???????????????????????????????????????\n" +"??????????????????????????????????????" +"??\n" +"??????????????????????????????????????" +"?\n" "????????????????!\n" msgid "Please select the reason for the revocation:\n" @@ -4606,7 +4651,7 @@ msgid "%s ...\n" msgstr "%s ...\n" msgid "WARNING: Weak key detected - please change passphrase again.\n" -msgstr "??: ???????????????????????????\n" +msgstr "*??*: ???????????????????????????\n" msgid "generating the deprecated 16-bit checksum for secret key protection\n" msgstr "?????16????????????????????\n" @@ -4630,15 +4675,15 @@ msgid "DSA key %s requires a %u bit or larger hash\n" msgstr "DSA? %s ?%u ???????????????????????\n" msgid "WARNING: signature digest conflict in message\n" -msgstr "??: ??????????????????????\n" +msgstr "*??*: ??????????????????????\n" #, c-format msgid "WARNING: signing subkey %s is not cross-certified\n" -msgstr "??: ????%s????????????\n" +msgstr "*??*: ????%s????????????\n" #, c-format msgid "WARNING: signing subkey %s has an invalid cross-certification\n" -msgstr "??: ?????????????%s?????\n" +msgstr "*??*: ?????????????%s?????\n" #, c-format msgid "public key %s is %lu second newer than the signature\n" @@ -4651,20 +4696,20 @@ msgstr "???%s???????%lu????????\n" #, c-format msgid "" "key %s was created %lu second in the future (time warp or clock problem)\n" -msgstr "?%s?%lu????????? (??????????????)\n" +msgstr "?%s?%lu????????? (??????????????)\n" #, c-format msgid "" "key %s was created %lu seconds in the future (time warp or clock problem)\n" -msgstr "?%s?%lu????????? (??????????????)\n" +msgstr "?%s?%lu????????? (??????????????)\n" #, c-format msgid "NOTE: signature key %s expired %s\n" -msgstr "??: ???%s?%s??????????\n" +msgstr "*??*: ???%s?%s??????????\n" #, c-format msgid "NOTE: signature key %s has been revoked\n" -msgstr "??: ? %s ???????\n" +msgstr "*??*: ? %s ???????\n" #, c-format msgid "assuming bad signature from key %s due to an unknown critical bit\n" @@ -4680,18 +4725,18 @@ msgstr "?%s: ?????????????????????\n #, c-format msgid "WARNING: unable to %%-expand notation (too large). Using unexpanded.\n" -msgstr "??: ???%%???? (????)????????\n" +msgstr "*??*: ???%%???? (????)?????????\n" #, c-format msgid "" "WARNING: unable to %%-expand policy URL (too large). Using unexpanded.\n" -msgstr "??: ????URL?%%???? (????)????????\n" +msgstr "*??*: ???URL?%%???? (????)?????????\n" #, c-format msgid "" "WARNING: unable to %%-expand preferred keyserver URL (too large). Using " "unexpanded.\n" -msgstr "??: ??????URL?%%???? (????)????????\n" +msgstr "*??*: ??????URL?%%???? (????)?????????\n" #, c-format msgid "checking created signature failed: %s\n" @@ -4707,7 +4752,9 @@ msgstr "--pgp2??????PGP 2.x????????????? #, c-format msgid "" "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n" -msgstr "??: ????????????? %s (%d) ?????????????????\n" +msgstr "" +"*??*: ????????????? %s (%d) ?????????????????" +"??\n" msgid "signing:" msgstr "??:" @@ -4740,7 +4787,7 @@ msgstr "???PGP?????Elgamal???????????? #, c-format msgid "trust record %lu, type %d: write failed: %s\n" -msgstr "??????%lu, ?%d: ??????????: %s\n" +msgstr "??????%lu, ?%d: ???????????: %s\n" #, c-format msgid "" @@ -4772,7 +4819,7 @@ msgstr "?%s??????????????: %s\n" #, c-format msgid "read error in `%s': %s\n" -msgstr "?%s????????: %s\n" +msgstr "?%s?????????: %s\n" #, c-format msgid "trustdb: sync failed: %s\n" @@ -4784,7 +4831,7 @@ msgstr "???????? ????%lu: ?????????? #, c-format msgid "trustdb rec %lu: write failed (n=%d): %s\n" -msgstr "???????? ????%lu: ?????????? (n=%d): %s\n" +msgstr "???????? ????%lu: ??????????? (n=%d): %s\n" msgid "trustdb transaction too large\n" msgstr "????????????????????????\n" @@ -4818,7 +4865,7 @@ msgid "%s: trustdb created\n" msgstr "%s: ??????????????\n" msgid "NOTE: trustdb not writable\n" -msgstr "??: ?????????????????\n" +msgstr "*??*: ??????????????????\n" #, c-format msgid "%s: invalid trustdb\n" @@ -4838,7 +4885,7 @@ msgstr "%s: ??????????????????: %s\n" #, c-format msgid "%s: error writing version record: %s\n" -msgstr "%s: ?????????????????: %s\n" +msgstr "%s: ??????????????????: %s\n" #, c-format msgid "trustdb: lseek failed: %s\n" @@ -4846,7 +4893,7 @@ msgstr "????????: ??????????: %s\n" #, c-format msgid "trustdb: read failed (n=%d): %s\n" -msgstr "????????: ?????????? (n=%d): %s\n" +msgstr "????????: ??????????? (n=%d): %s\n" #, c-format msgid "%s: not a trustdb file\n" @@ -4866,7 +4913,7 @@ msgstr "%s: ??????????????: %s\n" #, c-format msgid "%s: error writing dir record: %s\n" -msgstr "%s: ???????????????????: %s\n" +msgstr "%s: ????????????????????: %s\n" #, c-format msgid "%s: failed to zero a record: %s\n" @@ -4909,7 +4956,7 @@ msgstr "?%s?????????????????\n" #, c-format msgid "trust record %lu, req type %d: read failed: %s\n" -msgstr "??????%lu, ??????%d: ??????????: %s\n" +msgstr "??????%lu, ??????%d: ???????????: %s\n" #, c-format msgid "trust record %lu is not of requested type %d\n" @@ -4929,6 +4976,14 @@ msgstr "???????? (%d) ?????? - %s?????? msgid "using %s trust model\n" msgstr "%s????????\n" +#. TRANSLATORS: these strings are similar to those in +#. trust_value_to_string(), but are a fixed length. This is needed to +#. make attractive information listings where columns line up +#. properly. The value "10" should be the length of the strings you +#. choose to translate to. This is the length in printable columns. +#. It gets passed to atoi() so everything after the number is +#. essentially a comment and need not be translated. Either key and +#. uid are both NULL, or neither are NULL. msgid "10 translator see trustdb.c:uid_trust_string_fixed" msgstr "10" @@ -5016,7 +5071,7 @@ msgstr "??: %d ???: %3d ??: %3d ??: %d-, %dq, %dn, %dm, %df #, c-format msgid "unable to update trustdb version record: write failed: %s\n" msgstr "" -"???????????????????????????: ?????????" +"???????????????????????????: ??????????" "?: %s\n" msgid "" @@ -5040,7 +5095,7 @@ msgid "argument not expected" msgstr "????????????" msgid "read error" -msgstr "??????" +msgstr "???????" msgid "keyword too long" msgstr "???????????" @@ -5113,7 +5168,7 @@ msgstr "???????%s?????????: %s\n" #, c-format msgid "error writing to `%s': %s\n" -msgstr "?%s????????: %s\n" +msgstr "?%s?????????: %s\n" #, c-format msgid "removing stale lockfile (created by %d)\n" @@ -5148,7 +5203,7 @@ msgstr "???: kbxutil [?????] [????] (???? -h)" msgid "" "Syntax: kbxutil [options] [files]\n" -"list, export, import Keybox data\n" +"List, export, import Keybox data\n" msgstr "" "??: kbxutil [?????] [????]\n" "Keybox???????????????????\n" @@ -5181,22 +5236,22 @@ msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys." msgstr "|P|?????PIN Unblocking Code (PUK)??????????" msgid "|N|Please enter a new PIN for the key to create qualified signatures." -msgstr "|N|???PIN??????????????????????" +msgstr "|N|???PIN????????????????????????" msgid "||Please enter the PIN for the key to create qualified signatures." -msgstr "||???PIN??????????????????????" +msgstr "||???PIN????????????????????????" msgid "" "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create " "qualified signatures." msgstr "" -"|NP|???????????PIN?????????(PUK)??????????" +"|NP|?????????????PIN?????????(PUK)??????????" msgid "" "|P|Please enter the PIN Unblocking Code (PUK) for the key to create " "qualified signatures." msgstr "" -"|P|???????????PIN?????????(PUK)??????????" +"|P|?????????????PIN?????????(PUK)??????????" #, c-format msgid "error getting new PIN: %s\n" @@ -5229,7 +5284,9 @@ msgstr "?????PIN?%s???????\n" #, c-format msgid "failed to use default PIN as %s: %s - disabling further default use\n" -msgstr "??????PIN %s ???????????: %s - ??????????????????????\n" +msgstr "" +"??????PIN %s ???????????: %s - ??????????????" +"????????\n" #, c-format msgid "||Please enter the PIN%%0A[sigs done: %lu]" @@ -5240,14 +5297,14 @@ msgstr "||PIN?????????" #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" -msgstr "CHV%d?PIN??????????%d\n" +msgstr "CHV%d?PIN??????????%d??\n" #, c-format msgid "verify CHV%d failed: %s\n" -msgstr "CHV%d??????????: %s\n" +msgstr "CHV%d??????????: %s\n" msgid "error retrieving CHV status from card\n" -msgstr "??????CHV?????????\n" +msgstr "??????CHV???????????\n" msgid "card is permanently locked!\n" msgstr "??????????????!\n" @@ -5263,7 +5320,7 @@ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" msgstr "|A|???PIN?????????%%0A[????: %d]" msgid "|A|Please enter the Admin PIN" -msgstr "|A|???PI??????????" +msgstr "|A|???PIN?????????" msgid "access to admin commands is not configured\n" msgstr "??????????????????????\n" @@ -5275,6 +5332,9 @@ msgstr "||????Reset Code?????????" msgid "Reset Code is too short; minimum length is %d\n" msgstr "Reset Code?????????????%d???\n" +#. TRANSLATORS: Do not translate the "|*|" prefixes but +#. keep it at the start of the string. We need this elsewhere +#. to get some infos on the string. msgid "|RN|New Reset Code" msgstr "|RN|???Reset Code" @@ -5300,13 +5360,13 @@ msgid "key already exists\n" msgstr "????????\n" msgid "existing key will be replaced\n" -msgstr "???????????\n" +msgstr "?????????????\n" msgid "generating new key\n" msgstr "???????\n" msgid "writing new key\n" -msgstr "????????\n" +msgstr "?????????\n" msgid "creation timestamp missing\n" msgstr "??????????????\n" @@ -5345,8 +5405,7 @@ msgstr "????????????: %lu\n" msgid "" "verification of Admin PIN is currently prohibited through this command\n" -msgstr "" -"???PIN?????????????????????????\n" +msgstr "???PIN?????????????????????????\n" #, c-format msgid "can't access %s - invalid OpenPGP card?\n" @@ -5368,7 +5427,7 @@ msgid "|LEVEL|set the debugging level to LEVEL" msgstr "|LEVEL|?????????LEVEL????" msgid "|FILE|write a log to FILE" -msgstr "|FILE|FILE????????" +msgstr "|FILE|FILE??????????" msgid "|N|connect to reader at port N" msgstr "|N|???N??????????" @@ -5402,7 +5461,9 @@ msgstr "" "GnuPG?Smartcard????\n" msgid "please use the option `--daemon' to run the program in the background\n" -msgstr "\"--daemon\"?????????????????????????????????\n" +msgstr "" +"\"--daemon\"????????????????????????????????" +"?\n" #, c-format msgid "handler for fd %d started\n" @@ -5482,7 +5543,7 @@ msgstr "??????????: %d\n" msgid "dirmngr cache-only key lookup failed: %s\n" msgstr "dirmngr???????????????????: %s\n" -msgid "failed to allocated keyDB handle\n" +msgid "failed to allocate keyDB handle\n" msgstr "keyDB??????????????\n" msgid "certificate has been revoked" @@ -5556,19 +5617,22 @@ msgid "root certificate has now been marked as trusted\n" msgstr "??????????????????????\n" msgid "interactive marking as trusted not enabled in gpg-agent\n" -msgstr "??????????????????????gpg-agent???????????\n" +msgstr "" +"??????????????????????gpg-agent???????????\n" msgid "interactive marking as trusted disabled for this session\n" -msgstr "????????????????????????????????????????\n" +msgstr "" +"??????????????????????????????????????" +"??\n" msgid "WARNING: creation time of signature not known - assuming current time" -msgstr "??: ???????????? - ??????????" +msgstr "*??*: ???????????? - ??????????" msgid "no issuer found in certificate" msgstr "?????????????" msgid "self-signed certificate has a BAD signature" -msgstr "??????????????????" +msgstr "????????*???*???????" msgid "root certificate is not marked trusted" msgstr "???????????????????????" @@ -5584,7 +5648,7 @@ msgid "issuer certificate not found" msgstr "??????????????" msgid "certificate has a BAD signature" -msgstr "??????????????" +msgstr "????*???*???????" msgid "found another possible matching CA certificate - trying again" msgstr "????????????CA??????????? - ??????" @@ -5643,7 +5707,8 @@ msgid "" "S/N %s, ID 0x%08lX,\n" "created %s, expires %s.\n" msgstr "" -"X.509?????????????????????????????????????:\n" +"X.509????????????????????????????????????" +"?:\n" "\"%s\"\n" "S/N %s, ID 0x%08lX,\n" "?? %s, ???? %s.\n" @@ -5655,16 +5720,16 @@ msgstr "??????????????? - ???????? msgid "error getting key usage information: %s\n" msgstr "???????????: %s\n" -msgid "certificate should have not been used for certification\n" +msgid "certificate should not have been used for certification\n" msgstr "??????????????????????????\n" -msgid "certificate should have not been used for OCSP response signing\n" +msgid "certificate should not have been used for OCSP response signing\n" msgstr "????OCSP?????????????????????????\n" -msgid "certificate should have not been used for encryption\n" +msgid "certificate should not have been used for encryption\n" msgstr "???????????????????????????\n" -msgid "certificate should have not been used for signing\n" +msgid "certificate should not have been used for signing\n" msgstr "??????????????????????????\n" msgid "certificate is not usable for encryption\n" @@ -5713,7 +5778,8 @@ msgid "" "To complete this certificate request please enter the passphrase for the key " "you just created once more.\n" msgstr "" -"?????????????????????????????????????????\n" +"??????????????????????????????????????" +"???\n" #, c-format msgid " (%d) RSA\n" @@ -5899,10 +5965,10 @@ msgid "don't use the terminal at all" msgstr "???????????" msgid "|FILE|write a server mode log to FILE" -msgstr "|FILE|???????????FILE?????" +msgstr "|FILE|???????????FILE?????" msgid "|FILE|write an audit log to FILE" -msgstr "|FILE|?????FILE?????" +msgstr "|FILE|?????FILE?????" msgid "batch mode: never ask" msgstr "???????: ??????????????" @@ -5933,8 +5999,8 @@ msgstr "???: gpgsm [?????] [????] (???? -h)" msgid "" "Syntax: gpgsm [options] [files]\n" -"sign, check, encrypt or decrypt using the S/MIME protocol\n" -"default operation depends on the input data\n" +"Sign, check, encrypt or decrypt using the S/MIME protocol\n" +"Default operation depends on the input data\n" msgstr "" "??: gpgsm [?????] [????]\n" "S/MIME???????????????????????????\n" @@ -5945,7 +6011,7 @@ msgstr "???: gpgsm [?????] " #, c-format msgid "NOTE: won't be able to encrypt to `%s': %s\n" -msgstr "??:?%s?????????????: %s\n" +msgstr "*??*:?%s?????????????: %s\n" #, c-format msgid "unknown validation model `%s'\n" @@ -5967,7 +6033,7 @@ msgid "could not parse keyserver\n" msgstr "?????URL?????\n" msgid "WARNING: running with faked system time: " -msgstr "??: ???????????????????: " +msgstr "*??*: ???????????????????: " #, c-format msgid "importing common certificates `%s'\n" @@ -5990,9 +6056,6 @@ msgstr "?????????????\n" msgid "basic certificate checks failed - not imported\n" msgstr "???????????????? - ?????????????\n" -msgid "failed to allocate keyDB handle\n" -msgstr "keyDB??????????????\n" - #, c-format msgid "error getting stored flags: %s\n" msgstr "??????????????: %s\n" @@ -6025,7 +6088,7 @@ msgstr "????????????: %s\n" #, c-format msgid "error finding writable keyDB: %s\n" -msgstr "?????keyDB??????: %s\n" +msgstr "??????keyDB??????: %s\n" #, c-format msgid "error storing certificate: %s\n" @@ -6043,7 +6106,7 @@ msgid "Error - " msgstr "??? - " msgid "GPG_TTY has not been set - using maybe bogus default\n" -msgstr "GPG_TTY ?????????? - ?????????????\n" +msgstr "GPG_TTY ?????????? - ???????????????\n" #, c-format msgid "invalid formatted fingerprint in `%s', line %d\n" @@ -6062,7 +6125,8 @@ msgid "" "\n" "%s%sAre you really sure that you want to do this?" msgstr "" -"????????????????????????????:\n:\n" +"??????????????????????????????:\n" +":\n" "\"%s\"\n" "???????????????????????????????\n" "\n" @@ -6072,8 +6136,8 @@ msgid "" "Note, that this software is not officially approved to create or verify such " "signatures.\n" msgstr "" -"????????????????????????????????????" -"??????????????????????\n" +"??????????????????????????????????????" +"????????????????????\n" #, c-format msgid "" @@ -6081,13 +6145,15 @@ msgid "" "\"%s\"\n" "Note, that this certificate will NOT create a qualified signature!" msgstr "" -"????????????????????????????:\n" +"??????????????????????????????:\n" "\"%s\"\n" "????????: ???????????????????????!" #, c-format msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n" -msgstr "??????????? %d (%s)(??? %d ?)?????????????%s ?????\n" +msgstr "" +"??????????? %d (%s)(??? %d ?)?????????????%s ??" +"???\n" #, c-format msgid "hash algorithm used for signer %d: %s (%s)\n" @@ -6095,7 +6161,7 @@ msgstr "??? %d??????????????????: %s ( #, c-format msgid "checking for qualified certificate failed: %s\n" -msgstr "????????????????: %s\n" +msgstr "??????????????????: %s\n" msgid "Signature made " msgstr "?????? " @@ -6119,7 +6185,7 @@ msgid " aka" msgstr " ??" msgid "This is a qualified signature\n" -msgstr "??????????\n" +msgstr "?????????\n" msgid "quiet" msgstr "?????" @@ -6199,7 +6265,7 @@ msgid "Options useful for debugging" msgstr "????????????????" msgid "|FILE|write server mode logs to FILE" -msgstr "|FILE|FILE????????????????" +msgstr "|FILE|FILE????????????????" msgid "Options controlling the security" msgstr "????????????????" @@ -6223,7 +6289,8 @@ msgid "|N|set minimal required length for new passphrases to N" msgstr "|N|???????????????????N???" msgid "|N|require at least N non-alpha characters for a new passphrase" -msgstr "|N|??????????????????????????????N?????" +msgstr "" +"|N|??????????????????????????????N?????" msgid "|FILE|check new passphrases against pattern in FILE" msgstr "|FILE|??????????FILE???????????????" @@ -6382,8 +6449,8 @@ msgid "" "[options...] COMMAND [inputfile]\n" "Call a simple symmetric encryption tool\n" msgstr "" -"??: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE " -"[?????...] COMMAND [??????]\n" +"??: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE [????" +"?...] COMMAND [??????]\n" "??????????????????\n" #, c-format @@ -6404,7 +6471,7 @@ msgstr "%s??????????????????: %s\n" #, c-format msgid "error writing to %s: %s\n" -msgstr "?%s????????: %s\n" +msgstr "?%s?????????: %s\n" #, c-format msgid "error reading from %s: %s\n" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 631 ++++++++++++++++++++++++++++++++++---------------------------- 1 files changed, 349 insertions(+), 282 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org