From cvs at cvs.gnupg.org Tue Dec 2 12:38:43 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 02 Dec 2008 12:38:43 +0100 Subject: [svn] gcry - r1363 - in trunk: cipher mpi Message-ID: Author: wk Date: 2008-12-02 12:38:43 +0100 (Tue, 02 Dec 2008) New Revision: 1363 Modified: trunk/cipher/dsa.c trunk/mpi/ChangeLog trunk/mpi/mpi-pow.c Log: Re-indented some code. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2008-11-28 19:10:15 UTC (rev 1362) +++ trunk/mpi/ChangeLog 2008-12-02 11:38:43 UTC (rev 1363) @@ -1,3 +1,7 @@ +2008-12-02 Werner Koch + + * mpi-pow.c (gcry_mpi_powm): Re-indent. + 2008-08-20 Werner Koch * mpi-bit.c (gcry_mpi_lshift): Actually implement. Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-11-28 19:10:15 UTC (rev 1362) +++ trunk/cipher/dsa.c 2008-12-02 11:38:43 UTC (rev 1363) @@ -15,8 +15,7 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * License along with this program; if not, see . */ #include Modified: trunk/mpi/mpi-pow.c =================================================================== --- trunk/mpi/mpi-pow.c 2008-11-28 19:10:15 UTC (rev 1362) +++ trunk/mpi/mpi-pow.c 2008-12-02 11:38:43 UTC (rev 1363) @@ -1,5 +1,6 @@ -/* mpi-pow.c - MPI functions - * Copyright (C) 1994, 1996, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. +/* mpi-pow.c - MPI functions for exponentiation + * Copyright (C) 1994, 1996, 1998, 2000, 2002 + * 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -14,8 +15,7 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * License along with this program; if not, see . * * Note: This code is heavily based on the GNU MP Library. * Actually it's the same code with only minor changes in the @@ -37,265 +37,298 @@ * RES = BASE ^ EXPO mod MOD */ void -gcry_mpi_powm( gcry_mpi_t res, gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod) +gcry_mpi_powm (gcry_mpi_t res, + gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod) { - mpi_ptr_t rp, ep, mp, bp; - mpi_size_t esize, msize, bsize, rsize; - int msign, bsign, rsign; - int esec, msec, bsec, rsec; - mpi_size_t size; - int mod_shift_cnt; - int negative_result; - mpi_ptr_t mp_marker=NULL, bp_marker=NULL, ep_marker=NULL; - mpi_ptr_t xp_marker=NULL; - unsigned int mp_nlimbs = 0, bp_nlimbs = 0, ep_nlimbs = 0; - unsigned int xp_nlimbs = 0; - int assign_rp = 0; - mpi_ptr_t tspace = NULL; - mpi_size_t tsize=0; /* to avoid compiler warning */ - /* fixme: we should check that the warning is void*/ + mpi_ptr_t rp, ep, mp, bp; + mpi_size_t esize, msize, bsize, rsize; + int msign, bsign, rsign; + int esec, msec, bsec, rsec; + mpi_size_t size; + int mod_shift_cnt; + int negative_result; + mpi_ptr_t mp_marker = NULL; + mpi_ptr_t bp_marker = NULL; + mpi_ptr_t ep_marker = NULL; + mpi_ptr_t xp_marker = NULL; + unsigned int mp_nlimbs = 0; + unsigned int bp_nlimbs = 0; + unsigned int ep_nlimbs = 0; + unsigned int xp_nlimbs = 0; + int assign_rp = 0; + mpi_ptr_t tspace = NULL; + mpi_size_t tsize = 0; - esize = expo->nlimbs; - msize = mod->nlimbs; - size = 2 * msize; - msign = mod->sign; - esec = mpi_is_secure(expo); - msec = mpi_is_secure(mod); - bsec = mpi_is_secure(base); - rsec = mpi_is_secure(res); + esize = expo->nlimbs; + msize = mod->nlimbs; + size = 2 * msize; + msign = mod->sign; + + esec = mpi_is_secure(expo); + msec = mpi_is_secure(mod); + bsec = mpi_is_secure(base); + rsec = mpi_is_secure(res); - rp = res->d; - ep = expo->d; + rp = res->d; + ep = expo->d; - if( !msize ) - msize = 1 / msize; /* provoke a signal */ + if (!msize) + msize = 1 / msize; /* Provoke a signal. */ - if( !esize ) { - /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 - * depending on if MOD equals 1. */ - rp[0] = 1; - res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1; - res->sign = 0; - goto leave; + if (!esize) + { + /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending + on if MOD equals 1. */ + rp[0] = 1; + res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1; + res->sign = 0; + goto leave; } - /* Normalize MOD (i.e. make its most significant bit set) as required by - * mpn_divrem. This will make the intermediate values in the calculation - * slightly larger, but the correct result is obtained after a final - * reduction using the original MOD value. */ - mp_nlimbs = msec? msize:0; - mp = mp_marker = mpi_alloc_limb_space(msize, msec); - count_leading_zeros( mod_shift_cnt, mod->d[msize-1] ); - if( mod_shift_cnt ) - _gcry_mpih_lshift( mp, mod->d, msize, mod_shift_cnt ); - else - MPN_COPY( mp, mod->d, msize ); + /* Normalize MOD (i.e. make its most significant bit set) as + required by mpn_divrem. This will make the intermediate values + in the calculation slightly larger, but the correct result is + obtained after a final reduction using the original MOD value. */ + mp_nlimbs = msec? msize:0; + mp = mp_marker = mpi_alloc_limb_space(msize, msec); + count_leading_zeros (mod_shift_cnt, mod->d[msize-1]); + if (mod_shift_cnt) + _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt); + else + MPN_COPY( mp, mod->d, msize ); - bsize = base->nlimbs; - bsign = base->sign; - if( bsize > msize ) { /* The base is larger than the module. Reduce it. */ - /* Allocate (BSIZE + 1) with space for remainder and quotient. - * (The quotient is (bsize - msize + 1) limbs.) */ - bp_nlimbs = bsec ? (bsize + 1):0; - bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec ); - MPN_COPY( bp, base->d, bsize ); - /* We don't care about the quotient, store it above the remainder, - * at BP + MSIZE. */ - _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize ); - bsize = msize; - /* Canonicalize the base, since we are going to multiply with it - * quite a few times. */ - MPN_NORMALIZE( bp, bsize ); + bsize = base->nlimbs; + bsign = base->sign; + if (bsize > msize) + { + /* The base is larger than the module. Reduce it. + + Allocate (BSIZE + 1) with space for remainder and quotient. + (The quotient is (bsize - msize + 1) limbs.) */ + bp_nlimbs = bsec ? (bsize + 1):0; + bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec ); + MPN_COPY ( bp, base->d, bsize ); + /* We don't care about the quotient, store it above the + * remainder, at BP + MSIZE. */ + _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize ); + bsize = msize; + /* Canonicalize the base, since we are going to multiply with it + quite a few times. */ + MPN_NORMALIZE( bp, bsize ); } - else - bp = base->d; + else + bp = base->d; - if( !bsize ) { - res->nlimbs = 0; - res->sign = 0; - goto leave; + if (!bsize) + { + res->nlimbs = 0; + res->sign = 0; + goto leave; } - if( res->alloced < size ) { - /* We have to allocate more space for RES. If any of the input - * parameters are identical to RES, defer deallocation of the old - * space. */ - if( rp == ep || rp == mp || rp == bp ) { + if (res->alloced < size) + { + /* We have to allocate more space for RES. If any of the input + parameters are identical to RES, defer deallocation of the + old space. */ + if ( rp == ep || rp == mp || rp == bp ) + { rp = mpi_alloc_limb_space( size, rsec ); assign_rp = 1; - } - else { + } + else + { mpi_resize( res, size ); rp = res->d; - } + } } - else { /* Make BASE, EXPO and MOD not overlap with RES. */ - if( rp == bp ) { - /* RES and BASE are identical. Allocate temp. space for BASE. */ - gcry_assert (!bp_marker); - bp_nlimbs = bsec? bsize:0; - bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); - MPN_COPY(bp, rp, bsize); + else + { + /* Make BASE, EXPO and MOD not overlap with RES. */ + if ( rp == bp ) + { + /* RES and BASE are identical. Allocate temp. space for BASE. */ + gcry_assert (!bp_marker); + bp_nlimbs = bsec? bsize:0; + bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); + MPN_COPY(bp, rp, bsize); } - if( rp == ep ) { - /* RES and EXPO are identical. Allocate temp. space for EXPO. */ - ep_nlimbs = esec? esize:0; - ep = ep_marker = mpi_alloc_limb_space( esize, esec ); - MPN_COPY(ep, rp, esize); + if ( rp == ep ) + { + /* RES and EXPO are identical. Allocate temp. space for EXPO. */ + ep_nlimbs = esec? esize:0; + ep = ep_marker = mpi_alloc_limb_space( esize, esec ); + MPN_COPY(ep, rp, esize); } - if( rp == mp ) { - /* RES and MOD are identical. Allocate temporary space for MOD.*/ - gcry_assert (!mp_marker); - mp_nlimbs = msec?msize:0; - mp = mp_marker = mpi_alloc_limb_space( msize, msec ); - MPN_COPY(mp, rp, msize); + if ( rp == mp ) + { + /* RES and MOD are identical. Allocate temporary space for MOD.*/ + gcry_assert (!mp_marker); + mp_nlimbs = msec?msize:0; + mp = mp_marker = mpi_alloc_limb_space( msize, msec ); + MPN_COPY(mp, rp, msize); } } + + MPN_COPY ( rp, bp, bsize ); + rsize = bsize; + rsign = bsign; + + { + mpi_size_t i; + mpi_ptr_t xp; + int c; + mpi_limb_t e; + mpi_limb_t carry_limb; + struct karatsuba_ctx karactx; + + xp_nlimbs = msec? (2 * (msize + 1)):0; + xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); + + memset( &karactx, 0, sizeof karactx ); + negative_result = (ep[0] & 1) && base->sign; + + i = esize - 1; + e = ep[i]; + count_leading_zeros (c, e); + e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */ + c = BITS_PER_MPI_LIMB - 1 - c; - MPN_COPY( rp, bp, bsize ); - rsize = bsize; - rsign = bsign; + /* Main loop. + + Make the result be pointed to alternately by XP and RP. This + helps us avoid block copying, which would otherwise be + necessary with the overlap restrictions of + _gcry_mpih_divmod. With 50% probability the result after this + loop will be in the area originally pointed by RP (==RES->d), + and with 50% probability in the area originally pointed to by XP. */ + for (;;) + { + while (c) + { + mpi_ptr_t tp; + mpi_size_t xsize; + + /*mpih_mul_n(xp, rp, rp, rsize);*/ + if ( rsize < KARATSUBA_THRESHOLD ) + _gcry_mpih_sqr_n_basecase( xp, rp, rsize ); + else + { + if ( !tspace ) + { + tsize = 2 * rsize; + tspace = mpi_alloc_limb_space( tsize, 0 ); + } + else if ( tsize < (2*rsize) ) + { + _gcry_mpi_free_limb_space (tspace, 0); + tsize = 2 * rsize; + tspace = mpi_alloc_limb_space (tsize, 0 ); + } + _gcry_mpih_sqr_n (xp, rp, rsize, tspace); + } - { - mpi_size_t i; - mpi_ptr_t xp; - int c; - mpi_limb_t e; - mpi_limb_t carry_limb; - struct karatsuba_ctx karactx; + xsize = 2 * rsize; + if ( xsize > msize ) + { + _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); + xsize = msize; + } - xp_nlimbs = msec? (2 * (msize + 1)):0; - xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); + tp = rp; rp = xp; xp = tp; + rsize = xsize; - memset( &karactx, 0, sizeof karactx ); - negative_result = (ep[0] & 1) && base->sign; + if ( (mpi_limb_signed_t)e < 0 ) + { + /*mpih_mul( xp, rp, rsize, bp, bsize );*/ + if( bsize < KARATSUBA_THRESHOLD ) + _gcry_mpih_mul ( xp, rp, rsize, bp, bsize ); + else + _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize, + &karactx); + + xsize = rsize + bsize; + if ( xsize > msize ) + { + _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); + xsize = msize; + } + + tp = rp; rp = xp; xp = tp; + rsize = xsize; + } + e <<= 1; + c--; + } - i = esize - 1; - e = ep[i]; - count_leading_zeros (c, e); - e = (e << c) << 1; /* shift the expo bits to the left, lose msb */ - c = BITS_PER_MPI_LIMB - 1 - c; + i--; + if ( i < 0 ) + break; + e = ep[i]; + c = BITS_PER_MPI_LIMB; + } - /* Main loop. - * - * Make the result be pointed to alternately by XP and RP. This - * helps us avoid block copying, which would otherwise be necessary - * with the overlap restrictions of _gcry_mpih_divmod. With 50% probability - * the result after this loop will be in the area originally pointed - * by RP (==RES->d), and with 50% probability in the area originally - * pointed to by XP. - */ + /* We shifted MOD, the modulo reduction argument, left + MOD_SHIFT_CNT steps. Adjust the result by reducing it with the + original MOD. - for(;;) { - while( c ) { - mpi_ptr_t tp; - mpi_size_t xsize; + Also make sure the result is put in RES->d (where it already + might be, see above). */ + if ( mod_shift_cnt ) + { + carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt); + rp = res->d; + if ( carry_limb ) + { + rp[rsize] = carry_limb; + rsize++; + } + } + else + { + MPN_COPY( res->d, rp, rsize); + rp = res->d; + } - /*mpih_mul_n(xp, rp, rp, rsize);*/ - if( rsize < KARATSUBA_THRESHOLD ) - _gcry_mpih_sqr_n_basecase( xp, rp, rsize ); - else { - if( !tspace ) { - tsize = 2 * rsize; - tspace = mpi_alloc_limb_space( tsize, 0 ); - } - else if( tsize < (2*rsize) ) { - _gcry_mpi_free_limb_space (tspace, 0); - tsize = 2 * rsize; - tspace = mpi_alloc_limb_space( tsize, 0 ); - } - _gcry_mpih_sqr_n( xp, rp, rsize, tspace ); - } + if ( rsize >= msize ) + { + _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize); + rsize = msize; + } - xsize = 2 * rsize; - if( xsize > msize ) { - _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); - xsize = msize; - } + /* Remove any leading zero words from the result. */ + if ( mod_shift_cnt ) + _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt); + MPN_NORMALIZE (rp, rsize); + + _gcry_mpih_release_karatsuba_ctx (&karactx ); + } - tp = rp; rp = xp; xp = tp; - rsize = xsize; - - if( (mpi_limb_signed_t)e < 0 ) { - /*mpih_mul( xp, rp, rsize, bp, bsize );*/ - if( bsize < KARATSUBA_THRESHOLD ) { - _gcry_mpih_mul( xp, rp, rsize, bp, bsize ); - } - else { - _gcry_mpih_mul_karatsuba_case( - xp, rp, rsize, bp, bsize, &karactx ); - } - - xsize = rsize + bsize; - if( xsize > msize ) { - _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); - xsize = msize; - } - - tp = rp; rp = xp; xp = tp; - rsize = xsize; - } - e <<= 1; - c--; - } - - i--; - if( i < 0 ) - break; - e = ep[i]; - c = BITS_PER_MPI_LIMB; - } - - /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT - * steps. Adjust the result by reducing it with the original MOD. - * - * Also make sure the result is put in RES->d (where it already - * might be, see above). - */ - if( mod_shift_cnt ) { - carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt); - rp = res->d; - if( carry_limb ) { - rp[rsize] = carry_limb; - rsize++; - } - } - else { - MPN_COPY( res->d, rp, rsize); - rp = res->d; - } - - if( rsize >= msize ) { - _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize); - rsize = msize; - } - - /* Remove any leading zero words from the result. */ - if( mod_shift_cnt ) - _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt); - MPN_NORMALIZE (rp, rsize); - - _gcry_mpih_release_karatsuba_ctx( &karactx ); + if ( negative_result && rsize ) + { + if ( mod_shift_cnt ) + _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt); + _gcry_mpih_sub( rp, mp, msize, rp, rsize); + rsize = msize; + rsign = msign; + MPN_NORMALIZE(rp, rsize); } - - if( negative_result && rsize ) { - if( mod_shift_cnt ) - _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt); - _gcry_mpih_sub( rp, mp, msize, rp, rsize); - rsize = msize; - rsign = msign; - MPN_NORMALIZE(rp, rsize); - } - res->nlimbs = rsize; - res->sign = rsign; - - leave: - if( assign_rp ) _gcry_mpi_assign_limb_space( res, rp, size ); - if( mp_marker ) _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs ); - if( bp_marker ) _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs ); - if( ep_marker ) _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs ); - if( xp_marker ) _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs ); - if( tspace ) _gcry_mpi_free_limb_space( tspace, 0 ); + res->nlimbs = rsize; + res->sign = rsign; + + leave: + if (assign_rp) + _gcry_mpi_assign_limb_space( res, rp, size ); + if (mp_marker) + _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs ); + if (bp_marker) + _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs ); + if (ep_marker) + _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs ); + if (xp_marker) + _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs ); + if (tspace) + _gcry_mpi_free_limb_space( tspace, 0 ); } From cvs at cvs.gnupg.org Tue Dec 2 13:39:01 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 02 Dec 2008 13:39:01 +0100 Subject: [svn] gcry - r1364 - in trunk: mpi tests Message-ID: Author: wk Date: 2008-12-02 13:39:01 +0100 (Tue, 02 Dec 2008) New Revision: 1364 Modified: trunk/mpi/ChangeLog trunk/mpi/mpi-pow.c trunk/tests/ChangeLog trunk/tests/mpitests.c Log: Fix bug 977. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2008-12-02 11:38:43 UTC (rev 1363) +++ trunk/mpi/ChangeLog 2008-12-02 12:39:01 UTC (rev 1364) @@ -1,6 +1,8 @@ 2008-12-02 Werner Koch * mpi-pow.c (gcry_mpi_powm): Re-indent. + (gcry_mpi_powm): Simplified allocation of the result to fix a + double free bug. This is bug#977. Reported by Haakon Ringberg. 2008-08-20 Werner Koch Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-02 11:38:43 UTC (rev 1363) +++ trunk/tests/ChangeLog 2008-12-02 12:39:01 UTC (rev 1364) @@ -1,3 +1,7 @@ +2008-12-02 Werner Koch + + * mpitests.c (mpi_powm): New. + 2008-11-28 Werner Koch * fips186-dsa.c: New. Modified: trunk/mpi/mpi-pow.c =================================================================== --- trunk/mpi/mpi-pow.c 2008-12-02 11:38:43 UTC (rev 1363) +++ trunk/mpi/mpi-pow.c 2008-12-02 12:39:01 UTC (rev 1364) @@ -40,11 +40,15 @@ gcry_mpi_powm (gcry_mpi_t res, gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod) { + /* Pointer to the limbs of the arguments, their size and signs. */ mpi_ptr_t rp, ep, mp, bp; mpi_size_t esize, msize, bsize, rsize; int msign, bsign, rsign; - int esec, msec, bsec, rsec; + /* Flags telling the secure allocation status of the arguments. */ + int esec, msec, bsec, rsec; + /* Size of the result including space for temporary values. */ mpi_size_t size; + /* Helper. */ int mod_shift_cnt; int negative_result; mpi_ptr_t mp_marker = NULL; @@ -55,7 +59,6 @@ unsigned int bp_nlimbs = 0; unsigned int ep_nlimbs = 0; unsigned int xp_nlimbs = 0; - int assign_rp = 0; mpi_ptr_t tspace = NULL; mpi_size_t tsize = 0; @@ -127,54 +130,43 @@ goto leave; } - if (res->alloced < size) + + /* Make BASE, EXPO and MOD not overlap with RES. */ + if ( rp == bp ) { - /* We have to allocate more space for RES. If any of the input - parameters are identical to RES, defer deallocation of the - old space. */ - if ( rp == ep || rp == mp || rp == bp ) - { - rp = mpi_alloc_limb_space( size, rsec ); - assign_rp = 1; - } - else - { - mpi_resize( res, size ); - rp = res->d; - } + /* RES and BASE are identical. Allocate temp. space for BASE. */ + gcry_assert (!bp_marker); + bp_nlimbs = bsec? bsize:0; + bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); + MPN_COPY(bp, rp, bsize); } - else - { - /* Make BASE, EXPO and MOD not overlap with RES. */ - if ( rp == bp ) - { - /* RES and BASE are identical. Allocate temp. space for BASE. */ - gcry_assert (!bp_marker); - bp_nlimbs = bsec? bsize:0; - bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); - MPN_COPY(bp, rp, bsize); - } - if ( rp == ep ) - { - /* RES and EXPO are identical. Allocate temp. space for EXPO. */ - ep_nlimbs = esec? esize:0; - ep = ep_marker = mpi_alloc_limb_space( esize, esec ); - MPN_COPY(ep, rp, esize); - } - if ( rp == mp ) - { - /* RES and MOD are identical. Allocate temporary space for MOD.*/ - gcry_assert (!mp_marker); - mp_nlimbs = msec?msize:0; - mp = mp_marker = mpi_alloc_limb_space( msize, msec ); - MPN_COPY(mp, rp, msize); - } + if ( rp == ep ) + { + /* RES and EXPO are identical. Allocate temp. space for EXPO. */ + ep_nlimbs = esec? esize:0; + ep = ep_marker = mpi_alloc_limb_space( esize, esec ); + MPN_COPY(ep, rp, esize); } - + if ( rp == mp ) + { + /* RES and MOD are identical. Allocate temporary space for MOD.*/ + gcry_assert (!mp_marker); + mp_nlimbs = msec?msize:0; + mp = mp_marker = mpi_alloc_limb_space( msize, msec ); + MPN_COPY(mp, rp, msize); + } + + /* Copy base to the result. */ + if (res->alloced < size) + { + mpi_resize (res, size); + rp = res->d; + } MPN_COPY ( rp, bp, bsize ); rsize = bsize; rsign = bsign; + /* Main processing. */ { mpi_size_t i; mpi_ptr_t xp; @@ -285,12 +277,8 @@ rsize++; } } - else - { - MPN_COPY( res->d, rp, rsize); - rp = res->d; - } + gcry_assert (res->d == rp); if ( rsize >= msize ) { _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize); @@ -305,6 +293,7 @@ _gcry_mpih_release_karatsuba_ctx (&karactx ); } + /* Fixup for negative results. */ if ( negative_result && rsize ) { if ( mod_shift_cnt ) @@ -314,12 +303,11 @@ rsign = msign; MPN_NORMALIZE(rp, rsize); } + gcry_assert (res->d == rp); res->nlimbs = rsize; res->sign = rsign; leave: - if (assign_rp) - _gcry_mpi_assign_limb_space( res, rp, size ); if (mp_marker) _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs ); if (bp_marker) Modified: trunk/tests/mpitests.c =================================================================== --- trunk/tests/mpitests.c 2008-12-02 11:38:43 UTC (rev 1363) +++ trunk/tests/mpitests.c 2008-12-02 12:39:01 UTC (rev 1364) @@ -34,6 +34,19 @@ static int debug; +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + + /* Set up some test patterns */ /* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ @@ -157,6 +170,110 @@ } +/* What we test here is that we don't overwrite our args and that + using thne same mpi for several args works. */ +static int +test_powm (void) +{ + int b_int = 17; + int e_int = 3; + int m_int = 19; + gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int); + gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int); + gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int); + gcry_mpi_t res = gcry_mpi_new (0); + + gcry_mpi_powm (res, base, exp, mod); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using base for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (base, base, exp, mod); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using exp for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (exp, base, exp, mod); + if (gcry_mpi_cmp (res, exp)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using mod for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (mod, base, exp, mod); + if (gcry_mpi_cmp (res, mod)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + + /* Now check base ^ base mod mod. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (res, base, base, mod); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check base ^ base mod mod with base as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (base, base, base, mod); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check base ^ base mod mod with mod as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (mod, base, base, mod); + if (gcry_mpi_cmp (res, mod)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + + /* Now check base ^ base mod base. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_powm (res, base, base, base); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + + /* Check base ^ base mod base with base as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_powm (base, base, base, base); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + + /* Fixme: We should add the rest of the cases of course. */ + + + + return 1; +} + + int main (int argc, char* argv[]) { @@ -175,6 +292,7 @@ test_add (); test_sub (); test_mul (); + test_powm (); return 0; } From cvs at cvs.gnupg.org Tue Dec 2 19:22:54 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 02 Dec 2008 19:22:54 +0100 Subject: [svn] GpgOL - r291 - trunk/po Message-ID: Author: wk Date: 2008-12-02 19:22:54 +0100 (Tue, 02 Dec 2008) New Revision: 291 Modified: trunk/po/de.po trunk/po/sv.po Log: Typo fix. Modified: trunk/po/de.po [not shown] Modified: trunk/po/sv.po [not shown] From cvs at cvs.gnupg.org Wed Dec 3 09:50:32 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 03 Dec 2008 09:50:32 +0100 Subject: [svn] gcry - r1365 - in trunk: mpi tests Message-ID: Author: wk Date: 2008-12-03 09:50:32 +0100 (Wed, 03 Dec 2008) New Revision: 1365 Modified: trunk/mpi/ChangeLog trunk/mpi/mpi-pow.c trunk/tests/ChangeLog trunk/tests/benchmark.c trunk/tests/fips186-dsa.c trunk/tests/fipsdrv.c trunk/tests/mpitests.c Log: Fix last moi-pow.c change. Add some code to allow standalone builds of some test programs. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/mpi/ChangeLog 2008-12-03 08:50:32 UTC (rev 1365) @@ -1,3 +1,8 @@ +2008-12-03 Werner Koch + + * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really + useful! + 2008-12-02 Werner Koch * mpi-pow.c (gcry_mpi_powm): Re-indent. @@ -189,7 +194,7 @@ 2004-12-16 Werner Koch * config.links (mpi_optional_modules): Move entry for powerpc64 - before generic powerpc. Suggested by Rafael ?vila de Esp?ndola. + before generic powerpc. Suggested by Rafael ??vila de Esp??ndola. 2004-03-02 Werner Koch @@ -726,7 +731,7 @@ Wed Apr 8 09:44:33 1998 Werner Koch (wk at isil.d.shuttle.de) - * config.links: Applied small fix from Ulf M?ller. + * config.links: Applied small fix from Ulf M??ller. Mon Apr 6 12:38:52 1998 Werner Koch (wk at isil.d.shuttle.de) Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/tests/ChangeLog 2008-12-03 08:50:32 UTC (rev 1365) @@ -1,5 +1,7 @@ 2008-12-02 Werner Koch + * fipsdrv.c: All standalone build. + * mpitests.c (mpi_powm): New. 2008-11-28 Werner Koch Modified: trunk/mpi/mpi-pow.c =================================================================== --- trunk/mpi/mpi-pow.c 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/mpi/mpi-pow.c 2008-12-03 08:50:32 UTC (rev 1365) @@ -277,8 +277,12 @@ rsize++; } } + else if (res->d != rp) + { + MPN_COPY (res->d, rp, rsize); + rp = res->d; + } - gcry_assert (res->d == rp); if ( rsize >= msize ) { _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize); Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/tests/benchmark.c 2008-12-03 08:50:32 UTC (rev 1365) @@ -29,8 +29,14 @@ #else #include #endif -#include +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include +#endif + + #define PGM "benchmark" static int verbose; Modified: trunk/tests/fips186-dsa.c =================================================================== --- trunk/tests/fips186-dsa.c 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/tests/fips186-dsa.c 2008-12-03 08:50:32 UTC (rev 1365) @@ -25,8 +25,13 @@ #include #include -#include "../src/gcrypt.h" +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include +#endif + #define my_isascii(c) (!((c) & 0x80)) #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ @@ -444,7 +449,7 @@ } gcry_control (GCRYCTL_DISABLE_SECMEM, 0); - if (!gcry_check_version (GCRYPT_VERSION)) + if (!gcry_check_version ("1.4.4")) die ("version mismatch\n"); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/tests/fipsdrv.c 2008-12-03 08:50:32 UTC (rev 1365) @@ -32,8 +32,15 @@ #include #include -#include +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include +# define PACKAGE_BUGREPORT "devnull at example.org" +# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" +#endif + #define PGM "fipsdrv" #define my_isascii(c) (!((c) & 0x80)) Modified: trunk/tests/mpitests.c =================================================================== --- trunk/tests/mpitests.c 2008-12-02 12:39:01 UTC (rev 1364) +++ trunk/tests/mpitests.c 2008-12-03 08:50:32 UTC (rev 1365) @@ -27,9 +27,12 @@ #include #include -#include "../src/gcrypt.h" +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include +#endif - static int verbose; static int debug; From cvs at cvs.gnupg.org Wed Dec 3 15:24:03 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 03 Dec 2008 15:24:03 +0100 Subject: [svn] gpgme - r1349 - trunk/src Message-ID: Author: marcus Date: 2008-12-03 15:24:03 +0100 (Wed, 03 Dec 2008) New Revision: 1349 Modified: trunk/src/ChangeLog trunk/src/Makefile.am Log: 2008-12-03 Marcus Brinkmann * Makefile.am (status-table.h): Use $(builddir) to find gpgme.h. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-11-28 10:32:12 UTC (rev 1348) +++ trunk/src/ChangeLog 2008-12-03 14:24:03 UTC (rev 1349) @@ -1,3 +1,7 @@ +2008-12-03 Marcus Brinkmann + + * Makefile.am (status-table.h): Use $(builddir) to find gpgme.h. + 2008-11-18 Werner Koch * version.c (do_subsystem_inits): Always initialize I/O Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2008-11-28 10:32:12 UTC (rev 1348) +++ trunk/src/Makefile.am 2008-12-03 14:24:03 UTC (rev 1349) @@ -226,7 +226,7 @@ endif status-table.h : gpgme.h - $(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h + $(srcdir)/mkstatus < $(builddir)/gpgme.h > status-table.h install-data-local: install-def-file From cvs at cvs.gnupg.org Wed Dec 3 15:27:52 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 03 Dec 2008 15:27:52 +0100 Subject: [svn] gpgme - r1350 - in trunk/tests: . gpg gpgsm Message-ID: Author: marcus Date: 2008-12-03 15:27:52 +0100 (Wed, 03 Dec 2008) New Revision: 1350 Modified: trunk/tests/ChangeLog trunk/tests/Makefile.am trunk/tests/gpg/Makefile.am trunk/tests/gpgsm/Makefile.am Log: 2008-12-03 Marcus Brinkmann * Makefile.am (INCLUDES): Fix path to include file. * gpg/Makefile.am (INCLUDES), gpgsm/Makefile.am (INCLUDES): Likewise. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-03 14:24:03 UTC (rev 1349) +++ trunk/tests/ChangeLog 2008-12-03 14:27:52 UTC (rev 1350) @@ -1,3 +1,8 @@ +2008-12-03 Marcus Brinkmann + + * Makefile.am (INCLUDES): Fix path to include file. + * gpg/Makefile.am (INCLUDES), gpgsm/Makefile.am (INCLUDES): Likewise. + 2008-11-18 Werner Koch * gpgsm/cms-decrypt.c: New. Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2008-12-03 14:24:03 UTC (rev 1349) +++ trunk/tests/Makefile.am 2008-12-03 14:27:52 UTC (rev 1350) @@ -26,7 +26,7 @@ EXTRA_DIST = t-data-1.txt t-data-2.txt -INCLUDES = -I$(top_srcdir)/gpgme +INCLUDES = -I$(top_builddir)/src AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ LDADD = ../src/libgpgme.la @GPG_ERROR_LIBS@ Modified: trunk/tests/gpg/Makefile.am =================================================================== --- trunk/tests/gpg/Makefile.am 2008-12-03 14:24:03 UTC (rev 1349) +++ trunk/tests/gpg/Makefile.am 2008-12-03 14:27:52 UTC (rev 1350) @@ -43,7 +43,7 @@ EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \ geheim.txt pubkey-1.asc seckey-1.asc pinentry -INCLUDES = -I$(top_srcdir)/src +INCLUDES = -I$(top_builddir)/src AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ LDADD = ../../src/libgpgme.la Modified: trunk/tests/gpgsm/Makefile.am =================================================================== --- trunk/tests/gpgsm/Makefile.am 2008-12-03 14:24:03 UTC (rev 1349) +++ trunk/tests/gpgsm/Makefile.am 2008-12-03 14:27:52 UTC (rev 1350) @@ -29,7 +29,7 @@ EXTRA_DIST = cert_dfn_pca01.der cert_dfn_pca15.der cert_g10code_test1.der \ $(key_id) -INCLUDES = -I$(top_srcdir)/src +INCLUDES = -I$(top_builddir)/src AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ LDADD = ../../src/libgpgme.la From cvs at cvs.gnupg.org Wed Dec 3 16:14:48 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 03 Dec 2008 16:14:48 +0100 Subject: [svn] gcry - r1366 - trunk/tests Message-ID: Author: wk Date: 2008-12-03 16:14:48 +0100 (Wed, 03 Dec 2008) New Revision: 1366 Modified: trunk/tests/ChangeLog trunk/tests/cavs_driver.pl trunk/tests/fipsdrv.c Log: More DSA FIPS test suport. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-03 08:50:32 UTC (rev 1365) +++ trunk/tests/ChangeLog 2008-12-03 15:14:48 UTC (rev 1366) @@ -1,3 +1,11 @@ +2008-12-03 Werner Koch + + * fipsdrv.c (run_dsa_pqg_gen): Facor code out into .. + (print_dsa_domain_parameters, dsa_gen): .. these two new functions. + (print_sexp, read_sexp_from_file): New. + (run_dsa_sign): New. + (run_dsa_verify): New. + 2008-12-02 Werner Koch * fipsdrv.c: All standalone build. Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2008-12-03 08:50:32 UTC (rev 1365) +++ trunk/tests/cavs_driver.pl 2008-12-03 15:14:48 UTC (rev 1366) @@ -217,6 +217,16 @@ # h my $dsa_pqggen; +# +# Generate an DSA public key from the provided parameters: +# $1: Name of file to create +# $2: P in hex form +# $3: Q in hex form +# $4: G in hex form +# $5: Y in hex form +my $dsa_genpubkey; + + # Verify a message with DSA # $1: data to be verified in hex form # $2: file holding the public DSA key in PEM format @@ -451,6 +461,75 @@ return pipe_through_program("", $program); } +sub libgcrypt_gen_dsakey($) { + my $file = shift; + + my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; + my $tmp; + my %ret; + + die "ARCFOUR not available for DSA" if $opt{'R'}; + + $tmp = pipe_through_program("", $program); + die "dsa key gen failed: file $file not created" if (! -f $file); + + @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); + return %ret; +} + +sub libgcrypt_dsa_genpubkey($$$$$) { + my $filename = shift; + my $p = shift; + my $q = shift; + my $g = shift; + my $y = shift; + + my $sexp; + + $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))"; + + open(FH, ">", $filename) or die; + print FH $sexp; + close FH; +} + +sub libgcrypt_dsa_sign($$) { + my $data = shift; + my $keyfile = shift; + my $tmp; + my %ret; + + die "ARCFOUR not available for DSA" if $opt{'R'}; + + $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign"); + @ret{'Y', 'R', 'S'} = split(/\n/, $tmp); + return %ret; +} + +sub libgcrypt_dsa_verify($$$$) { + my $data = shift; + my $keyfile = shift; + my $r = shift; + my $s = shift; + + my $ret; + + die "ARCFOUR not available for DSA" if $opt{'R'}; + + my $sigfile = "$keyfile.sig"; + open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; + print FH "(sig-val(dsa(r #$r)(s #$s#)))"; + close FH; + + $ret = pipe_through_program($data, + "fipsdrv --verbose --key $keyfile --signature $sigfile dsa-verify"); + unlink ($sigfile); + # Parse through the output information + return ($ret =~ /GOOD signature/); +} + + + ######### End of libgcrypt implementation ################ ################################################################ @@ -1415,7 +1494,7 @@ # but since it is not run on a security sensitive # system, I hope that this is fine my $keyfile = "dsa_sigver.tmp.$$"; - gen_pubdsakey($keyfile, $p, $q, $g, $y); + &dsa_genpubkey($keyfile, $p, $q, $g, $y); $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n"); @@ -1572,8 +1651,8 @@ ##### Identify the test type if ($tmpline =~ /SigVer/ && $opt{'D'} ) { $tt = 12; - die "Interface function dsa_verify for dSA verification not defined for tested library" - if (!defined($dsa_verify)); + die "Interface function dsa_verify or dsa_genpubey for dSA verification not defined for tested library" + if (!defined($dsa_verify) || !defined($dsa_genpubkey)); } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { $tt = 11; die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" @@ -1927,6 +2006,8 @@ unlink("rsa_sigver.tmp.$$.sig"); unlink("rsa_sigver.tmp.$$.der"); unlink("rsa_sigver.tmp.$$.cnf"); + + unlink("dsa_sigver.tmp.$$.sig"); exit; } @@ -1961,6 +2042,10 @@ $state_rng = \&libgcrypt_state_rng; $hmac = \&libgcrypt_hmac; $dsa_pqggen = \&libgcrypt_dsa_pqggen; + $gen_dsakey = \&libgcrypt_gen_dsakey; + $dsa_sign = \&libgcrypt_dsa_sign; + $dsa_verify = \&libgcrypt_dsa_verify; + $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; } else { die "Invalid interface option given"; } Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2008-12-03 08:50:32 UTC (rev 1365) +++ trunk/tests/fipsdrv.c 2008-12-03 15:14:48 UTC (rev 1366) @@ -739,6 +739,34 @@ } +/* Read an S-expression from FNAME. */ +static gcry_sexp_t +read_sexp_from_file (const char *fname) +{ + gcry_error_t err; + FILE *fp; + char *buffer; + size_t buflen; + gcry_sexp_t sexp; + + fp = fopen (fname, "rb"); + if (!fp) + die ("can't open `%s': %s\n", fname, strerror (errno)); + buffer = read_file (fp, 0, &buflen); + if (!buffer) + die ("error reading `%s'\n", fname); + fclose (fp); + if (!buflen) + die ("error: file `%s' is empty\n", fname); + + err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free); + if (err) + die ("error parsing `%s': %s\n", fname, gpg_strerror (err)); + + return sexp; +} + + static void print_buffer (const void *buffer, size_t length) { @@ -875,9 +903,24 @@ die ("writing output failed: %s\n", strerror (errno)); } +/* Print the S-expression A to the stream FP. */ +static void +print_sexp (gcry_sexp_t a, FILE *fp) +{ + char *buf; + size_t size; + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = gcry_xmalloc (size); + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + if (fwrite (buf, size, 1, fp) != 1) + die ("error writing to stream: %s\n", strerror (errno)); + gcry_free (buf); +} + + static gcry_error_t init_external_rng_test (void **r_context, unsigned int flags, @@ -1542,42 +1585,52 @@ -/* Generate DSA donmain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex - format and in this order: p, q, g, seed, counter, h. */ -static void -run_dsa_pqg_gen (int keysize) +/* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ +static gcry_sexp_t +dsa_gen (int keysize) { gpg_error_t err; - gcry_sexp_t keyspec, key, l1, l2; - gcry_mpi_t mpi; - int idx; - const void *data; - size_t datalen; - char *string; + gcry_sexp_t keyspec, key; - /* Note that we create a complete key but don't return the x and y - values. */ err = gcry_sexp_build (&keyspec, NULL, "(genkey (dsa (nbits %d)(use-fips186-2)))", keysize); if (err) - die ("gcry_sexp_build failed for DSA domain parameter generation: %s\n", + die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); err = gcry_pk_genkey (&key, keyspec); if (err) - die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); gcry_sexp_release (keyspec); - l1 = gcry_sexp_find_token (key, "private-key", 0); + return key; +} + + +/* Print the domain parameter as well as the derive information. KEY + is the complete key as returned by dsa_gen. We print to stdout + with one parameter per line in hex format using this order: p, q, + g, seed, counter, h. */ +static void +print_dsa_domain_parameters (gcry_sexp_t key) +{ + gcry_sexp_t l1, l2; + gcry_mpi_t mpi; + int idx; + const void *data; + size_t datalen; + char *string; + + l1 = gcry_sexp_find_token (key, "public-key", 0); if (!l1) - die ("private key not found in genkey result\n"); + die ("public key not found in genkey result\n"); l2 = gcry_sexp_find_token (l1, "dsa", 0); if (!l2) - die ("returned private key not formed as expected\n"); + die ("returned public key not formed as expected\n"); gcry_sexp_release (l1); l1 = l2; @@ -1586,10 +1639,10 @@ { l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1); if (!l2) - die ("no %c parameter in returned private key\n", "pqg"[idx]); + die ("no %c parameter in returned public key\n", "pqg"[idx]); mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); if (!mpi) - die ("no value for %c parameter in returned private key\n","pqg"[idx]); + die ("no value for %c parameter in returned public key\n","pqg"[idx]); gcry_sexp_release (l2); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); @@ -1603,46 +1656,215 @@ l2 = gcry_sexp_find_token (l1, "seed-values", 0); if (!l2) - die ("no seed-values in returned private key\n"); + die ("no seed-values in returned key\n"); gcry_sexp_release (l1); l1 = l2; l2 = gcry_sexp_find_token (l1, "seed", 0); if (!l2) - die ("no seed value in returned private key\n"); + die ("no seed value in returned key\n"); data = gcry_sexp_nth_data (l2, 1, &datalen); if (!data) - die ("no seed value in returned private key\n"); + die ("no seed value in returned key\n"); print_data_line (data, datalen); gcry_sexp_release (l2); l2 = gcry_sexp_find_token (l1, "counter", 0); if (!l2) - die ("no counter value in returned private key\n"); + die ("no counter value in returned key\n"); string = gcry_sexp_nth_string (l2, 1); if (!string) - die ("no counter value in returned private key\n"); + die ("no counter value in returned key\n"); printf ("%lX\n", strtoul (string, NULL, 10)); gcry_free (string); gcry_sexp_release (l2); l2 = gcry_sexp_find_token (l1, "h", 0); if (!l2) - die ("no n value in returned private key\n"); + die ("no n value in returned key\n"); mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); if (!mpi) - die ("no h value in returned private key\n"); + die ("no h value in returned key\n"); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); gcry_sexp_release (l2); gcry_sexp_release (l1); +} + + +/* Generate DSA domain parameters for a modulus size of KEYSIZE. The + result is printed to stdout with one parameter per line in hex + format and in this order: p, q, g, seed, counter, h. */ +static void +run_dsa_pqg_gen (int keysize) +{ + gcry_sexp_t key; + + key = dsa_gen (keysize); + print_dsa_domain_parameters (key); gcry_sexp_release (key); } +/* Generate a DSA key of size of KEYSIZE and write the private key to + FILENAME. Also write the parameters to stdout in the same way as + run_dsa_pqg_gen. */ +static void +run_dsa_gen (int keysize, const char *filename) +{ + gcry_sexp_t key, private_key; + FILE *fp; + + key = dsa_gen (keysize); + private_key = gcry_sexp_find_token (key, "private-key", 0); + if (!private_key) + die ("private key not found in genkey result\n"); + print_dsa_domain_parameters (key); + + fp = fopen (filename, "wb"); + if (!fp) + die ("can't create `%s': %s\n", filename, strerror (errno)); + print_sexp (private_key, fp); + fclose (fp); + + gcry_sexp_release (private_key); + gcry_sexp_release (key); +} + + +/* Sign DATA of length DATALEN using the key taken from the S-expression + encoded KEYFILE. */ static void +run_dsa_sign (const void *data, size_t datalen, const char *keyfile) + +{ + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; + gcry_mpi_t tmpmpi; + + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, data, datalen, NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmpmpi); + gcry_mpi_release (tmpmpi); + } + if (err) + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + + s_key = read_sexp_from_file (keyfile); + + err = gcry_pk_sign (&s_sig, s_data, s_key); + if (err) + { + gcry_sexp_release (read_private_key_file (keyfile, 1)); + die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", + (int)datalen, keyfile, gpg_strerror (err)); + } + gcry_sexp_release (s_data); + + /* We need to return the Y parameter first. */ + s_tmp = gcry_sexp_find_token (s_key, "private-key", 0); + if (!s_tmp) + die ("private key part not found in provided key\n"); + + s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0); + if (!s_tmp2) + die ("private key part is not a DSA key\n"); + gcry_sexp_release (s_tmp); + + s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0); + tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); + if (!tmpmpi) + die ("no y parameter in DSA key\n"); + print_mpi_line (tmpmpi, 1); + gcry_mpi_release (tmpmpi); + gcry_sexp_release (s_tmp); + + gcry_sexp_release (s_key); + + + /* Now return the actual signature. */ + s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); + if (!s_tmp) + die ("no sig-val element in returned S-expression\n"); + + gcry_sexp_release (s_sig); + s_sig = s_tmp; + s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0); + if (!s_tmp) + die ("no dsa element in returned S-expression\n"); + + gcry_sexp_release (s_sig); + s_sig = s_tmp; + + s_tmp = gcry_sexp_find_token (s_sig, "r", 0); + tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); + if (!tmpmpi) + die ("no r parameter in returned S-expression\n"); + print_mpi_line (tmpmpi, 1); + gcry_mpi_release (tmpmpi); + gcry_sexp_release (s_tmp); + + s_tmp = gcry_sexp_find_token (s_sig, "s", 0); + tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); + if (!tmpmpi) + die ("no s parameter in returned S-expression\n"); + print_mpi_line (tmpmpi, 1); + gcry_mpi_release (tmpmpi); + gcry_sexp_release (s_tmp); + + gcry_sexp_release (s_sig); +} + + + +/* Verify DATA of length DATALEN using the public key taken from the + S-expression in KEYFILE against the S-expression formatted + signature in SIGFILE. */ +static void +run_dsa_verify (const void *data, size_t datalen, + const char *keyfile, const char *sigfile) + +{ + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig; + gcry_mpi_t tmpmpi; + + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, data, datalen, NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmpmpi); + gcry_mpi_release (tmpmpi); + } + if (err) + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + + s_key = read_sexp_from_file (keyfile); + s_sig = read_sexp_from_file (sigfile); + + err = gcry_pk_verify (s_sig, s_data, s_key); + if (!err) + puts ("GOOD signature"); + else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) + puts ("BAD signature"); + else + printf ("ERROR (%s)\n", gpg_strerror (err)); + + gcry_sexp_release (s_sig); + gcry_sexp_release (s_key); + gcry_sexp_release (s_data); +} + + + + +static void usage (int show_help) { if (!show_help) @@ -1656,7 +1878,7 @@ "Run a crypto operation using hex encoded input and output.\n" "MODE:\n" " encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify},\n" - " dsa-pqg-gen\n" + " dsa-{pqg-gen,gen,sign,verify}\n" "OPTIONS:\n" " --verbose Print additional information\n" " --binary Input and output is in binary form\n" @@ -1850,7 +2072,8 @@ && !mct_server && strcmp (mode_string, "random") && strcmp (mode_string, "rsa-gen") - && strcmp (mode_string, "dsa-pqg-gen") ) + && strcmp (mode_string, "dsa-pqg-gen") + && strcmp (mode_string, "dsa-gen") ) { data = read_file (input, !binary_input, &datalen); if (!data) @@ -2097,6 +2320,43 @@ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); run_dsa_pqg_gen (keysize); } + else if (!strcmp (mode_string, "dsa-gen")) + { + int keysize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + if (!key_string) + die ("option --key is required in this mode\n"); + run_dsa_gen (keysize, key_string); + } + else if (!strcmp (mode_string, "dsa-sign")) + { + if (!key_string) + die ("option --key is required in this mode\n"); + if (access (key_string, R_OK)) + die ("option --key needs to specify an existing keyfile\n"); + if (!data) + die ("no data available (do not use --chunk)\n"); + + run_dsa_sign (data, datalen, key_string); + } + else if (!strcmp (mode_string, "dsa-verify")) + { + if (!key_string) + die ("option --key is required in this mode\n"); + if (access (key_string, R_OK)) + die ("option --key needs to specify an existing keyfile\n"); + if (!data) + die ("no data available (do not use --chunk)\n"); + if (!signature_string) + die ("option --signature is required in this mode\n"); + if (access (signature_string, R_OK)) + die ("option --signature needs to specify an existing file\n"); + + run_dsa_verify (data, datalen, key_string, signature_string); + } else usage (0); From cvs at cvs.gnupg.org Thu Dec 4 14:24:26 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 04 Dec 2008 14:24:26 +0100 Subject: [svn] gcry - r1367 - trunk/doc Message-ID: Author: wk Date: 2008-12-04 14:24:26 +0100 (Thu, 04 Dec 2008) New Revision: 1367 Modified: trunk/doc/gcrypt.texi Log: Add some notes to the hander register fucntions. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-12-03 15:14:48 UTC (rev 1366) +++ trunk/doc/gcrypt.texi 2008-12-04 13:24:26 UTC (rev 1367) @@ -626,7 +626,7 @@ @item GCRYCTL_DISABLE_SECMEM; Arguments: none This command disables the use of secure memory. If this command is -used in FIPS mode, FIPS mode will be disabled and the fucntion +used in FIPS mode, FIPS mode will be disabled and the function @code{gcry_fips_mode_active} returns false. However, in Enforced FIPS mode this command has no effect at all. @@ -1207,7 +1207,7 @@ @chapter Handler Functions Libgcrypt makes it possible to install so called `handler functions', -which get called by Libgcrypt in case of certain events. +which get called by Libgcrypt in case of certain events. @menu * Progress handler:: Using a progress handler function. @@ -1235,7 +1235,8 @@ @deftypefun void gcry_set_progress_handler (gcry_handler_progress_t @var{cb}, void *@var{cb_data}) This function installs @var{cb} as the `Progress handler' function. - at var{cb} must be defined as follows: +It may be used only during initialization. @var{cb} must be defined +as follows: @example void @@ -1309,7 +1310,14 @@ @deftypefun void gcry_set_allocation_handler (gcry_handler_alloc_t @var{func_alloc}, gcry_handler_alloc_t @var{func_alloc_secure}, gcry_handler_secure_check_t @var{func_secure_check}, gcry_handler_realloc_t @var{func_realloc}, gcry_handler_free_t @var{func_free}) Install the provided functions and use them instead of the built-in -functions for doing memory allocation. +functions for doing memory allocation. Using this function is in +general not recommended because the standard Libgcrypt allocation +functions are guaranteed to zeroize memory if needed. + +This function may be used only during initialization and may not be +used in fips mode. + + @end deftypefun @node Error handler From cvs at cvs.gnupg.org Thu Dec 4 17:24:23 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 04 Dec 2008 17:24:23 +0100 Subject: [svn] gcry - r1368 - trunk/mpi Message-ID: Author: wk Date: 2008-12-04 17:24:23 +0100 (Thu, 04 Dec 2008) New Revision: 1368 Modified: trunk/mpi/ChangeLog trunk/mpi/mpicoder.c Log: Re-indent source4. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2008-12-04 13:24:26 UTC (rev 1367) +++ trunk/mpi/ChangeLog 2008-12-04 16:24:23 UTC (rev 1368) @@ -1,3 +1,7 @@ +2008-12-04 Werner Koch + + * mpicoder.c: Re-indent. + 2008-12-03 Werner Koch * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really Modified: trunk/mpi/mpicoder.c =================================================================== --- trunk/mpi/mpicoder.c 2008-12-04 13:24:26 UTC (rev 1367) +++ trunk/mpi/mpicoder.c 2008-12-04 16:24:23 UTC (rev 1368) @@ -15,8 +15,7 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * License along with this program; if not, see . */ #include @@ -29,7 +28,7 @@ #define MAX_EXTERN_MPI_BITS 16384 - +/* Helper used to scan PGP style MPIs. Returns NULL on failure. */ static gcry_mpi_t mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread, int secure) @@ -86,74 +85,85 @@ * Make an mpi from a hex character string. */ static int -mpi_fromstr(gcry_mpi_t val, const char *str) +mpi_fromstr (gcry_mpi_t val, const char *str) { - int sign=0, prepend_zero=0, i, j, c, c1, c2; - unsigned nbits, nbytes, nlimbs; - mpi_limb_t a; + int sign = 0; + int prepend_zero = 0; + int i, j, c, c1, c2; + unsigned int nbits, nbytes, nlimbs; + mpi_limb_t a; - if( *str == '-' ) { - sign = 1; - str++; + if ( *str == '-' ) + { + sign = 1; + str++; } - /* skip optional hex prefix */ - if ( *str == '0' && str[1] == 'x' ) { - str += 2; - } + /* Skip optional hex prefix. */ + if ( *str == '0' && str[1] == 'x' ) + str += 2; - nbits = strlen(str)*4; - if( nbits % 8 ) - prepend_zero = 1; - nbytes = (nbits+7) / 8; - nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; - if( val->alloced < nlimbs ) - mpi_resize(val, nlimbs ); - i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; - i %= BYTES_PER_MPI_LIMB; - j= val->nlimbs = nlimbs; - val->sign = sign; - for( ; j > 0; j-- ) { - a = 0; - for(; i < BYTES_PER_MPI_LIMB; i++ ) { - if( prepend_zero ) { - c1 = '0'; - prepend_zero = 0; + nbits = 4 * strlen (str); + if ((nbits % 8)) + prepend_zero = 1; + + nbytes = (nbits+7) / 8; + nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; + + if ( val->alloced < nlimbs ) + mpi_resize (val, nlimbs); + + i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB); + i %= BYTES_PER_MPI_LIMB; + j = val->nlimbs = nlimbs; + val->sign = sign; + for (; j > 0; j--) + { + a = 0; + for (; i < BYTES_PER_MPI_LIMB; i++) + { + if (prepend_zero) + { + c1 = '0'; + prepend_zero = 0; } - else - c1 = *str++; - gcry_assert (c1); - c2 = *str++; - gcry_assert (c2); - if( c1 >= '0' && c1 <= '9' ) - c = c1 - '0'; - else if( c1 >= 'a' && c1 <= 'f' ) - c = c1 - 'a' + 10; - else if( c1 >= 'A' && c1 <= 'F' ) - c = c1 - 'A' + 10; - else { - mpi_clear(val); - return 1; + else + c1 = *str++; + + gcry_assert (c1); + c2 = *str++; + gcry_assert (c2); + if ( c1 >= '0' && c1 <= '9' ) + c = c1 - '0'; + else if ( c1 >= 'a' && c1 <= 'f' ) + c = c1 - 'a' + 10; + else if ( c1 >= 'A' && c1 <= 'F' ) + c = c1 - 'A' + 10; + else + { + mpi_clear (val); + return 1; /* Error. */ } - c <<= 4; - if( c2 >= '0' && c2 <= '9' ) - c |= c2 - '0'; - else if( c2 >= 'a' && c2 <= 'f' ) - c |= c2 - 'a' + 10; - else if( c2 >= 'A' && c2 <= 'F' ) - c |= c2 - 'A' + 10; - else { - mpi_clear(val); - return 1; + c <<= 4; + if ( c2 >= '0' && c2 <= '9' ) + c |= c2 - '0'; + else if( c2 >= 'a' && c2 <= 'f' ) + c |= c2 - 'a' + 10; + else if( c2 >= 'A' && c2 <= 'F' ) + c |= c2 - 'A' + 10; + else + { + mpi_clear(val); + return 1; /* Error. */ } - a <<= 8; - a |= c; + a <<= 8; + a |= c; } - i = 0; - val->d[j-1] = a; + i = 0; + val->d[j-1] = a; } - - return 0; + + return 0; /* Okay. */ } @@ -204,447 +214,505 @@ } -/**************** - * Return an m_alloced buffer with the MPI (msb first). - * NBYTES receives the length of this buffer. Caller must free the - * return string (This function does return a 0 byte buffer with NBYTES - * set to zero if the value of A is zero. If sign is not NULL, it will - * be set to the sign of the A. - */ -static byte * -do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure ) +/* Return an allocated buffer with the MPI (msb first). NBYTES + receives the length of this buffer. Caller must free the return + string. This function does return a 0 byte buffer with NBYTES set + to zero if the value of A is zero. If sign is not NULL, it will be + set to the sign of the A. */ +static unsigned char * +do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure) { - byte *p, *buffer; - mpi_limb_t alimb; - int i; - size_t n; + unsigned char *p, *buffer; + mpi_limb_t alimb; + int i; + size_t n; + + if (sign) + *sign = a->sign; - if( sign ) - *sign = a->sign; - *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; - n = *nbytes? *nbytes:1; /* allocate at least one byte */ - p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n) + *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; + n = *nbytes? *nbytes:1; /* Allocate at least one byte. */ + p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n) : gcry_xmalloc(n); - for(i=a->nlimbs-1; i >= 0; i-- ) { - alimb = a->d[i]; + for (i=a->nlimbs-1; i >= 0; i--) + { + alimb = a->d[i]; #if BYTES_PER_MPI_LIMB == 4 - *p++ = alimb >> 24; - *p++ = alimb >> 16; - *p++ = alimb >> 8; - *p++ = alimb ; + *p++ = alimb >> 24; + *p++ = alimb >> 16; + *p++ = alimb >> 8; + *p++ = alimb ; #elif BYTES_PER_MPI_LIMB == 8 - *p++ = alimb >> 56; - *p++ = alimb >> 48; - *p++ = alimb >> 40; - *p++ = alimb >> 32; - *p++ = alimb >> 24; - *p++ = alimb >> 16; - *p++ = alimb >> 8; - *p++ = alimb ; + *p++ = alimb >> 56; + *p++ = alimb >> 48; + *p++ = alimb >> 40; + *p++ = alimb >> 32; + *p++ = alimb >> 24; + *p++ = alimb >> 16; + *p++ = alimb >> 8; + *p++ = alimb ; #else - #error please implement for this limb size. +# error please implement for this limb size. #endif } - /* This is sub-optimal but we need to do the shift operation - because the caller has to free the returned buffer */ - for(p=buffer; !*p && *nbytes; p++, --*nbytes ) - ; - if( p != buffer ) - memmove(buffer,p, *nbytes); - return buffer; + /* This is sub-optimal but we need to do the shift operation because + the caller has to free the returned buffer. */ + for (p=buffer; !*p && *nbytes; p++, --*nbytes) + ; + if (p != buffer) + memmove (buffer,p, *nbytes); + return buffer; } byte * -_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ) +_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign) { - return do_get_buffer( a, nbytes, sign, 0 ); + return do_get_buffer (a, nbytes, sign, 0); } byte * -_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ) +_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign) { - return do_get_buffer( a, nbytes, sign, 1 ); + return do_get_buffer (a, nbytes, sign, 1); } -/**************** - * Use BUFFER to update MPI. + +/* + * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to + * SIGN. */ void -_gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer_arg, - unsigned int nbytes, int sign ) +_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg, + unsigned int nbytes, int sign) { - const unsigned char *buffer = (const unsigned char*)buffer_arg; - const byte *p; - mpi_limb_t alimb; - int nlimbs; - int i; - - nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; - RESIZE_IF_NEEDED(a, nlimbs); - a->sign = sign; - - for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) { + const unsigned char *buffer = (const unsigned char*)buffer_arg; + const unsigned char *p; + mpi_limb_t alimb; + int nlimbs; + int i; + + nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; + RESIZE_IF_NEEDED(a, nlimbs); + a->sign = sign; + + for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) + { #if BYTES_PER_MPI_LIMB == 4 - alimb = *p-- ; - alimb |= *p-- << 8 ; - alimb |= *p-- << 16 ; - alimb |= *p-- << 24 ; + alimb = *p-- ; + alimb |= *p-- << 8 ; + alimb |= *p-- << 16 ; + alimb |= *p-- << 24 ; #elif BYTES_PER_MPI_LIMB == 8 - alimb = (mpi_limb_t)*p-- ; - alimb |= (mpi_limb_t)*p-- << 8 ; - alimb |= (mpi_limb_t)*p-- << 16 ; - alimb |= (mpi_limb_t)*p-- << 24 ; - alimb |= (mpi_limb_t)*p-- << 32 ; - alimb |= (mpi_limb_t)*p-- << 40 ; - alimb |= (mpi_limb_t)*p-- << 48 ; - alimb |= (mpi_limb_t)*p-- << 56 ; + alimb = (mpi_limb_t)*p-- ; + alimb |= (mpi_limb_t)*p-- << 8 ; + alimb |= (mpi_limb_t)*p-- << 16 ; + alimb |= (mpi_limb_t)*p-- << 24 ; + alimb |= (mpi_limb_t)*p-- << 32 ; + alimb |= (mpi_limb_t)*p-- << 40 ; + alimb |= (mpi_limb_t)*p-- << 48 ; + alimb |= (mpi_limb_t)*p-- << 56 ; #else - #error please implement for this limb size. +# error please implement for this limb size. #endif - a->d[i++] = alimb; + a->d[i++] = alimb; } - if( p >= buffer ) { + if ( p >= buffer ) + { #if BYTES_PER_MPI_LIMB == 4 - alimb = *p-- ; - if( p >= buffer ) alimb |= *p-- << 8 ; - if( p >= buffer ) alimb |= *p-- << 16 ; - if( p >= buffer ) alimb |= *p-- << 24 ; + alimb = *p--; + if (p >= buffer) + alimb |= *p-- << 8; + if (p >= buffer) + alimb |= *p-- << 16; + if (p >= buffer) + alimb |= *p-- << 24; #elif BYTES_PER_MPI_LIMB == 8 - alimb = (mpi_limb_t)*p-- ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ; - if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ; + alimb = (mpi_limb_t)*p--; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 8; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 16; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 24; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 32; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 40; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 48; + if (p >= buffer) + alimb |= (mpi_limb_t)*p-- << 56; #else - #error please implement for this limb size. +# error please implement for this limb size. #endif - a->d[i++] = alimb; + a->d[i++] = alimb; } - a->nlimbs = i; - gcry_assert (i == nlimbs); + a->nlimbs = i; + gcry_assert (i == nlimbs); } - /* Convert the external representation of an integer stored in BUFFER with a length of BUFLEN into a newly create MPI returned in RET_MPI. If NBYTES is not NULL, it will receive the number of - bytes actually scanned after a successful operation. */ + bytes actually scanned after a successful operation. */ gcry_error_t -gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, - const void *buffer_arg, size_t buflen, size_t *nscanned ) +gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, + const void *buffer_arg, size_t buflen, size_t *nscanned) { - const unsigned char *buffer = (const unsigned char*)buffer_arg; - struct gcry_mpi *a = NULL; - unsigned int len; - int secure = (buffer && gcry_is_secure (buffer)); + const unsigned char *buffer = (const unsigned char*)buffer_arg; + struct gcry_mpi *a = NULL; + unsigned int len; + int secure = (buffer && gcry_is_secure (buffer)); - if (format == GCRYMPI_FMT_SSH) - len = 0; - else - len = buflen; + if (format == GCRYMPI_FMT_SSH) + len = 0; + else + len = buflen; + + if (format == GCRYMPI_FMT_STD) + { + const unsigned char *s = buffer; - if( format == GCRYMPI_FMT_STD ) { - const byte *s = buffer; - - a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) - /BYTES_PER_MPI_LIMB) - : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); - if( len ) { /* not zero */ - a->sign = *s & 0x80; - if( a->sign ) { - /* FIXME: we have to convert from 2compl to magnitude format */ - mpi_free(a); - return gcry_error (GPG_ERR_INTERNAL); + a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) + /BYTES_PER_MPI_LIMB) + : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); + if (len) + { + a->sign = !!(*s & 0x80); + if (a->sign) + { + /* FIXME: we have to convert from 2compl to magnitude format */ + mpi_free (a); + return gcry_error (GPG_ERR_INTERNAL); } - else - _gcry_mpi_set_buffer( a, s, len, 0 ); + else + _gcry_mpi_set_buffer (a, s, len, 0); } - if( ret_mpi ) { - mpi_normalize ( a ); - *ret_mpi = a; + if (ret_mpi) + { + mpi_normalize ( a ); + *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + else + mpi_free(a); + return gcry_error (GPG_ERR_NO_ERROR); } - else if( format == GCRYMPI_FMT_USG ) { - a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) - /BYTES_PER_MPI_LIMB) - : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); + else if (format == GCRYMPI_FMT_USG) + { + a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) + /BYTES_PER_MPI_LIMB) + : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); - if( len ) /* not zero */ - _gcry_mpi_set_buffer( a, buffer, len, 0 ); - if( ret_mpi ) { - mpi_normalize ( a ); - *ret_mpi = a; + if (len) + _gcry_mpi_set_buffer (a, buffer, len, 0); + if (ret_mpi) + { + mpi_normalize ( a ); + *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + else + mpi_free(a); + return 0; } - else if( format == GCRYMPI_FMT_PGP ) { - a = mpi_read_from_buffer (buffer, &len, secure); - if( nscanned ) - *nscanned = len; - if( ret_mpi && a ) { - mpi_normalize ( a ); - *ret_mpi = a; + else if (format == GCRYMPI_FMT_PGP) + { + a = mpi_read_from_buffer (buffer, &len, secure); + if (nscanned) + *nscanned = len; + if (ret_mpi && a) + { + mpi_normalize (a); + *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ); + else + mpi_free(a); + return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ); } - else if( format == GCRYMPI_FMT_SSH ) { - const unsigned char *s = buffer; - size_t n; + else if (format == GCRYMPI_FMT_SSH) + { + const unsigned char *s = buffer; + size_t n; + + if (len && len < 4) + return gcry_error (GPG_ERR_TOO_SHORT); - if( len && len < 4 ) - return gcry_error (GPG_ERR_TOO_SHORT); - n = s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; - s += 4; - if (len) - len -= 4; - if( len && n > len ) - return gcry_error (GPG_ERR_TOO_LARGE); /* or should it be - too_short */ + n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); + s += 4; + if (len) + len -= 4; + if (len && n > len) + return gcry_error (GPG_ERR_TOO_LARGE); - a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1) - /BYTES_PER_MPI_LIMB) - : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); - if( n ) { /* not zero */ - a->sign = *s & 0x80; - if( a->sign ) { - /* FIXME: we have to convert from 2compl to magnitude format */ - mpi_free(a); - return gcry_error (GPG_ERR_INTERNAL); + a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1) + /BYTES_PER_MPI_LIMB) + : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); + if (n) + { + a->sign = !!(*s & 0x80); + if (a->sign) + { + /* FIXME: we have to convert from 2compl to magnitude format */ + mpi_free(a); + return gcry_error (GPG_ERR_INTERNAL); } - else - _gcry_mpi_set_buffer( a, s, n, 0 ); + else + _gcry_mpi_set_buffer( a, s, n, 0 ); } - if( nscanned ) - *nscanned = n+4; - if( ret_mpi ) { + if (nscanned) + *nscanned = n+4; + if (ret_mpi) + { mpi_normalize ( a ); *ret_mpi = a; - } + } else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + mpi_free(a); + return 0; } - else if( format == GCRYMPI_FMT_HEX ) { - if( buflen ) - return gcry_error (GPG_ERR_INV_ARG); /* can only handle C - strings for now */ - a = secure? mpi_alloc_secure (0) : mpi_alloc(0); - if( mpi_fromstr ( a, (const char *)buffer ) ) - return gcry_error (GPG_ERR_INV_OBJ); - if( ret_mpi ) { - mpi_normalize ( a ); - *ret_mpi = a; + else if (format == GCRYMPI_FMT_HEX) + { + /* We can only handle C strings for now. */ + if (buflen) + return gcry_error (GPG_ERR_INV_ARG); + + a = secure? mpi_alloc_secure (0) : mpi_alloc(0); + if (mpi_fromstr (a, (const char *)buffer)) + return gcry_error (GPG_ERR_INV_OBJ); + if (ret_mpi) + { + mpi_normalize ( a ); + *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + else + mpi_free(a); + return 0; } - else - return gcry_error (GPG_ERR_INV_ARG); + else + return gcry_error (GPG_ERR_INV_ARG); } + /* Convert the big integer A into the external representation described by FORMAT and store it in the provided BUFFER which has been allocated by the user with a size of BUFLEN bytes. NWRITTEN receives the actual length of the external representation unless it has been passed as NULL. BUFFER may be NULL to query the required - length.*/ + length. */ gcry_error_t -gcry_mpi_print( enum gcry_mpi_format format, +gcry_mpi_print (enum gcry_mpi_format format, unsigned char *buffer, size_t buflen, size_t *nwritten, struct gcry_mpi *a) { - unsigned int nbits = mpi_get_nbits(a); - size_t len; - size_t dummy_nwritten; + unsigned int nbits = mpi_get_nbits (a); + size_t len; + size_t dummy_nwritten; + + if (!nwritten) + nwritten = &dummy_nwritten; - if (!nwritten) - nwritten = &dummy_nwritten; + len = buflen; + *nwritten = 0; + if (format == GCRYMPI_FMT_STD) + { + unsigned char *tmp; + int extra = 0; + unsigned int n; + + if (a->sign) + return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ - len = buflen; - *nwritten = 0; - if( format == GCRYMPI_FMT_STD ) { - unsigned char *tmp; - int extra = 0; - unsigned int n; - - if( a->sign ) - return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */ - - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - if( n && (*tmp & 0x80) ) { - n++; - extra=1; + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (n && (*tmp & 0x80)) + { + n++; + extra=1; } - - if (buffer && n > len) { - /* The provided buffer is too short. */ - gcry_free (tmp); - return gcry_error (GPG_ERR_TOO_SHORT); + + if (buffer && n > len) + { + /* The provided buffer is too short. */ + gcry_free (tmp); + return gcry_error (GPG_ERR_TOO_SHORT); } - if( buffer ) { - unsigned char *s = buffer; - if( extra ) - *s++ = 0; + if (buffer) + { + unsigned char *s = buffer; - memcpy( s, tmp, n-extra ); + if (extra) + *s++ = 0; + memcpy (s, tmp, n-extra); } - gcry_free(tmp); - *nwritten = n; - return gcry_error (GPG_ERR_NO_ERROR); + gcry_free(tmp); + *nwritten = n; + return 0; } - else if( format == GCRYMPI_FMT_USG ) { - unsigned int n = (nbits + 7)/8; + else if (format == GCRYMPI_FMT_USG) + { + unsigned int n = (nbits + 7)/8; - /* we ignore the sign for this format */ - /* FIXME: for performance reasons we should put this into - * mpi_aprint becuase we can then use the buffer directly */ - if (buffer && n > len) - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ - if( buffer ) { - unsigned char *tmp; - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - memcpy( buffer, tmp, n ); - gcry_free(tmp); + /* Note: We ignore the sign for this format. */ + /* FIXME: for performance reasons we should put this into + mpi_aprint because we can then use the buffer directly. */ + if (buffer && n > len) + return gcry_error (GPG_ERR_TOO_SHORT); + if (buffer) + { + unsigned char *tmp; + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + memcpy (buffer, tmp, n); + gcry_free (tmp); } - *nwritten = n; - return gcry_error (GPG_ERR_NO_ERROR); + *nwritten = n; + return 0; } - else if( format == GCRYMPI_FMT_PGP ) { - unsigned int n = (nbits + 7)/8; + else if (format == GCRYMPI_FMT_PGP) + { + unsigned int n = (nbits + 7)/8; + + /* The PGP format can only handle unsigned integers. */ + if( a->sign ) + return gcry_error (GPG_ERR_INV_ARG); - if( a->sign ) - return gcry_error (GPG_ERR_INV_ARG); /* pgp format can only handle unsigned */ + if (buffer && n+2 > len) + return gcry_error (GPG_ERR_TOO_SHORT); - if (buffer && n+2 > len) - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ - if( buffer ) { - unsigned char *tmp; - unsigned char *s = buffer; - s[0] = nbits >> 8; - s[1] = nbits; + if (buffer) + { + unsigned char *tmp; + unsigned char *s = buffer; - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - memcpy( s+2, tmp, n ); - gcry_free(tmp); + s[0] = nbits >> 8; + s[1] = nbits; + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + memcpy (s+2, tmp, n); + gcry_free (tmp); } - *nwritten = n+2; - return gcry_error (GPG_ERR_NO_ERROR); + *nwritten = n+2; + return 0; } - else if( format == GCRYMPI_FMT_SSH ) { - unsigned char *tmp; - int extra = 0; - unsigned int n; - - if( a->sign ) - return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */ - - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - if( n && (*tmp & 0x80) ) { - n++; - extra=1; + else if (format == GCRYMPI_FMT_SSH) + { + unsigned char *tmp; + int extra = 0; + unsigned int n; + + if (a->sign) + return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (n && (*tmp & 0x80)) + { + n++; + extra=1; } - if (buffer && n+4 > len) { - gcry_free(tmp); - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ + if (buffer && n+4 > len) + { + gcry_free(tmp); + return gcry_error (GPG_ERR_TOO_SHORT); } - if( buffer ) { - byte *s = buffer; - *s++ = n >> 24; - *s++ = n >> 16; - *s++ = n >> 8; - *s++ = n; - if( extra ) - *s++ = 0; - memcpy( s, tmp, n-extra ); + if (buffer) + { + unsigned char *s = buffer; + + *s++ = n >> 24; + *s++ = n >> 16; + *s++ = n >> 8; + *s++ = n; + if (extra) + *s++ = 0; + + memcpy (s, tmp, n-extra); } - gcry_free(tmp); - *nwritten = 4+n; - return gcry_error (GPG_ERR_NO_ERROR); + gcry_free (tmp); + *nwritten = 4+n; + return 0; } - else if( format == GCRYMPI_FMT_HEX ) { - byte *tmp; - int i; - int extra = 0; - unsigned int n=0; + else if (format == GCRYMPI_FMT_HEX) + { + unsigned char *tmp; + int i; + int extra = 0; + unsigned int n = 0; + + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!n || (*tmp & 0x80)) + extra = 2; - tmp = _gcry_mpi_get_buffer( a, &n, NULL ); - if( !n || (*tmp & 0x80) ) - extra=2; + if (buffer && 2*n + extra + !!a->sign + 1 > len) + { + gcry_free(tmp); + return gcry_error (GPG_ERR_TOO_SHORT); + } + if (buffer) + { + unsigned char *s = buffer; - if(buffer && 2*n + extra + !!a->sign + 1 > len) { - gcry_free(tmp); - return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ - } - if( buffer ) { - byte *s = buffer; - if( a->sign ) - *s++ = '-'; - if( extra ) { - *s++ = '0'; - *s++ = '0'; + if (a->sign) + *s++ = '-'; + if (extra) + { + *s++ = '0'; + *s++ = '0'; } + + for (i=0; i < n; i++) + { + unsigned int c = tmp[i]; - for(i=0; i < n; i++ ) { - unsigned int c = tmp[i]; - *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ; - c &= 15; - *s++ = c < 10? '0'+c : 'A'+c-10 ; + *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ; + c &= 15; + *s++ = c < 10? '0'+c : 'A'+c-10 ; } - *s++ = 0; - *nwritten = s - buffer; + *s++ = 0; + *nwritten = s - buffer; } - else { - *nwritten = 2*n + extra + !!a->sign + 1; + else + { + *nwritten = 2*n + extra + !!a->sign + 1; } - gcry_free(tmp); - return gcry_error (GPG_ERR_NO_ERROR); + gcry_free (tmp); + return 0; } - else - return gcry_error (GPG_ERR_INV_ARG); + else + return gcry_error (GPG_ERR_INV_ARG); } -/**************** + +/* * Like gcry_mpi_print but this function allocates the buffer itself. - * The caller has to supply the address of a pointer. NWRITTEN may be + * The caller has to supply the address of a pointer. NWRITTEN may be * NULL. */ gcry_error_t -gcry_mpi_aprint( enum gcry_mpi_format format, +gcry_mpi_aprint (enum gcry_mpi_format format, unsigned char **buffer, size_t *nwritten, - struct gcry_mpi *a ) + struct gcry_mpi *a) { - size_t n; - gcry_error_t rc; + size_t n; + gcry_error_t rc; + + *buffer = NULL; + rc = gcry_mpi_print (format, NULL, 0, &n, a); + if (rc) + return rc; - *buffer = NULL; - rc = gcry_mpi_print( format, NULL, 0, &n, a ); - if( rc ) - return rc; - *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n ); - rc = gcry_mpi_print( format, *buffer, n, &n, a ); - if( rc ) { - gcry_free(*buffer); - *buffer = NULL; + *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n ); + rc = gcry_mpi_print( format, *buffer, n, &n, a ); + if (rc) + { + gcry_free(*buffer); + *buffer = NULL; } - else if( nwritten ) - *nwritten = n; - return rc; + else if (nwritten) + *nwritten = n; + return rc; } From cvs at cvs.gnupg.org Fri Dec 5 09:46:02 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Dec 2008 09:46:02 +0100 Subject: [svn] gcry - r1369 - in trunk: . mpi random tests Message-ID: Author: wk Date: 2008-12-05 09:46:01 +0100 (Fri, 05 Dec 2008) New Revision: 1369 Modified: trunk/TODO trunk/mpi/ChangeLog trunk/mpi/mpicoder.c trunk/random/random-csprng.c trunk/tests/benchmark.c Log: Fixed error cases in mpicoder. Documentation cleanups. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2008-12-04 16:24:23 UTC (rev 1368) +++ trunk/mpi/ChangeLog 2008-12-05 08:46:01 UTC (rev 1369) @@ -1,5 +1,15 @@ -2008-12-04 Werner Koch +2008-12-05 Werner Koch + * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is + larger than the buffer (potential problem). Do not print error + messages. + (mpi_fromstr): Return an error instead of hitting an assert. + (gcry_mpi_scan) : Fix potential double free problem. + (gcry_mpi_scan) : Fix potential memory leak. + (do_get_buffer): Return NULL on memory allocation failure. + (gcry_mpi_print): Check result of do_get_buffer. + (gcry_mpi_aprint): Return error on a memory allocation failure. + * mpicoder.c: Re-indent. 2008-12-03 Werner Koch Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-12-04 16:24:23 UTC (rev 1368) +++ trunk/TODO 2008-12-05 08:46:01 UTC (rev 1369) @@ -36,9 +36,6 @@ collectros need to run that bunch of Unix utilities we don't waste their precious results. -* mpi_print does not use secure memory - for internal variables. - * Add OAEP * gcryptrnd.c Modified: trunk/mpi/mpicoder.c =================================================================== --- trunk/mpi/mpicoder.c 2008-12-04 16:24:23 UTC (rev 1368) +++ trunk/mpi/mpicoder.c 2008-12-05 08:46:01 UTC (rev 1369) @@ -1,6 +1,6 @@ /* mpicoder.c - Coder for the external representation of MPIs - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 + * 2008 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -43,12 +43,12 @@ nbits = buffer[0] << 8 | buffer[1]; if ( nbits > MAX_EXTERN_MPI_BITS ) { - log_error ("mpi too large (%u bits)\n", nbits); +/* log_debug ("mpi too large (%u bits)\n", nbits); */ goto leave; } else if( !nbits ) { - log_error ("an mpi of size 0 is not allowed\n"); +/* log_debug ("an mpi of size 0 is not allowed\n"); */ goto leave; } buffer += 2; @@ -56,7 +56,7 @@ nbytes = (nbits+7) / 8; nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; - val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc( nlimbs ); + val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs); i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; i %= BYTES_PER_MPI_LIMB; j= val->nlimbs = nlimbs; @@ -67,7 +67,12 @@ for (; i < BYTES_PER_MPI_LIMB; i++ ) { if ( ++nread > *ret_nread ) - log_bug ("mpi larger than buffer"); + { +/* log_debug ("mpi larger than buffer"); */ + mpi_free (val); + val = NULL; + goto leave; + } a <<= 8; a |= *buffer++; } @@ -82,7 +87,7 @@ /**************** - * Make an mpi from a hex character string. + * Fill the mpi VAL from the hex string in STR. */ static int mpi_fromstr (gcry_mpi_t val, const char *str) @@ -130,9 +135,17 @@ else c1 = *str++; - gcry_assert (c1); + if (!c1) + { + mpi_clear (val); + return 1; /* Error. */ + } c2 = *str++; - gcry_assert (c2); + if (!c2) + { + mpi_clear (val); + return 1; /* Error. */ + } if ( c1 >= '0' && c1 <= '9' ) c = c1 - '0'; else if ( c1 >= 'a' && c1 <= 'f' ) @@ -216,9 +229,10 @@ /* Return an allocated buffer with the MPI (msb first). NBYTES receives the length of this buffer. Caller must free the return - string. This function does return a 0 byte buffer with NBYTES set + string. This function returns an allocated buffer with NBYTES set to zero if the value of A is zero. If sign is not NULL, it will be - set to the sign of the A. */ + set to the sign of the A. On error NULL is returned and ERRNO set + appropriately. */ static unsigned char * do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure) { @@ -232,8 +246,10 @@ *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; n = *nbytes? *nbytes:1; /* Allocate at least one byte. */ - p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n) - : gcry_xmalloc(n); + p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n) + : gcry_malloc (n); + if (!buffer) + return NULL; for (i=a->nlimbs-1; i >= 0; i--) { @@ -399,7 +415,7 @@ } else mpi_free(a); - return gcry_error (GPG_ERR_NO_ERROR); + return 0; } else if (format == GCRYMPI_FMT_USG) { @@ -428,9 +444,12 @@ mpi_normalize (a); *ret_mpi = a; } - else - mpi_free(a); - return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ); + else if (a) + { + mpi_free(a); + a = NULL; + } + return a? 0 : gcry_error (GPG_ERR_INV_OBJ); } else if (format == GCRYMPI_FMT_SSH) { @@ -464,14 +483,14 @@ } if (nscanned) *nscanned = n+4; - if (ret_mpi) - { - mpi_normalize ( a ); - *ret_mpi = a; - } - else - mpi_free(a); - return 0; + if (ret_mpi) + { + mpi_normalize ( a ); + *ret_mpi = a; + } + else + mpi_free(a); + return 0; } else if (format == GCRYMPI_FMT_HEX) { @@ -481,7 +500,10 @@ a = secure? mpi_alloc_secure (0) : mpi_alloc(0); if (mpi_fromstr (a, (const char *)buffer)) - return gcry_error (GPG_ERR_INV_OBJ); + { + mpi_free (a); + return gcry_error (GPG_ERR_INV_OBJ); + } if (ret_mpi) { mpi_normalize ( a ); @@ -526,6 +548,8 @@ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); if (n && (*tmp & 0x80)) { n++; @@ -564,6 +588,8 @@ unsigned char *tmp; tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); memcpy (buffer, tmp, n); gcry_free (tmp); } @@ -590,6 +616,8 @@ s[1] = nbits; tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); memcpy (s+2, tmp, n); gcry_free (tmp); } @@ -606,6 +634,8 @@ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); if (n && (*tmp & 0x80)) { n++; @@ -643,6 +673,8 @@ unsigned int n = 0; tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); if (!n || (*tmp & 0x80)) extra = 2; @@ -704,7 +736,9 @@ if (rc) return rc; - *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n ); + *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n); + if (!*buffer) + return gpg_error_from_syserror (); rc = gcry_mpi_print( format, *buffer, n, &n, a ); if (rc) { Modified: trunk/random/random-csprng.c =================================================================== --- trunk/random/random-csprng.c 2008-12-04 16:24:23 UTC (rev 1368) +++ trunk/random/random-csprng.c 2008-12-05 08:46:01 UTC (rev 1369) @@ -1,4 +1,4 @@ -/* random-csprng.c - CSPRNG style random number generator (libgcrypt clssic) +/* random-csprng.c - CSPRNG style random number generator (libgcrypt classic) * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, * 2007, 2008 Free Software Foundation, Inc. * @@ -20,9 +20,15 @@ /* This random number generator is modelled after the one described in - Peter Gutmann's paper: "Software Generation of Practically Strong - Random Numbers". See also chapter 6 in his book "Cryptographic - Security Architecture", New York, 2004, ISBN 0-387-95387-6. + Peter Gutmann's 1998 Usenix Security Symposium paper: "Software + Generation of Practically Strong Random Numbers". See also chapter + 6 in his book "Cryptographic Security Architecture", New York, + 2004, ISBN 0-387-95387-6. + + Note that the acronym CSPRNG stands for "Continuously Seeded + PseudoRandom Number Generator" as used in Peter's implementation of + the paper and not only for "Cryptographically Secure PseudoRandom + Number Generator". */ Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2008-12-04 16:24:23 UTC (rev 1368) +++ trunk/tests/benchmark.c 2008-12-05 08:46:01 UTC (rev 1369) @@ -640,7 +640,7 @@ fflush (stdout); err = gcry_sexp_build (&key_spec, NULL, - gcry_control (GCRYCTL_FIPS_MODE_P, 0) + gcry_fips_mode_active () ? "(genkey (RSA (nbits %d)))" : "(genkey (RSA (nbits %d)(transient-key)))", p_sizes[testno]); From cvs at cvs.gnupg.org Fri Dec 5 12:58:25 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Dec 2008 12:58:25 +0100 Subject: [svn] gcry - r1370 - trunk/doc Message-ID: Author: wk Date: 2008-12-05 12:58:25 +0100 (Fri, 05 Dec 2008) New Revision: 1370 Modified: trunk/doc/ChangeLog trunk/doc/gcrypt.texi Log: doc updates Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-12-05 08:46:01 UTC (rev 1369) +++ trunk/doc/ChangeLog 2008-12-05 11:58:25 UTC (rev 1370) @@ -1,3 +1,7 @@ +2008-12-05 Werner Koch + + * gcrypt.texi: Updates for pubkey generation. + 2008-10-20 Werner Koch * gcrypt.texi (Error handler): Fix description of Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-12-05 08:46:01 UTC (rev 1369) +++ trunk/doc/gcrypt.texi 2008-12-05 11:58:25 UTC (rev 1370) @@ -520,6 +520,7 @@ @node Enabling FIPS mode @section How to enable the FIPS mode @cindex FIPS mode + at cindex FIPS 140 Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the @@ -2761,12 +2762,14 @@ @end example @item use-x931 + at cindex X9.31 Force the use of the ANSI X9.31 key generation algorithm instead of the default algorithm. This flag is only meaningful for RSA and usually not required. Note that this algorithm is implicitly used if either @code{derive-parms} is given or Libgcrypt is in FIPS mode. @item use-fips186 + at cindex FIPS 186 Force the use of the FIPS 186 key generation algorithm instead of the default algorithm. This flag is only meaningful for DSA and usually not required. Note that this algorithm is implicitly used if either @@ -4766,9 +4769,16 @@ the RSA decryption directly, a blinded value @math{y = x r^{e} \bmod n} is decrypted and the unblinded value @math{x' = y' r^{-1} \bmod n} returned. The blinding value @math{r} is a random value with the size -of the modulus @math{n} and generated with @code{GCRY_STRONG_RANDOM} +of the modulus @math{n} and generated with @code{GCRY_WEAK_RANDOM} random level. + at cindex X9.31 + at cindex FIPS 186 +The algorithm used for RSA and DSA key generation depends on whether +Libgcrypt is operated in standard or in FIPS mode. In standard mode +an algorithm based on the Lim-Lee prime number generator is used. In +FIPS mode RSA keys are generated as specified in ANSI X9.31 (1998) and +DSA keys as specified in FIPS 186-2. @@ -4948,6 +4958,14 @@ @end enumerate +To support the generation of RSA and DSA keys in FIPS mode according +to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime +generation functions: @code{_gcry_derive_x931_prime} and + at code{_gcry_generate_fips186_2_prime}. These functions are internal +and not available through the public API. + + + @node Random-Number Subsystem Architecture @section Random-Number Subsystem Architecture @@ -5537,10 +5555,14 @@ and thus are in addition available. @item -RSA and DSA key generation refuses to create a key with a keysize of +RSA key generation refuses to create a key with a keysize of less than 1024 bits. @item +DSA key generation refuses to create a key with a keysize other +than 1024 bits. + + at item The @code{transient-key} flag for RSA key generation is ignored. @item From cvs at cvs.gnupg.org Fri Dec 5 13:01:06 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Dec 2008 13:01:06 +0100 Subject: [svn] GnuPG - r4882 - in trunk: . agent common doc po scd tools Message-ID: Author: wk Date: 2008-12-05 13:01:01 +0100 (Fri, 05 Dec 2008) New Revision: 4882 Modified: trunk/TODO trunk/agent/ChangeLog trunk/agent/learncard.c trunk/agent/minip12.c trunk/autogen.sh trunk/common/ChangeLog trunk/common/exechelp.c trunk/doc/scdaemon.texi trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po trunk/scd/ChangeLog trunk/scd/app-openpgp.c trunk/scd/command.c trunk/scd/scdaemon.c trunk/scd/scdaemon.h trunk/tools/ChangeLog trunk/tools/gpg-connect-agent.c trunk/tools/gpgconf-comp.c Log: Add option --card-timeout. Add a new attribyte to app-openpgp.c Fix two portability bugs. Have gpg-connect-agent autostart gpg-agent on W32. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/agent/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) @@ -1,3 +1,9 @@ +2008-12-05 Werner Koch + + * minip12.c (decrypt_block): Fix const modified of CHARSETS. + * learncard.c (sinfo_cb_parm_s): Remove superflous semicolon. + Reported by Stoyan Angelov. + 2008-11-18 Werner Koch * gpg-agent.c (make_libversion): New. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/common/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) @@ -1,3 +1,8 @@ +2008-12-05 Werner Koch + + * exechelp.c (gnupg_spawn_process, gnupg_spawn_process_fd) + (gnupg_spawn_process_detached) [W32]: Remove debug output. + 2008-11-20 Werner Koch * audit.c (writeout_li): Translate OKTEXT. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/scd/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) @@ -1,3 +1,15 @@ +2008-12-05 Werner Koch + + * app-openpgp.c (app_local_s): Add field ALGO_ATTR_CHANGE. + (app_select_openpgp): Parse new capability. + (show_caps): Show new capability. + +2008-12-03 Werner Koch + + * scdaemon.c (opts): Use ARGPARSE_ macros. Add option + --card-timeout. + * command.c (update_reader_status_file): Implement it. + 2008-11-18 Werner Koch * scdaemon.c (make_libversion): New. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/tools/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) @@ -1,3 +1,13 @@ +2008-12-05 Werner Koch + + * gpg-connect-agent.c (opts): Use ARGPARSE_ macros. + (start_agent) [W32]: Start agent if not running. + +2008-12-03 Werner Koch + + * gpgconf-comp.c : Add option --card-timeout. Remove + unused option --disable-opensc. + 2008-10-20 Werner Koch * gpgsplit.c (write_part): Remove unused arg FNAME. Change caller. Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/TODO 2008-12-05 12:01:01 UTC (rev 4882) @@ -63,7 +63,11 @@ would be better to do this just at one place. First we need to see how we can support cards with multiple applications. ** Resolve fixme in do_sign of app-dinsig. +** Disconnect + Card timeout is currently used as a boolean. + Add disconnect support for the ccid driver. +* Regression tests ** Add a regression test to check the extkeyusage. * Windows port (W32) @@ -75,8 +79,6 @@ * sm/ ** check that we issue NO_SECKEY xxx if a -u key was not found We don't. The messages returned are also wrong (recipient vs. signer). -** gpgsm_format_name2 - Replace by an estream based implementation. * jnlib/ ** Try to remove all jnlib_xmalloc. Modified: trunk/agent/learncard.c =================================================================== --- trunk/agent/learncard.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/agent/learncard.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -76,7 +76,7 @@ typedef struct sinfo_s *SINFO; struct sinfo_cb_parm_s { - int error;; + int error; SINFO info; }; Modified: trunk/agent/minip12.c =================================================================== --- trunk/agent/minip12.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/agent/minip12.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -498,7 +498,7 @@ int iter, const char *pw, int cipher_algo, int (*check_fnc) (const void *, size_t)) { - static const char const *charsets[] = { + static const char * const charsets[] = { "", /* No conversion - use the UTF-8 passphrase direct. */ "ISO-8859-1", "ISO-8859-15", Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/autogen.sh 2008-12-05 12:01:01 UTC (rev 4882) @@ -209,5 +209,5 @@ $AUTOCONF${FORCE} echo "You may now run: - ./configure --sysconfdir=/etc --enable-maintainer-mode && make + ./configure --sysconfdir=/etc --enable-maintainer-mode --enable-symcryptrun --enable-mailto && make " Modified: trunk/common/exechelp.c =================================================================== --- trunk/common/exechelp.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/common/exechelp.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -396,7 +396,7 @@ | ((flags & 128)? DETACHED_PROCESS : 0) | GetPriorityClass (GetCurrentProcess ()) | CREATE_SUSPENDED); - log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); +/* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ cmdline, /* Command line arguments. */ &sec_attr, /* Process security attributes. */ @@ -421,10 +421,10 @@ /* Close the other end of the pipe. */ CloseHandle (fd_to_handle (rp[1])); - log_debug ("CreateProcess ready: hProcess=%p hThread=%p" - " dwProcessID=%d dwThreadId=%d\n", - pi.hProcess, pi.hThread, - (int) pi.dwProcessId, (int) pi.dwThreadId); +/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ +/* " dwProcessID=%d dwThreadId=%d\n", */ +/* pi.hProcess, pi.hThread, */ +/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); @@ -558,7 +558,7 @@ si.hStdOutput = outfd == -1? stdhd[1] : (void*)_get_osfhandle (outfd); si.hStdError = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd); - log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); +/* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ cmdline, /* Command line arguments. */ &sec_attr, /* Process security attributes. */ @@ -585,10 +585,10 @@ if (err) return err; - log_debug ("CreateProcess ready: hProcess=%p hThread=%p" - " dwProcessID=%d dwThreadId=%d\n", - pi.hProcess, pi.hThread, - (int) pi.dwProcessId, (int) pi.dwThreadId); +/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ +/* " dwProcessID=%d dwThreadId=%d\n", */ +/* pi.hProcess, pi.hThread, */ +/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); @@ -796,8 +796,8 @@ | GetPriorityClass (GetCurrentProcess ()) | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); - log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", - pgmname, cmdline); +/* log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", */ +/* pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ cmdline, /* Command line arguments. */ &sec_attr, /* Process security attributes. */ @@ -817,10 +817,10 @@ xfree (cmdline); cmdline = NULL; - log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" - " dwProcessID=%d dwThreadId=%d\n", - pi.hProcess, pi.hThread, - (int) pi.dwProcessId, (int) pi.dwThreadId); +/* log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" */ +/* " dwProcessID=%d dwThreadId=%d\n", */ +/* pi.hProcess, pi.hThread, */ +/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ CloseHandle (pi.hThread); Modified: trunk/doc/scdaemon.texi =================================================================== --- trunk/doc/scdaemon.texi 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/doc/scdaemon.texi 2008-12-05 12:01:01 UTC (rev 4882) @@ -252,7 +252,21 @@ @end smallexample + at item --card-timeout @var{n} + at opindex card-timeout +If @var{n} is not 0 and no client is actively using the card, the card +will be powered down after @var{n} seconds. Powering down the card +avoids a potential risk of damaging a card when used with certain +cheap readers. This also allows non Scdaemon aware applications to +access the card. The disadvantage of using a card timeout is that +accessing the card takes longer and that the user needs to enter the +PIN again after the next power up. +Note that with the current version of Scdaemon the card is powered +down immediatley at the next timer tick for any value of @var{n} other +than 0. + + @item --disable-keypad @opindex disable-keypad Even if a card reader features a keypad, do not try to use it. Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/scd/app-openpgp.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -167,13 +167,14 @@ /* Keep track of extended card capabilities. */ struct { - unsigned int is_v2:1; /* This is a v2.0 compatible card. */ + unsigned int is_v2:1; /* This is a v2.0 compatible card. */ unsigned int get_challenge:1; unsigned int key_import:1; unsigned int change_force_chv:1; unsigned int private_dos:1; - unsigned int sm_supported:1; /* Secure Messaging is supported. */ - unsigned int sm_aes128:1; /* Use AES-128 for SM. */ + unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */ + unsigned int sm_supported:1; /* Secure Messaging is supported. */ + unsigned int sm_aes128:1; /* Use AES-128 for SM. */ unsigned int max_certlen_3:16; unsigned int max_get_challenge:16; /* Maximum size for get_challenge. */ unsigned int max_cmd_data:16; /* Maximum data size for a command. */ @@ -3154,6 +3155,7 @@ log_info ("Key-Import .....: %s\n", s->extcap.key_import? "yes":"no"); log_info ("Change-Force-PW1: %s\n", s->extcap.change_force_chv? "yes":"no"); log_info ("Private-DOs ....: %s\n", s->extcap.private_dos? "yes":"no"); + log_info ("Algo-Attr-Change: %s\n", s->extcap.algo_attr_change? "yes":"no"); log_info ("SM-Support .....: %s", s->extcap.sm_supported? "yes":"no"); if (s->extcap.sm_supported) log_printf (" (%s)", s->extcap.sm_aes128? "AES-128":"3DES"); @@ -3376,6 +3378,7 @@ app->app_local->extcap.key_import = !!(*buffer & 0x20); app->app_local->extcap.change_force_chv = !!(*buffer & 0x10); app->app_local->extcap.private_dos = !!(*buffer & 0x08); + app->app_local->extcap.algo_attr_change = !!(*buffer & 0x04); } if (buflen >= 10) { Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/scd/command.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -2095,14 +2095,18 @@ } /* Check whether a disconnect is pending. */ - for (sl=session_list; sl; sl = sl->next_session) - if (!sl->disconnect_allowed) - break; - if (session_list && !sl) + if (opt.card_timeout) { - /* At least one connection and all allow a disconnect. */ - log_debug ("disconnecting card in slot %d\n", ss->slot); - apdu_disconnect (ss->slot); + for (sl=session_list; sl; sl = sl->next_session) + if (!sl->disconnect_allowed) + break; + if (session_list && !sl) + { + /* FIXME: Use a real timeout. */ + /* At least one connection and all allow a disconnect. */ + log_debug ("disconnecting card in slot %d\n", ss->slot); + apdu_disconnect (ss->slot); + } } } Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/scd/scdaemon.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -80,6 +80,7 @@ oDaemon, oBatch, oReaderPort, + oCardTimeout, octapiDriver, opcscDriver, oDisableCCID, @@ -94,46 +95,53 @@ static ARGPARSE_OPTS opts[] = { - - { aGPGConfList, "gpgconf-list", 256, "@" }, - { aGPGConfTest, "gpgconf-test", 256, "@" }, + ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"), + ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"), - { 301, NULL, 0, N_("@Options:\n ") }, + ARGPARSE_group (301, N_("@Options:\n ")), - { oServer, "server", 0, N_("run in server mode (foreground)") }, - { oMultiServer, "multi-server", 0, - N_("run in multi server mode (foreground)") }, - { oDaemon, "daemon", 0, N_("run in daemon mode (background)") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oSh, "sh", 0, N_("sh-style command output") }, - { oCsh, "csh", 0, N_("csh-style command output") }, - { oOptions, "options" , 2, N_("read options from file")}, - { oDebug, "debug" ,4|16, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugWait,"debug-wait",1, "@"}, - { oDebugAllowCoreDump, "debug-allow-core-dump", 0, "@" }, - { oDebugCCIDDriver, "debug-ccid-driver", 0, "@"}, - { oDebugDisableTicker, "debug-disable-ticker", 0, "@"}, - { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, - { oReaderPort, "reader-port", 2, N_("|N|connect to reader at port N")}, - { octapiDriver, "ctapi-driver", 2, N_("|NAME|use NAME as ct-API driver")}, - { opcscDriver, "pcsc-driver", 2, N_("|NAME|use NAME as PC/SC driver")}, - { oDisableCCID, "disable-ccid", 0, + ARGPARSE_s_n (oServer,"server", N_("run in server mode (foreground)")), + ARGPARSE_s_n (oMultiServer, "multi-server", + N_("run in multi server mode (foreground)")), + ARGPARSE_s_n (oDaemon, "daemon", N_("run in daemon mode (background)")), + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), + ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")), + ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")), + ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), + ARGPARSE_p_u (oDebug, "debug", "@"), + ARGPARSE_s_n (oDebugAll, "debug-all", "@"), + ARGPARSE_s_s (oDebugLevel, "debug-level" , + N_("|LEVEL|set the debugging level to LEVEL")), + ARGPARSE_s_i (oDebugWait, "debug-wait", "@"), + ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"), + ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"), + ARGPARSE_s_n (oDebugDisableTicker, "debug-disable-ticker", "@"), + ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")), + ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write a log to FILE")), + ARGPARSE_s_s (oReaderPort, "reader-port", + N_("|N|connect to reader at port N")), + ARGPARSE_s_s (octapiDriver, "ctapi-driver", + N_("|NAME|use NAME as ct-API driver")), + ARGPARSE_s_s (opcscDriver, "pcsc-driver", + N_("|NAME|use NAME as PC/SC driver")), + ARGPARSE_s_n (oDisableCCID, "disable-ccid", #ifdef HAVE_LIBUSB N_("do not use the internal CCID driver") #else "@" #endif - /* end --disable-ccid */}, - { oDisableKeypad, "disable-keypad", 0, N_("do not use a reader's keypad")}, - { oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")}, - { oDenyAdmin, "deny-admin", 0, "@" }, - { oDisableApplication, "disable-application", 2, "@"}, - - {0} + /* end --disable-ccid */), + ARGPARSE_s_u (oCardTimeout, "card-timeout", + N_("|N|disconnect the card after N seconds of inactivity")), + ARGPARSE_s_n (oDisableKeypad, "disable-keypad", + N_("do not use a reader's keypad")), + ARGPARSE_s_n (oAllowAdmin, "allow-admin", + N_("allow the use of admin card commands")), + ARGPARSE_s_n (oDenyAdmin, "deny-admin", "@"), + ARGPARSE_s_s (oDisableApplication, "disable-application", "@"), + + ARGPARSE_end () }; @@ -528,12 +536,16 @@ case oAllowAdmin: opt.allow_admin = 1; break; case oDenyAdmin: opt.allow_admin = 0; break; + + case oCardTimeout: opt.card_timeout = pargs.r.ret_ulong; break; case oDisableApplication: add_to_strlist (&opt.disabled_applications, pargs.r.ret_str); break; - default : pargs.err = configfp? 1:2; break; + default: + pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; + break; } } if (configfp) @@ -619,6 +631,7 @@ #endif printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE ); printf ("disable-keypad:%lu:\n", GC_OPT_FLAG_NONE ); + printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0); scd_exit (0); } Modified: trunk/scd/scdaemon.h =================================================================== --- trunk/scd/scdaemon.h 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/scd/scdaemon.h 2008-12-05 12:01:01 UTC (rev 4882) @@ -61,6 +61,7 @@ cards. */ strlist_t disabled_applications; /* Card applications we do not want to use. */ + unsigned long card_timeout; /* Disconnect after N seconds of inactivity. */ } opt; Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/tools/gpg-connect-agent.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -34,7 +34,11 @@ #include "../common/sysutils.h" #include "../common/membuf.h" #include "../common/ttyio.h" +#ifdef HAVE_W32_SYSTEM +# include "../common/exechelp.h" +#endif + #define CONTROL_D ('D' - 'A' + 1) #define octdigitp(p) (*(p) >= '0' && *(p) <= '7') @@ -59,27 +63,30 @@ /* The list of commands and options. */ -static ARGPARSE_OPTS opts[] = - { - { 301, NULL, 0, N_("@\nOptions:\n ") }, +static ARGPARSE_OPTS opts[] = { + ARGPARSE_group (301, N_("@\nOptions:\n ")), - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("quiet") }, - { oHex, "hex", 0, N_("print data out hex encoded") }, - { oDecode,"decode", 0, N_("decode received data lines") }, - { oRawSocket, "raw-socket", 2, N_("|NAME|connect to Assuan socket NAME")}, - { oExec, "exec", 0, N_("run the Assuan server given on the command line")}, - { oNoExtConnect, "no-ext-connect", - 0, N_("do not use extended connect mode")}, - { oRun, "run", 2, N_("|FILE|run commands from FILE on startup")}, - { oSubst, "subst", 0, N_("run /subst on startup")}, - /* hidden options */ - { oNoVerbose, "no-verbose", 0, "@"}, - { oHomedir, "homedir", 2, "@" }, - {0} - }; + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")), + ARGPARSE_s_n (oHex, "hex", N_("print data out hex encoded")), + ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")), + ARGPARSE_s_s (oRawSocket, "raw-socket", + N_("|NAME|connect to Assuan socket NAME")), + ARGPARSE_s_n (oExec, "exec", + N_("run the Assuan server given on the command line")), + ARGPARSE_s_n (oNoExtConnect, "no-ext-connect", + N_("do not use extended connect mode")), + ARGPARSE_s_s (oRun, "run", + N_("|FILE|run commands from FILE on startup")), + ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")), + ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"), + ARGPARSE_s_s (oHomedir, "homedir", "@" ), + ARGPARSE_end () +}; + + /* We keep all global options in the structure OPT. */ struct { @@ -2081,6 +2088,38 @@ /* Check whether we can connect at the standard socket. */ sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); rc = assuan_socket_connect (&ctx, sockname, 0); + +#ifdef HAVE_W32_SYSTEM + /* If we failed to connect under Windows, we fire up the agent. */ + if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) + { + const char *agent_program; + const char *argv[3]; + int save_rc = rc; + + if (opt.verbose) + log_info (_("no running gpg-agent - starting one\n")); + agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); + + argv[0] = "--daemon"; + argv[1] = "--use-standard-socket"; + argv[2] = NULL; + + rc = gnupg_spawn_process_detached (agent_program, argv, NULL); + if (rc) + log_debug ("failed to start agent `%s': %s\n", + agent_program, gpg_strerror (rc)); + else + { + /* Give the agent some time to prepare itself. */ + gnupg_sleep (3); + /* Now try again to connect the agent. */ + rc = assuan_socket_connect (&ctx, sockname, 0); + } + if (rc) + rc = save_rc; + } +#endif /*HAVE_W32_SYSTEM*/ xfree (sockname); } else Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2008-11-20 21:54:47 UTC (rev 4881) +++ trunk/tools/gpgconf-comp.c 2008-12-05 12:01:01 UTC (rev 4882) @@ -599,15 +599,15 @@ { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "gnupg", "|NAME|use NAME as PC/SC driver", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "do not use the OpenSC layer", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "do not use the internal CCID driver", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "gnupg", "do not use a reader's keypad", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + { "card-timeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "|N|disconnect the card after N seconds of inactivity", + GC_ARG_TYPE_UINT32, GC_BACKEND_SCDAEMON }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, @@ -616,7 +616,7 @@ "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", N_("|FILE|write server mode logs to FILE"), + "gnupg", N_("|FILE|write a log to FILE"), GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON }, { "Security", From cvs at cvs.gnupg.org Fri Dec 5 17:31:40 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Dec 2008 17:31:40 +0100 Subject: [svn] GnuPG - r4883 - in trunk: common g10 sm Message-ID: Author: wk Date: 2008-12-05 17:31:39 +0100 (Fri, 05 Dec 2008) New Revision: 4883 Added: trunk/common/percent.c trunk/common/t-percent.c Modified: trunk/common/ChangeLog trunk/common/Makefile.am trunk/common/util.h trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/sm/ChangeLog trunk/sm/certdump.c trunk/sm/certreqgen.c Log: Add a custom prompt for the CSR generation. Add a new percent escape fucntion. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/common/ChangeLog 2008-12-05 16:31:39 UTC (rev 4883) @@ -1,5 +1,7 @@ 2008-12-05 Werner Koch + * percent.c, t-percent.c: New. + * exechelp.c (gnupg_spawn_process, gnupg_spawn_process_fd) (gnupg_spawn_process_detached) [W32]: Remove debug output. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/g10/ChangeLog 2008-12-05 16:31:39 UTC (rev 4883) @@ -1,3 +1,9 @@ +2008-12-05 Werner Koch + + * call-agent.c (percent_plus_escape): Rename to + my_percent_plus_escape and also escape the percent character. + Change all callers. + 2008-11-18 Werner Koch * gpg.c (build_lib_list): Remove. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/sm/ChangeLog 2008-12-05 16:31:39 UTC (rev 4883) @@ -1,3 +1,14 @@ +2008-12-05 Werner Koch + + * certreqgen.c (create_request): Provide a custom prompt for the + signing. + + * certdump.c (gpgsm_format_keydesc): Remove debug output. + (gpgsm_format_keydesc): Remove saving of errno as xfree is + supposed not to change it. Use the new percent_plus_escape + function which also fixes the issue that we did not escaped a + percent in the past. + 2008-11-18 Werner Koch * gpgsm.c (make_libversion): New. Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/common/Makefile.am 2008-12-05 16:31:39 UTC (rev 4883) @@ -52,6 +52,7 @@ yesno.c \ b64enc.c b64dec.c \ convert.c \ + percent.c \ miscellaneous.c \ xasprintf.c \ xreadline.c \ @@ -107,13 +108,14 @@ # # Module tests # -module_tests = t-convert t-gettime t-sysutils t-sexputil +module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil module_maint_tests = t-helpfile t-b64 t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) t_convert_LDADD = $(t_common_ldadd) +t_percent_LDADD = $(t_common_ldadd) t_gettime_LDADD = $(t_common_ldadd) t_sysutils_LDADD = $(t_common_ldadd) t_helpfile_LDADD = $(t_common_ldadd) Added: trunk/common/percent.c =================================================================== --- trunk/common/percent.c (rev 0) +++ trunk/common/percent.c 2008-12-05 16:31:39 UTC (rev 4883) @@ -0,0 +1,76 @@ +/* percent.c - Percent escaping + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include + +#include "util.h" + + +/* Create a newly alloced string from STRING with all spaces and + control characters converted to plus signs or %xx sequences. The + function returns the new string or NULL in case of a malloc + failure. + + Note that we also escape the quote character to work around a bug + in the mingw32 runtime which does not correcty handle command line + quoting. We correctly double the quote mark when calling a program + (i.e. gpg-protect-tool), but the pre-main code does not notice the + double quote as an escaped quote. We do this also on POSIX systems + for consistency. */ +char * +percent_plus_escape (const char *string) +{ + char *buffer, *p; + const char *s; + size_t length; + + for (length=1, s=string; *s; s++) + { + if (*s == '+' || *s == '\"' || *s == '%' + || *(const unsigned char *)s < 0x20) + length += 3; + else + length++; + } + + buffer = p = xtrymalloc (length); + if (!buffer) + return NULL; + + for (s=string; *s; s++) + { + if (*s == '+' || *s == '\"' || *s == '%' + || *(const unsigned char *)s < 0x20) + { + snprintf (p, 4, "%%%02X", *(unsigned char *)s); + p += 3; + } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; + + return buffer; + +} Added: trunk/common/t-percent.c =================================================================== --- trunk/common/t-percent.c (rev 0) +++ trunk/common/t-percent.c 2008-12-05 16:31:39 UTC (rev 4883) @@ -0,0 +1,97 @@ +/* t-percent.c - Module test for percent.c + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + +static void +test_percent_plus_escape (void) +{ + static struct { + const char *string; + const char *expect; + } tbl[] = { + { + "", + "" + }, { + "a", + "a", + }, { + " ", + "+", + }, { + " ", + "++" + }, { + "+ +", + "%2B+%2B" + }, { + "\" \"", + "%22+%22" + }, { + "%22", + "%2522" + }, { + "%% ", + "%25%25+" + }, { + "\n ABC\t", + "%0A+ABC%09" + }, { NULL, NULL } + }; + char *buf; + int i; + + for (i=0; tbl[i].string; i++) + { + buf = percent_plus_escape (tbl[i].string); + if (!buf) + { + fprintf (stderr, "out of core: %s\n", strerror (errno)); + exit (2); + } + if (strcmp (buf, tbl[i].expect)) + fail (i); + xfree (buf); + } +} + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_percent_plus_escape (); + + return 0; +} + Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/common/util.h 2008-12-05 16:31:39 UTC (rev 4883) @@ -199,7 +199,10 @@ char *buffer, size_t bufsize, size_t *buflen); char *hex2str_alloc (const char *hexstring, size_t *r_count); +/*-- percent.c --*/ +char *percent_plus_escape (const char *string); + /*-- homedir.c --*/ const char *standard_homedir (void); const char *default_homedir (void); Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/g10/call-agent.c 2008-12-05 16:31:39 UTC (rev 4883) @@ -148,15 +148,15 @@ escaping. Note that the provided buffer needs to be 3 times the size of ATEXT plus 1. Returns a pointer to the leading Nul in P. */ static char * -percent_plus_escape (char *p, const char *atext) +my_percent_plus_escape (char *p, const char *atext) { const unsigned char *s; for (s=atext; *s; s++) { - if (*s < ' ' || *s == '+') + if (*s < ' ' || *s == '+' || *s == '%') { - sprintf (p, "%%%02X", *s); + snprintf (p, 4, "%%%02X", *s); p += 3; } else if (*s == ' ') @@ -865,25 +865,25 @@ p = stpcpy (line, cmd); if (cache_id && *cache_id) - p = percent_plus_escape (p, cache_id); + p = my_percent_plus_escape (p, cache_id); else *p++ = 'X'; *p++ = ' '; if (err_msg && *err_msg) - p = percent_plus_escape (p, err_msg); + p = my_percent_plus_escape (p, err_msg); else *p++ = 'X'; *p++ = ' '; if (prompt && *prompt) - p = percent_plus_escape (p, prompt); + p = my_percent_plus_escape (p, prompt); else *p++ = 'X'; *p++ = ' '; if (desc_msg && *desc_msg) - p = percent_plus_escape (p, desc_msg); + p = my_percent_plus_escape (p, desc_msg); else *p++ = 'X'; *p = 0; Modified: trunk/sm/certdump.c =================================================================== --- trunk/sm/certdump.c 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/sm/certdump.c 2008-12-05 16:31:39 UTC (rev 4883) @@ -924,13 +924,12 @@ /* Create a key description for the CERT, this may be passed to the - pinentry. The caller must free the returned string. NULL may be + pinentry. The caller must free the returned string. NULL may be returned on error. */ char * gpgsm_format_keydesc (ksba_cert_t cert) { - char *name, *subject, *buffer, *p; - const char *s; + char *name, *subject, *buffer; ksba_isotime_t t; char created[20]; char expires[20]; @@ -939,10 +938,8 @@ char *orig_codeset; name = ksba_cert_get_subject (cert, 0); - log_printhex ("XXXX NAME: ", name, strlen (name)); subject = name? gpgsm_format_name2 (name, 0) : NULL; ksba_free (name); name = NULL; - log_printhex ("YYYY NAME: ", subject, strlen (subject)); sexp = ksba_cert_get_serial (cert); sn = sexp? gpgsm_format_serial (sexp) : NULL; @@ -975,38 +972,16 @@ if (!name) { - int save_errno = errno; xfree (subject); xfree (sn); - errno = save_errno; return NULL; } xfree (subject); xfree (sn); - buffer = p = xtrymalloc (strlen (name) * 3 + 1); - for (s=name; *s; s++) - { - /* We also escape the quote character to work around a bug in - the mingw32 runtime which does not correcty handle command - line quoting. We correctly double the quote mark when - calling a program (i.e. gpg-protect-tool), but the pre-main - code does not notice the double quote as an escaped - quote. */ - if (*s < ' ' || *s == '+' || *s == '\"') - { - sprintf (p, "%%%02X", *(unsigned char *)s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p = 0; + buffer = percent_plus_escape (name); xfree (name); - return buffer; } Modified: trunk/sm/certreqgen.c =================================================================== --- trunk/sm/certreqgen.c 2008-12-05 12:01:01 UTC (rev 4882) +++ trunk/sm/certreqgen.c 2008-12-05 16:31:39 UTC (rev 4883) @@ -788,6 +788,8 @@ gcry_sexp_release (s_pkey); bin2hex (grip, 20, hexgrip); + log_info ("about to sign CSR for key: &%s\n", hexgrip); + if (carddirect) rc = gpgsm_scd_pksign (ctrl, carddirect, NULL, gcry_md_read(md, GCRY_MD_SHA1), @@ -795,11 +797,23 @@ GCRY_MD_SHA1, &sigval, &siglen); else - rc = gpgsm_agent_pksign (ctrl, hexgrip, NULL, - gcry_md_read(md, GCRY_MD_SHA1), - gcry_md_get_algo_dlen (GCRY_MD_SHA1), - GCRY_MD_SHA1, - &sigval, &siglen); + { + char *orig_codeset; + char *desc; + + orig_codeset = i18n_switchto_utf8 (); + desc = percent_plus_escape + (_("To complete this certificate request please enter" + " the passphrase for the key you just created once" + " more.\n")); + i18n_switchback (orig_codeset); + rc = gpgsm_agent_pksign (ctrl, hexgrip, desc, + gcry_md_read(md, GCRY_MD_SHA1), + gcry_md_get_algo_dlen (GCRY_MD_SHA1), + GCRY_MD_SHA1, + &sigval, &siglen); + xfree (desc); + } if (rc) { log_error ("signing failed: %s\n", gpg_strerror (rc)); @@ -818,8 +832,8 @@ } } while (stopreason != KSBA_SR_READY); - + leave: gcry_md_close (md); ksba_certreq_release (cr); From cvs at cvs.gnupg.org Fri Dec 5 17:40:19 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Dec 2008 17:40:19 +0100 Subject: [svn] GnuPG - r4884 - trunk/po Message-ID: Author: wk Date: 2008-12-05 17:40:19 +0100 (Fri, 05 Dec 2008) New Revision: 4884 Modified: trunk/po/de.po Log: Typo fixes. Modified: trunk/po/de.po [not shown] From cvs at cvs.gnupg.org Fri Dec 5 19:53:07 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Dec 2008 19:53:07 +0100 Subject: [svn] gcry - r1371 - in trunk: cipher doc src tests Message-ID: Author: wk Date: 2008-12-05 19:53:06 +0100 (Fri, 05 Dec 2008) New Revision: 1371 Modified: trunk/cipher/ChangeLog trunk/cipher/dsa.c trunk/doc/gcrypt.texi trunk/src/ChangeLog trunk/src/global.c trunk/src/stdmem.c trunk/tests/ChangeLog trunk/tests/pubkey.c Log: Allow (transient-key) for DSA. Type fix. Made sure that gcry_free preserves ERRNO. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/cipher/ChangeLog 2008-12-05 18:53:06 UTC (rev 1371) @@ -1,3 +1,10 @@ +2008-12-05 Werner Koch + + * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine + the RNG quality needed. + (dsa_generate_ext): Parse the transient-key flag und pass it to + generate. + 2008-11-28 Werner Koch * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/src/ChangeLog 2008-12-05 18:53:06 UTC (rev 1371) @@ -1,3 +1,7 @@ +2008-12-05 Werner Koch + + * global.c (gcry_free): Save and restore ERRNO if set. + 2008-11-24 Werner Koch * sexp.c (get_internal_buffer): New. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/tests/ChangeLog 2008-12-05 18:53:06 UTC (rev 1371) @@ -1,3 +1,8 @@ +2008-12-05 Werner Koch + + * pubkey.c (get_dsa_key_new): Add arg transient_key. + (check_run): Use it. + 2008-12-03 Werner Koch * fipsdrv.c (run_dsa_pqg_gen): Facor code out into .. Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/cipher/dsa.c 2008-12-05 18:53:06 UTC (rev 1371) @@ -91,6 +91,7 @@ static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, + int transient_key, gcry_mpi_t **ret_factors); static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey); @@ -225,13 +226,16 @@ /* - Generate a DSA key pair with a key of size NBITS. + Generate a DSA key pair with a key of size NBITS. If transient_key + is true the key is generated using the standard RNG and not the + very secure one. + Returns: 2 structures filled with all needed values and an array with the n-1 factors of (p-1) */ static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, - gcry_mpi_t **ret_factors ) + int transient_key, gcry_mpi_t **ret_factors ) { gcry_mpi_t p; /* the prime */ gcry_mpi_t q; /* the 160 bit prime factor */ @@ -240,6 +244,7 @@ gcry_mpi_t x; /* the secret exponent */ gcry_mpi_t h, e; /* helper */ unsigned char *rndbuf; + gcry_random_level_t random_level; if (qbits) ; /* Caller supplied qbits. Use this value. */ @@ -261,9 +266,15 @@ if (nbits < 2*qbits || nbits > 15360) return GPG_ERR_INV_VALUE; - if (nbits < 1024 && fips_mode ()) - return GPG_ERR_INV_VALUE; + if (fips_mode ()) + { + if (nbits < 1024) + return GPG_ERR_INV_VALUE; + if (transient_key) + return GPG_ERR_INV_VALUE; + } + /* Generate the primes. */ p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); /* get q out of factors */ q = mpi_copy((*ret_factors)[0]); @@ -289,8 +300,10 @@ * 0 < x < q-1 * This must be a very good random number because this * is the secret part. */ - if( DBG_CIPHER ) - log_debug("choosing a random x "); + /* The random quality depends on the transient_key flag. */ + random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; + if (DBG_CIPHER) + log_debug("choosing a random x%s", transient_key? " (transient-key)":""); gcry_assert( qbits >= 160 ); x = mpi_alloc_secure( mpi_get_nlimbs(q) ); mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ @@ -300,11 +313,10 @@ if( DBG_CIPHER ) progress('.'); if( !rndbuf ) - rndbuf = gcry_random_bytes_secure( (qbits+7)/8, - GCRY_VERY_STRONG_RANDOM ); + rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level); else { /* Change only some of the higher bits (= 2 bytes)*/ - char *r = gcry_random_bytes_secure (2, GCRY_VERY_STRONG_RANDOM); + char *r = gcry_random_bytes_secure (2, random_level); memcpy(rndbuf, r, 2 ); gcry_free(r); } @@ -633,6 +645,7 @@ unsigned int qbits = 0; gcry_sexp_t deriveparms = NULL; gcry_sexp_t seedinfo = NULL; + int transient_key = 0; int use_fips186_2 = 0; int use_fips186 = 0; @@ -662,6 +675,15 @@ gcry_sexp_release (l1); } + /* Parse the optional transient-key flag. */ + l1 = gcry_sexp_find_token (genparms, "transient-key", 0); + if (l1) + { + transient_key = 1; + gcry_sexp_release (l1); + } + + /* Get the optional derive parameters. */ deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0); /* Parse the optional "use-fips186" flags. */ @@ -709,7 +731,7 @@ } else { - ec = generate (&sk, nbits, qbits, retfactors); + ec = generate (&sk, nbits, qbits, transient_key, retfactors); } if (!ec) { Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/doc/gcrypt.texi 2008-12-05 18:53:06 UTC (rev 1371) @@ -2708,10 +2708,11 @@ 15680 are valid as long as they are multiples of 8. @item transient-key -This is only meaningful for RSA keys. This is a flag with no value. If -given the RSA key is created using a faster and a somewhat less secure -random number generator. This flag may be used for keys which are only -used for a short time and do not require full cryptographic strength. +This is only meaningful for RSA and DSA keys. This is a flag with no +value. If given the RSA or DSA key is created using a faster and a +somewhat less secure random number generator. This flag may be used +for keys which are only used for a short time and do not require full +cryptographic strength. @item domain This is only meaningful for DLP algorithms. If specified keys are @@ -5563,7 +5564,7 @@ than 1024 bits. @item -The @code{transient-key} flag for RSA key generation is ignored. +The @code{transient-key} flag for RSA and DSA key generation is ignored. @item Support for the VIA Padlock engine is disabled. Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/src/global.c 2008-12-05 18:53:06 UTC (rev 1371) @@ -810,15 +810,24 @@ } void -gcry_free( void *p ) +gcry_free (void *p) { - if( !p ) + int save_errno; + + if (!p) return; + /* In case ERRNO is set we better save it so that the free machinery + may not accidently change ERRNO. We restore it only if it was + already set to comply with the usual C semantic for ERRNO. */ + save_errno = errno; if (free_func) free_func (p); else _gcry_private_free (p); + + if (save_errno) + errno = save_errno; } void * Modified: trunk/src/stdmem.c =================================================================== --- trunk/src/stdmem.c 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/src/stdmem.c 2008-12-05 18:53:06 UTC (rev 1371) @@ -207,12 +207,12 @@ /* - * Free a memory block allocated by this opr the secmem module + * Free a memory block allocated by this or the secmem module */ void _gcry_private_free (void *a) { - byte *p = a; + unsigned char *p = a; if (!p) return; Modified: trunk/tests/pubkey.c =================================================================== --- trunk/tests/pubkey.c 2008-12-05 11:58:25 UTC (rev 1370) +++ trunk/tests/pubkey.c 2008-12-05 18:53:06 UTC (rev 1371) @@ -351,14 +351,18 @@ *skey = sec_key; } + static void -get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; - rc = gcry_sexp_new - (&key_spec, "(genkey (dsa (nbits 4:1024)))", 0, 1); + rc = gcry_sexp_new (&key_spec, + transient_key + ? "(genkey (dsa (nbits 4:1024)(transient-key)))" + : "(genkey (dsa (nbits 4:1024)))", + 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); @@ -467,11 +471,21 @@ if (verbose) fprintf (stderr, "Generating DSA key.\n"); - get_dsa_key_new (&pkey, &skey); + get_dsa_key_new (&pkey, &skey, 0); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); + if (!gcry_fips_mode_active ()) + { + if (verbose) + fprintf (stderr, "Generating transient DSA key.\n"); + get_dsa_key_new (&pkey, &skey, 1); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + } + if (verbose) fprintf (stderr, "Generating DSA key (FIPS 186).\n"); get_dsa_key_fips186_new (&pkey, &skey); From cvs at cvs.gnupg.org Mon Dec 8 12:42:33 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Dec 2008 12:42:33 +0100 Subject: [svn] GnuPG - r4885 - trunk/doc Message-ID: Author: wk Date: 2008-12-08 12:42:33 +0100 (Mon, 08 Dec 2008) New Revision: 4885 Modified: trunk/doc/ChangeLog trunk/doc/DETAILS Log: Cleanups. Fixes bug 956. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-12-05 16:40:19 UTC (rev 4884) +++ trunk/doc/ChangeLog 2008-12-08 11:42:33 UTC (rev 4885) @@ -1,3 +1,10 @@ +2008-12-08 Werner Koch + + * DETAILS: Clarify the use of "trust" and "validity" as suggested + by Daniel Kahn Gillmor. Fix some typos. Remove the outdated + sections on packet headers and pipemode. Point to the libgcrypt + manual for a description of the key generation. + 2008-11-12 Werner Koch * gpg-agent.texi (Agent Options): Use Posix $() instead of Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2008-12-05 16:40:19 UTC (rev 4884) +++ trunk/doc/DETAILS 2008-12-08 11:42:33 UTC (rev 4885) @@ -39,7 +39,7 @@ tru = trust database information spk = signature subpacket - 2. Field: A letter describing the calculated trust. This is a single + 2. Field: A letter describing the calculated validity. This is a single letter, but be prepared that additional information may follow in some future versions. (not used for secret keys) o = Unknown (this key is new to the system) @@ -48,18 +48,23 @@ (deprecated - use the 'D' in field 12 instead) r = The key has been revoked e = The key has expired - - = Unknown trust (i.e. no value assigned) - q = Undefined trust + - = Unknown validity (i.e. no value assigned) + q = Undefined validity '-' and 'q' may safely be treated as the same value for most purposes - n = Don't trust this key at all - m = There is marginal trust in this key - f = The key is fully trusted - u = The key is ultimately trusted. This often means + n = The key is valid + m = The key is marginal valid. + f = The key is fully valid + u = The key is ultimately valid. This often means that the secret key is available, but any key may - be marked as ultimately trusted. + be marked as ultimately valid. - For X.509 certificates an 'u' is used for a trusted root + If the validity information is given for a UID or UAT + record, it describes the validity calculated based on this + user ID. If given for a key record it describes the best + validity taken from the best rated user ID. + + For X.509 certificates a 'u' is used for a trusted root certificate (i.e. for the trust anchor) and an 'f' for all other valid certificates. @@ -73,12 +78,12 @@ 5. Field: KeyID - 6. Field: Creation Date (in UTC). For UID and UAT records, this is the - self-signature date. Note that the date is usally printed - in seconds since epoch, however, we are migrating to an ISO - 8601 format (e.g. "19660205T091500"). This is currently - only relevant for X.509, A simple way to detect the format - is be scannning for the 'T'. + 6. Field: Creation Date (in UTC). For UID and UAT records, this is + the self-signature date. Note that the date is usally + printed in seconds since epoch, however, we are migrating + to an ISO 8601 format (e.g. "19660205T091500"). This is + currently only relevant for X.509. A simple way to detect + the new format is to scan for the 'T'. 7. Field: Key or user ID/user attribute expiration date or empty if none. @@ -92,7 +97,7 @@ This is a single letter, but be prepared that additional information may follow in some future versions. For trust signatures with a regular expression, this is the regular - expression value, quoted as in field 10. + expression value, quoted as in field 10. 10. Field: User-ID. The value is quoted like a C string to avoid control characters (the colon is quoted "\x3a"). @@ -103,11 +108,12 @@ An FPR record stores the fingerprint here. The fingerprint of an revocation key is stored here. -11. Field: Signature class. This is a 2 digit hexnumber followed by - either the letter 'x' for an exportable signature or the - letter 'l' for a local-only signature. - The class byte of an revocation key is also given here, - 'x' and 'l' ist used the same way. +11. Field: Signature class as per RFC-4880. This is a 2 digit + hexnumber followed by either the letter 'x' for an + exportable signature or the letter 'l' for a local-only + signature. The class byte of an revocation key is also + given here, 'x' and 'l' is used the same way. IT is not + used for X.509. 12. Field: Key capabilities: e = encrypt @@ -128,8 +134,8 @@ this is the same string as the fingerprint. The advantage of using this value is that it is guaranteed to have been been build by the same lookup algorithm as gpgsm uses. - For "uid" recods this lists the preferences n the sameway the - -edit menu does. + For "uid" records this lists the preferences in the same + way the gpg's --edit-key menu does. For "sig" records, this is the fingerprint of the key that issued the signature. Note that this is only filled in if the signature verified correctly. Note also that for @@ -156,8 +162,12 @@ !--------- index (eg. DSA goes from 0 to 3: p,q,g,y) -The "tru" trust database records have the fields: +Example for a "tru" trust base record: + tru:o:0:1166697654:1:3:1:5 + + The fields are: + 2: Reason for staleness of trust. If this field is empty, then the trustdb is not stale. This field may have multiple flags in it: @@ -174,12 +184,18 @@ GnuPG before version 1.4 used the classic trust model by default. GnuPG 1.4 and later uses the PGP trust model by default. - 4: Date trustdb was created in seconds since 1/1/1970. - 5: Date trustdb will expire in seconds since 1/1/1970. + 4: Date trustdb was created in seconds since 1970-01-01. + 5: Date trustdb will expire in seconds since 1970-01-01. + 6: Number of marginally trusted users to introduce a new key signer + (gpg's option --marginals-needed) + 7: Number of completely trusted users to introduce a new key signer. + (gpg's option --completes-needed) + 8: Maximum depth of a certification chain. + *gpg's option --max-cert-depth) The "spk" signature subpacket records have the fields: - 2: Subpacket number as per RFC-2440 and later. + 2: Subpacket number as per RFC-4880 and later. 3: Flags in hex. Currently the only two bits assigned are 1, to indicate that the subpacket came from the hashed part of the signature, and 2, to indicate the subpacket was marked critical. @@ -320,16 +336,19 @@ TRUST_FULLY [0 []] TRUST_ULTIMATE [0 []] For good signatures one of these status lines are emitted to - indicate how trustworthy the signature is. The error token - values are currently only emitted by gpgsm. VALIDATION_MODEL - describes the algorithm used to check the validity of the key. - The defaults are the standard Web of Trust model for gpg and the - the standard X.509 model for gpgsm. The defined values are + indicate the validity of the key used to create the signature. + The error token values are currently only emitted by gpgsm. + VALIDATION_MODEL describes the algorithm used to check the + validity of the key. The defaults are the standard Web of + Trust model for gpg and the the standard X.509 model for + gpgsm. The defined values are "pgp" for the standard PGP WoT. "shell" for the standard X.509 model. "chain" for the chain model. + Note that we use the term "TRUST_" in the status names for + historic reasons; we now speak of validity. PKA_TRUST_GOOD PKA_TRUST_BAD @@ -535,8 +554,8 @@ NOTATION_NAME NOTATION_DATA - name and string are %XX escaped; the data may be splitted - among several notation_data lines. + name and string are %XX escaped; the data may be split + among several NOTATION_DATA lines. USERID_HINT Give a hint about the user ID for a certain keyID. @@ -660,7 +679,7 @@ --status-fd as part of the required information is carried on the ATTRIBUTE status tag (see above). -The contents of the attribute data is specified by 2440bis, but for +The contents of the attribute data is specified by RFC 4880. For convenience, here is the Photo ID format, as it is currently the only attribute defined: @@ -693,25 +712,25 @@ pubkey: the third field contains the public key algorithmdcaiphers this version of GnuPG supports, separated by semicolons. The - algorithm numbers are as specified in RFC-2440. + algorithm numbers are as specified in RFC-4880. cfg:pubkey:1;2;3;16;17 cipher: the third field contains the symmetric ciphers this version of GnuPG supports, separated by semicolons. The cipher numbers - are as specified in RFC-2440. + are as specified in RFC-4880. cfg:cipher:2;3;4;7;8;9;10 digest: the third field contains the digest (hash) algorithms this version of GnuPG supports, separated by semicolons. The - digest numbers are as specified in RFC-2440. + digest numbers are as specified in RFC-4880. cfg:digest:1;2;3;8;9;10 compress: the third field contains the compression algorithms this version of GnuPG supports, separated by semicolons. The - algorithm numbers are as specified in RFC-2440. + algorithm numbers are as specified in RFC-4880. cfg:compress:0;1;2;3 @@ -728,35 +747,9 @@ Key generation ============== - Key generation shows progress by printing different characters to - stderr: - "." Last 10 Miller-Rabin tests failed - "+" Miller-Rabin test succeeded - "!" Reloading the pool with fresh prime numbers - "^" Checking a new value for the generator - "<" Size of one factor decreased - ">" Size of one factor increased + See the Libcrypt manual. - The prime number for Elgamal is generated this way: - 1) Make a prime number q of 160, 200, 240 bits (depending on the keysize) - 2) Select the length of the other prime factors to be at least the size - of q and calculate the number of prime factors needed - 3) Make a pool of prime numbers, each of the length determined in step 2 - 4) Get a new permutation out of the pool or continue with step 3 - if we have tested all permutations. - 5) Calculate a candidate prime p = 2 * q * p[1] * ... * p[n] + 1 - 6) Check that this prime has the correct length (this may change q if - it seems not to be possible to make a prime of the desired length) - 7) Check whether this is a prime using trial divisions and the - Miller-Rabin test. - 8) Continue with step 4 if we did not find a prime in step 7. - 9) Find a generator for that prime. - - This algorithm is based on Lim and Lee's suggestion from the - Crypto '97 proceedings p. 260. - - Unattended key generation ========================= This feature allows unattended generation of keys controlled by a @@ -1122,59 +1115,6 @@ -Packet Headers -=============== - -GNUPG uses PGP 2 packet headers and also understands OpenPGP packet header. -There is one enhancement used with the old style packet headers: - - CTB bits 10, the "packet-length length bits", have values listed in - the following table: - - 00 - 1-byte packet-length field - 01 - 2-byte packet-length field - 10 - 4-byte packet-length field - 11 - no packet length supplied, unknown packet length - - As indicated in this table, depending on the packet-length length - bits, the remaining 1, 2, 4, or 0 bytes of the packet structure field - are a "packet-length field". The packet-length field is a whole - number field. The value of the packet-length field is defined to be - the value of the whole number field. - - A value of 11 is currently used in one place: on compressed data. - That is, a compressed data block currently looks like , - where , binary 10 1000 11, is an indefinite-length packet. The - proper interpretation is "until the end of the enclosing structure", - although it should never appear outermost (where the enclosing - structure is a file). - -+ This will be changed with another version, where the new meaning of -+ the value 11 (see below) will also take place. -+ -+ A value of 11 for other packets enables a special length encoding, -+ which is used in case, where the length of the following packet can -+ not be determined prior to writing the packet; especially this will -+ be used if large amounts of data are processed in filter mode. -+ -+ It works like this: After the CTB (with a length field of 11) a -+ marker field is used, which gives the length of the following datablock. -+ This is a simple 2 byte field (MSB first) containing the amount of data -+ following this field, not including this length field. After this datablock -+ another length field follows, which gives the size of the next datablock. -+ A value of 0 indicates the end of the packet. The maximum size of a -+ data block is limited to 65534, thereby reserving a value of 0xffff for -+ future extensions. These length markers must be inserted into the data -+ stream just before writing the data out. -+ -+ This 2 byte field is large enough, because the application must buffer -+ this amount of data to prepend the length marker before writing it out. -+ Data block sizes larger than about 32k doesn't make any sense. Note -+ that this may also be used for compressed data streams, but we must use -+ another packet version to tell the application that it can not assume, -+ that this is the last packet. - - GNU extensions to the S2K algorithm =================================== S2K mode 101 is used to identify these extensions. @@ -1185,44 +1125,7 @@ 1002 - a stub to access smartcards (not used in 1.2.x) -Pipemode -======== -NOTE: This is deprecated and will be removed in future versions. -This mode can be used to perform multiple operations with one call to -gpg. It comes handy in cases where you have to verify a lot of -signatures. Currently we support only detached signatures. This mode -is a kludge to avoid running gpg n daemon mode and using Unix Domain -Sockets to pass the data to it. There is no easy portable way to do -this under Windows, so we use plain old pipes which do work well under -Windows. Because there is no way to signal multiple EOFs in a pipe we -have to embed control commands in the data stream: We distinguish -between a data state and a control state. Initially the system is in -data state but it won't accept any data. Instead it waits for -transition to control state which is done by sending a single '@' -character. While in control state the control command os expected and -this command is just a single byte after which the system falls back -to data state (but does not necesary accept data now). The simplest -control command is a '@' which just inserts this character into the -data stream. - -Here is the format we use for detached signatures: -"@<" - Begin of new stream -"@B" - Detached signature follows. - This emits a control packet (1,'B') - -"@t" - Signed text follows. - This emits the control packet (2, 'B') - -"@." - End of operation. The final control packet forces signature - verification -"@>" - End of stream - - - - - - Other Notes =========== * For packet version 3 we calculate the keyids this way: From cvs at cvs.gnupg.org Mon Dec 8 12:50:05 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Dec 2008 12:50:05 +0100 Subject: [svn] GnuPG - r4886 - trunk/po Message-ID: Author: wk Date: 2008-12-08 12:50:05 +0100 (Mon, 08 Dec 2008) New Revision: 4886 Modified: trunk/po/ChangeLog trunk/po/de.po Log: typo fixes. Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2008-12-08 11:42:33 UTC (rev 4885) +++ trunk/po/ChangeLog 2008-12-08 11:50:05 UTC (rev 4886) @@ -1,3 +1,7 @@ +2008-12-08 Werner Koch + + * de.po: Typo fixes. Reported by Daniel Leidert. + 2008-11-13 Werner Koch * de.po: Udpate. Modified: trunk/po/de.po [not shown] From cvs at cvs.gnupg.org Mon Dec 8 17:45:52 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Dec 2008 17:45:52 +0100 Subject: [svn] pinentry - r190 - in trunk: . qt qt4 Message-ID: Author: wk Date: 2008-12-08 17:45:52 +0100 (Mon, 08 Dec 2008) New Revision: 190 Modified: trunk/ChangeLog trunk/NEWS trunk/qt/main.cpp trunk/qt4/main.cpp Log: Fix utf-8 problem. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-11-12 11:21:39 UTC (rev 189) +++ trunk/ChangeLog 2008-12-08 16:45:52 UTC (rev 190) @@ -1,3 +1,8 @@ +2008-12-08 Werner Koch + + * qt/main.cpp (qt_cmd_handler) : Translate from utf8. + * qt4/main.cpp (qt_cmd_handler) : Translate from utf8. + 2008-11-12 Ludovic Rousseau (wk) * pinentry/pinentry.h (struct pinentry): Add field TITLE. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-11-12 11:21:39 UTC (rev 189) +++ trunk/NEWS 2008-12-08 16:45:52 UTC (rev 190) @@ -5,6 +5,9 @@ * Add Qt4 pinentry. + * Fix utf-8 problem in Qt pinentries. + + Noteworthy changes in version 0.7.5 (2008-02-15) ------------------------------------------------ Modified: trunk/qt/main.cpp =================================================================== --- trunk/qt/main.cpp 2008-11-12 11:21:39 UTC (rev 189) +++ trunk/qt/main.cpp 2008-12-08 16:45:52 UTC (rev 190) @@ -113,9 +113,13 @@ } else { - bool ret = QMessageBox::information (parent, "", pe->description, - pe->ok ? pe->ok : "OK", - pe->cancel ? pe->cancel : "Cancel"); + QString desc = QString::fromUtf8 (pe->description? pe->description :""); + QString ok = QString::fromUtf8 (pe->ok ? pe->ok : "OK"); + QString can = QString::fromUtf8 (pe->cancel ? pe->cancel : "Cancel"); + bool ret; + + ret = QMessageBox::information (parent, "", desc, ok, can ); + return !ret; } } Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2008-11-12 11:21:39 UTC (rev 189) +++ trunk/qt4/main.cpp 2008-12-08 16:45:52 UTC (rev 190) @@ -118,9 +118,13 @@ } else { - bool ret = QMessageBox::information (parent, "", pe->description, - pe->ok ? pe->ok : "OK", - pe->cancel ? pe->cancel : "Cancel"); + QString desc = QString::fromUtf8 (pe->description? pe->description :""); + QString ok = QString::fromUtf8 (pe->ok ? pe->ok : "OK"); + QString can = QString::fromUtf8 (pe->cancel ? pe->cancel : "Cancel"); + bool ret; + + ret = QMessageBox::information (parent, "", desc, ok, can ); + return !ret; } } From cvs at cvs.gnupg.org Mon Dec 8 18:11:26 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Dec 2008 18:11:26 +0100 Subject: [svn] GnuPG - r4887 - in trunk: . tools Message-ID: Author: wk Date: 2008-12-08 18:11:26 +0100 (Mon, 08 Dec 2008) New Revision: 4887 Modified: trunk/THANKS trunk/tools/ChangeLog trunk/tools/gpgkey2ssh.c Log: Fix bug 901. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2008-12-08 11:50:05 UTC (rev 4886) +++ trunk/tools/ChangeLog 2008-12-08 17:11:26 UTC (rev 4887) @@ -1,3 +1,9 @@ +2008-12-08 Werner Koch + + * gpgkey2ssh.c (main): Change order of output for RSA. Change name + of DSA identifier. Reported by Daniel Kahn Gillmor. This is + bug#901. + 2008-12-05 Werner Koch * gpg-connect-agent.c (opts): Use ARGPARSE_ macros. Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2008-12-08 11:50:05 UTC (rev 4886) +++ trunk/THANKS 2008-12-08 17:11:26 UTC (rev 4887) @@ -48,6 +48,7 @@ Daiki Ueno ueno at unixuser.org Dan Winship danw at helixcode.com Daniel Eisenbud eisenbud at cs.swarthmore.edu +Daniel Kahn Gillmor dkg at fifthhorseman dot net Daniel Koening dan at chaosdorf.de Daniel Leidert daniel leidert at wgdd.de Daniel Resare daniel at resare.com Modified: trunk/tools/gpgkey2ssh.c =================================================================== --- trunk/tools/gpgkey2ssh.c 2008-12-08 11:50:05 UTC (rev 4886) +++ trunk/tools/gpgkey2ssh.c 2008-12-08 17:11:26 UTC (rev 4887) @@ -1,4 +1,4 @@ -/* gpgkey2ssh.c - Converter ... +/* gpgkey2ssh.c - Converter (Debug helper) * Copyright (C) 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. @@ -17,6 +17,15 @@ * along with this program; if not, see . */ +/* + FIXME: This tool needs some cleanup: + + - Do not use assert() for error output. + - Add proper option parsing and standard options. + - retrieve_key_material needs to take the ordinal at field 1 in account. + 0 Write a man page. +*/ + #include #include @@ -272,11 +281,11 @@ { identifier = "ssh-rsa"; ret = key_to_blob (&blob, &blob_n, identifier, - &pkdbuf[0], &pkdbuf[1], NULL); + &pkdbuf[1], &pkdbuf[0], NULL); } else if (algorithm_id == 17) { - identifier = "ssh-dsa"; + identifier = "ssh-dss"; ret = key_to_blob (&blob, &blob_n, identifier, &pkdbuf[0], &pkdbuf[1], &pkdbuf[2], &pkdbuf[3], NULL); } From cvs at cvs.gnupg.org Mon Dec 8 20:10:42 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Dec 2008 20:10:42 +0100 Subject: [svn] GnuPG - r4888 - in trunk: agent doc scd Message-ID: Author: wk Date: 2008-12-08 20:10:42 +0100 (Mon, 08 Dec 2008) New Revision: 4888 Modified: trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/doc/gpg.texi trunk/scd/ChangeLog trunk/scd/scdaemon.c Log: Align ticker to the full or half second. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-12-08 17:11:26 UTC (rev 4887) +++ trunk/agent/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) @@ -1,3 +1,8 @@ +2008-12-08 Werner Koch + + * gpg-agent.c (handle_connections): Sync the ticker to the next + full second. This is bug#871. + 2008-12-05 Werner Koch * minip12.c (decrypt_block): Fix const modified of CHARSETS. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-12-08 17:11:26 UTC (rev 4887) +++ trunk/scd/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) @@ -1,3 +1,9 @@ +2008-12-08 Werner Koch + + * scdaemon.c (handle_connections): Sync ticker to the next full + interval. + (TIMERTICK_INTERVAL_USEC): Change to 500ms. + 2008-12-05 Werner Koch * app-openpgp.c (app_local_s): Add field ALGO_ATTR_CHANGE. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2008-12-08 17:11:26 UTC (rev 4887) +++ trunk/agent/gpg-agent.c 2008-12-08 19:10:42 UTC (rev 4888) @@ -1794,11 +1794,21 @@ FD_ZERO (&fdset); } - /* Create a timeout event if needed. */ + /* Create a timeout event if needed. To help with power saving + we syncronize the ticks to the next full second. */ if (!time_ev) - time_ev = pth_event (PTH_EVENT_TIME, - pth_timeout (TIMERTICK_INTERVAL, 0)); + { + pth_time_t nexttick; + nexttick = pth_timeout (TIMERTICK_INTERVAL, 0); + if (nexttick.tv_usec > 10) /* Use a 10 usec threshhold. */ + { + nexttick.tv_sec++; + nexttick.tv_usec = 0; + } + time_ev = pth_event (PTH_EVENT_TIME, nexttick); + } + /* POSIX says that fd_set should be implemented as a structure, thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2008-12-08 17:11:26 UTC (rev 4887) +++ trunk/doc/gpg.texi 2008-12-08 19:10:42 UTC (rev 4888) @@ -226,8 +226,8 @@ @item --decrypt @itemx -d @opindex decrypt -Decrypt the file given on the command line (or @code{stdin} if no file -is specified) and write it to stdout (or the file specified with +Decrypt the file given on the command line (or STDIN if no file +is specified) and write it to STDOUT (or the file specified with @option{--output}). If the decrypted file is signed, the signature is also verified. This command differs from the default operation, as it never writes to the filename which is included in the file and it rejects @@ -237,19 +237,19 @@ @opindex verify Assume that the first argument is a signed file or a detached signature and verify it without generating any output. With no arguments, the -signature packet is read from stdin. If only a sigfile is given, it may +signature packet is read from STDIN. If only a sigfile is given, it may be a complete signature or a detached signature, in which case the signed stuff is expected in a file without the ".sig" or ".asc" extension. With more than 1 argument, the first should be a detached signature and the remaining files are the signed stuff. To read the -signed stuff from stdin, use @samp{-} as the second filename. For +signed stuff from STDIN, use @samp{-} as the second filename. For security reasons a detached signature cannot read the signed material -from stdin without denoting it in the above way. +from STDIN without denoting it in the above way. @item --multifile @opindex multifile This modifies certain other commands to accept multiple files for -processing on the command line or read from stdin with each filename on +processing on the command line or read from STDIN with each filename on a separate line. This allows for many files to be processed at once. @option{--multifile} may currently be used along with @option{--verify}, @option{--encrypt}, and @option{--decrypt}. Note that @@ -394,7 +394,7 @@ @opindex export Either export all keys from all keyrings (default keyrings and those registered via option @option{--keyring}), or if at least one name is given, -those of the given name. The new keyring is written to stdout or to the +those of the given name. The new keyring is written to STDOUT or to the file given with option @option{--output}. Use together with @option{--armor} to mail those keys. @@ -487,14 +487,14 @@ @item --export-ownertrust @opindex export-ownertrust -Send the ownertrust values to stdout. This is useful for backup purposes +Send the ownertrust values to STDOUT. This is useful for backup purposes as these values are the only ones which can't be re-created from a corrupted trust DB. @item --import-ownertrust @opindex import-ownertrust Update the trustdb with the ownertrust values stored in @code{files} (or -stdin if not given); existing values will be overwritten. +STDIN if not given); existing values will be overwritten. @item --rebuild-keydb-caches @opindex rebuild-keydb-caches @@ -505,7 +505,7 @@ @item --print-md @code{algo} @itemx --print-mds @opindex print-md -Print message digest of algorithm ALGO for all given files or stdin. +Print message digest of algorithm ALGO for all given files or STDIN. With the second form (or a deprecated "*" as algo) digests for all available algorithms are printed. @@ -957,7 +957,12 @@ @opindex batch @opindex no-batch Use batch mode. Never ask, do not allow interactive commands. - at option{--no-batch} disables this option. + at option{--no-batch} disables this option. Note that even with a +filename given on the command line, gpg might still need to read from +STDIN (in particular if gpg figures that the input is a +detached signature and no data file has been specified). Thus if you +do not want to feed data via STDIN, you should connect STDIN to + at file{/dev/null}. @item --no-tty @opindex no-tty @@ -1104,7 +1109,7 @@ then the photo will be supplied to the viewer on standard input. The default viewer is "xloadimage -fork -quiet -title 'KeyID 0x%k' -stdin". Note that if your image viewer program is not secure, then +STDIN". Note that if your image viewer program is not secure, then executing it from GnuPG does not make it secure. @item --exec-path @code{string} @@ -2118,7 +2123,7 @@ @code{file}. @item --logger-fd @code{n} -Write log output to file descriptor @code{n} and not to stderr. +Write log output to file descriptor @code{n} and not to STDERR. @item --log-file @code{file} @itemx --logger-file @code{file} @@ -2310,7 +2315,7 @@ @item --passphrase-fd @code{n} Read the passphrase from file descriptor @code{n}. Only the first line will be read from file descriptor @code{n}. If you use 0 for @code{n}, -the passphrase will be read from stdin. This can only be used if only +the passphrase will be read from STDIN. This can only be used if only one passphrase is supplied. @ifclear gpgone Note that this passphrase is only used if the option @option{--batch} @@ -2771,7 +2776,7 @@ If you are going to verify detached signatures, make sure that the program knows about it; either give both filenames on the command line -or use @samp{-} to specify stdin. +or use @samp{-} to specify STDIN. @mansect interoperability @chapheading INTEROPERABILITY WITH OTHER OPENPGP PROGRAMS Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2008-12-08 17:11:26 UTC (rev 4887) +++ trunk/scd/scdaemon.c 2008-12-08 19:10:42 UTC (rev 4888) @@ -156,7 +156,7 @@ #define DEFAULT_PCSC_DRIVER "libpcsclite.so" #endif -/* The timer tick used for housekeeping stuff. We poll every 250ms to +/* The timer tick used for housekeeping stuff. We poll every 500ms to let the user immediately know a status change. This is not too good for power saving but given that there is no @@ -167,7 +167,7 @@ mechanism. Given that a native thread could only be used under W32 we don't do that at all. */ #define TIMERTICK_INTERVAL_SEC (0) -#define TIMERTICK_INTERVAL_USEC (250000) +#define TIMERTICK_INTERVAL_USEC (500000) /* Flag to indicate that a shutdown was requested. */ static int shutdown_pending; @@ -1152,11 +1152,25 @@ listen_fd = -1; } - /* Create a timeout event if needed. */ + /* Create a timeout event if needed. Round it up to the next + microsecond interval to help with power saving. */ if (!time_ev) - time_ev = pth_event (PTH_EVENT_TIME, - pth_timeout (TIMERTICK_INTERVAL_SEC, - TIMERTICK_INTERVAL_USEC)); + { + pth_time_t nexttick = pth_timeout (TIMERTICK_INTERVAL_SEC, + TIMERTICK_INTERVAL_USEC/2); + if ((nexttick.tv_usec % (TIMERTICK_INTERVAL_USEC/2)) > 10) + { + nexttick.tv_usec = ((nexttick.tv_usec + /(TIMERTICK_INTERVAL_USEC/2)) + + 1) * (TIMERTICK_INTERVAL_USEC/2); + if (nexttick.tv_usec >= 1000000) + { + nexttick.tv_sec++; + nexttick.tv_usec = 0; + } + } + time_ev = pth_event (PTH_EVENT_TIME, nexttick); + } /* POSIX says that fd_set should be implemented as a structure, thus a simple assignment is fine to copy the entire set. */ From cvs at cvs.gnupg.org Mon Dec 8 20:28:37 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 08 Dec 2008 20:28:37 +0100 Subject: [svn] gpgme - r1351 - trunk Message-ID: Author: marcus Date: 2008-12-08 20:28:36 +0100 (Mon, 08 Dec 2008) New Revision: 1351 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac Log: 2008-12-08 Marcus Brinkmann Release GPGME 1.1.8. * configure.ac: Bump API revision. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-12-03 14:27:52 UTC (rev 1350) +++ trunk/ChangeLog 2008-12-08 19:28:36 UTC (rev 1351) @@ -1,3 +1,9 @@ +2008-12-08 Marcus Brinkmann + + Release GPGME 1.1.8. + + * configure.ac: Bump API revision. + 2008-11-03 Marcus Brinkmann * configure.ac: Replace gpgme paths with src. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-12-03 14:27:52 UTC (rev 1350) +++ trunk/NEWS 2008-12-08 19:28:36 UTC (rev 1351) @@ -1,14 +1,10 @@ -Noteworthy changes in version 1.1.7 (unreleased) +Noteworthy changes in version 1.1.8 (2008-12-08) ------------------------------------------------ * SIGPIPE is now again ignored as described in the manual. Fixes regresion introduced with 1.1.6. - * Interface changes relative to the 1.1.7 release: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Noteworthy changes in version 1.1.7 (2008-10-17) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-12-03 14:27:52 UTC (rev 1350) +++ trunk/configure.ac 2008-12-08 19:28:36 UTC (rev 1351) @@ -32,7 +32,7 @@ # SVN version is the most recent one in a branch. To disable the SVN # version for the real release, set the my_issvn macro to no. m4_define(my_version, [1.1.8]) -m4_define(my_issvn, [yes]) +m4_define(my_issvn, [no]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) @@ -51,7 +51,7 @@ # Subtract 2 from this value if you want to make the LFS transition an # ABI break. [Note to self: Remove this comment with the next regular break.] LIBGPGME_LT_AGE=6 -LIBGPGME_LT_REVISION=5 +LIBGPGME_LT_REVISION=6 # If the API is changed in an incompatible way: increment the next counter. GPGME_CONFIG_API_VERSION=1 From cvs at cvs.gnupg.org Tue Dec 9 09:58:03 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 09:58:03 +0100 Subject: [svn] GnuPG - r4889 - in trunk: . agent doc g10 kbx scd sm tools Message-ID: Author: wk Date: 2008-12-09 09:58:02 +0100 (Tue, 09 Dec 2008) New Revision: 4889 Modified: trunk/NEWS trunk/agent/ChangeLog trunk/agent/command.c trunk/agent/gpg-agent.c trunk/agent/preset-passphrase.c trunk/agent/protect-tool.c trunk/doc/tools.texi trunk/g10/ChangeLog trunk/g10/cpr.c trunk/g10/gpg.c trunk/g10/gpgv.c trunk/g10/keylist.c trunk/kbx/ChangeLog trunk/kbx/kbxutil.c trunk/scd/ChangeLog trunk/scd/scdaemon.c trunk/sm/ChangeLog trunk/sm/gpgsm.c trunk/tools/ChangeLog trunk/tools/gpg-check-pattern.c trunk/tools/gpg-connect-agent.c trunk/tools/gpgconf.c trunk/tools/symcryptrun.c Log: Minor fixes. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/agent/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) @@ -1,3 +1,12 @@ +2008-12-09 Werner Koch + + * gpg-agent.c (main): Call i18n_init before init_common_subsystems. + * preset-passphrase.c (main): Ditto. + * protect-tool.c (main): Ditto. + + * command.c (cmd_preset_passphrase): Allow an arbitrary string for + the cache id. + 2008-12-08 Werner Koch * gpg-agent.c (handle_connections): Sync the ticker to the next Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/g10/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) @@ -1,3 +1,15 @@ +2008-12-09 Werner Koch + + * gpg.c (open_info_file): Add arg BINARY and adjust callers. + + * gpg.c (main): Call i18n_init before init_common_subsystems. + * gpgv.c (main): Ditto. + + * keylist.c (set_attrib_fd): Do not close ATTRIB_FP if it is the + log stream. + (set_attrib_fd) [W32]: Set to binary mode. + (dump_attribs): Flush the stream after writing. + 2008-12-05 Werner Koch * call-agent.c (percent_plus_escape): Rename to Modified: trunk/kbx/ChangeLog =================================================================== --- trunk/kbx/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/kbx/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) @@ -1,3 +1,7 @@ +2008-12-09 Werner Koch + + * kbxutil.c (main): Call i18n_init before init_common_subsystems. + 2008-11-20 Werner Koch * keybox-update.c (create_tmp_file) [USE_ONLY_8DOT3]: Use other Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/scd/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) @@ -1,3 +1,7 @@ +2008-12-09 Werner Koch + + * scdaemon.c (main): Call i18n_init before init_common_subsystems. + 2008-12-08 Werner Koch * scdaemon.c (handle_connections): Sync ticker to the next full Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/sm/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) @@ -1,3 +1,7 @@ +2008-12-09 Werner Koch + + * gpgsm.c (main): Call i18n_init before init_common_subsystems. + 2008-12-05 Werner Koch * certreqgen.c (create_request): Provide a custom prompt for the Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/tools/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) @@ -1,3 +1,11 @@ +2008-12-09 Werner Koch + + * gpg-check-pattern.c (main): Call i18n_init before + init_common_subsystems. + * gpg-connect-agent.c (main): Ditto. + * gpgconf.c (main): Ditto. + * symcryptrun.c (main): Ditto. + 2008-12-08 Werner Koch * gpgkey2ssh.c (main): Change order of output for RSA. Change name Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/NEWS 2008-12-09 08:58:02 UTC (rev 4889) @@ -41,7 +41,8 @@ * [w32] Fixed a race condition bteween gpg and gpgsm in the use of temporary file names. - * The gpg-preset-passphrase mechanism works again. + * The gpg-preset-passphrase mechanism works again. An arbitrary + string may now be used for a custom cache ID. * Admin PINs are cached again (bug in 2.0.9). Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/agent/command.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -1093,7 +1093,7 @@ return rc; } -/* PRESET_PASSPHRASE +/* PRESET_PASSPHRASE Set the cached passphrase/PIN for the key identified by the keygrip to passwd for the given time, where -1 means infinite and 0 means @@ -1104,7 +1104,6 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line) { int rc; - unsigned char grip[20]; char *grip_clear = NULL; char *passphrase = NULL; int ttl; @@ -1113,11 +1112,6 @@ if (!opt.allow_preset_passphrase) return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase"); - rc = parse_keygrip (ctx, line, grip); - if (rc) - return rc; - - /* FIXME: parse_keygrip should return a tail pointer. */ grip_clear = line; while (*line && (*line != ' ' && *line != '\t')) line++; Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/agent/gpg-agent.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -535,9 +535,9 @@ log_set_prefix ("gpg-agent", JNLIB_LOG_WITH_PREFIX|JNLIB_LOG_WITH_PID); /* Make sure that our subsystems are ready. */ + i18n_init (); init_common_subsystems (); - i18n_init (); /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ Modified: trunk/agent/preset-passphrase.c =================================================================== --- trunk/agent/preset-passphrase.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/agent/preset-passphrase.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -209,10 +209,9 @@ log_set_prefix ("gpg-preset-passphrase", 1); /* Make sure that our subsystems are ready. */ + i18n_init (); init_common_subsystems (); - i18n_init (); - opt_homedir = default_homedir (); pargs.argc = &argc; Modified: trunk/agent/protect-tool.c =================================================================== --- trunk/agent/protect-tool.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/agent/protect-tool.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -1059,10 +1059,9 @@ log_set_prefix ("gpg-protect-tool", 1); /* Make sure that our subsystems are ready. */ + i18n_init (); init_common_subsystems (); - i18n_init (); - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) { log_fatal( _("%s is too old (need %s, have %s)\n"), "libgcrypt", Modified: trunk/doc/tools.texi =================================================================== --- trunk/doc/tools.texi 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/doc/tools.texi 2008-12-09 08:58:02 UTC (rev 4889) @@ -979,7 +979,7 @@ .B gpg-preset-passphrase .RI [ options ] .RI [ command ] -.I keygrip +.I cache-id @end ifset @mansect description @@ -1009,15 +1009,20 @@ @command{gpg-preset-passphrase} is invoked this way: @example -gpg-preset-passphrase [options] [command] @var{keygrip} +gpg-preset-passphrase [options] [command] @var{cacheid} @end example - at var{keygrip} is a 40 character string of hexadecimal characters -identifying the key for which the passphrase should be set or cleared. -This keygrip is listed along with the key when running the command: - at code{gpgsm --dump-secret-keys}. One of the following command options -must be given: + at var{cacheid} is either a 40 character keygrip of hexadecimal +characters identifying the key for which the passphrase should be set +or cleared. The keygrip is listed along with the key when running the +command: @code{gpgsm --dump-secret-keys}. Alternatively an arbitrary +string may be used to identify a passphrase; it is suggested that such +a string is prefixed with the name of the application (e.g + at code{foo:12346}). + at noindent +One of the following command options must be given: + @table @gnupgtabopt @item --preset @opindex preset @@ -1027,7 +1032,7 @@ @item --forget @opindex forget -Flush the passphrase for the given keygrip from the cache. +Flush the passphrase for the given cache ID from the cache. @end table Modified: trunk/g10/cpr.c =================================================================== --- trunk/g10/cpr.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/g10/cpr.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -229,7 +229,7 @@ /* Print the BEGIN_SIGNING status message. If MD is not NULL it is - used retrieve the hash algorithms used for the message. */ + used to retrieve the hash algorithms used for the message. */ void write_status_begin_signing (gcry_md_hd_t md) { Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/g10/gpg.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -1036,9 +1036,9 @@ used with --status-file etc functions. Not generally useful but it avoids the riscos specific functions and well some Windows people might like it too. Prints an error message and returns -1 on - error. On success the file descriptor is returned. */ + error. On success the file descriptor is returned. */ static int -open_info_file (const char *fname, int for_write) +open_info_file (const char *fname, int for_write, int binary) { #ifdef __riscos__ return riscos_fdopenfile (fname, for_write); @@ -1048,10 +1048,16 @@ similar to the option file but in that case it is unlikely that sensitive information may be retrieved by means of error messages. */ + (void)fname; + (void)for_write; + (void)binary; return -1; #else int fd; + if (binary) + binary = MY_O_BINARY; + /* if (is_secured_filename (fname)) */ /* { */ /* fd = -1; */ @@ -1062,10 +1068,10 @@ do { if (for_write) - fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY, + fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY | binary, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); else - fd = open (fname, O_RDONLY | MY_O_BINARY); + fd = open (fname, O_RDONLY | binary); } while (fd == -1 && errno == EINTR); /* } */ @@ -1910,6 +1916,7 @@ log_set_prefix ("gpg", 1); /* Make sure that our subsystems are ready. */ + i18n_init(); init_common_subsystems (); /* Check that the libraries are suitable. Do it right here because the @@ -1929,7 +1936,6 @@ create_dotlock(NULL); /* Register locking cleanup. */ - i18n_init(); opt.command_fd = -1; /* no command fd */ opt.compress_level = -1; /* defaults to standard compress level */ @@ -2216,16 +2222,16 @@ case oDebugLevel: debug_level = pargs.r.ret_str; break; case oStatusFD: - set_status_fd( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); + set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); break; case oStatusFile: - set_status_fd ( open_info_file (pargs.r.ret_str, 1) ); + set_status_fd ( open_info_file (pargs.r.ret_str, 1, 0) ); break; case oAttributeFD: - set_attrib_fd(translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + set_attrib_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); break; case oAttributeFile: - set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) ); + set_attrib_fd ( open_info_file (pargs.r.ret_str, 1, 1) ); break; case oLoggerFD: log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); @@ -2522,14 +2528,14 @@ pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); break; case oPasswdFile: - pwfd = open_info_file (pargs.r.ret_str, 0); + pwfd = open_info_file (pargs.r.ret_str, 0, 1); break; case oPasswdRepeat: opt.passwd_repeat=pargs.r.ret_int; break; case oCommandFD: opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); break; case oCommandFile: - opt.command_fd = open_info_file (pargs.r.ret_str, 0); + opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1); break; case oCipherAlgo: def_cipher_string = xstrdup(pargs.r.ret_str); Modified: trunk/g10/gpgv.c =================================================================== --- trunk/g10/gpgv.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/g10/gpgv.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -147,10 +147,10 @@ log_set_prefix ("gpgv", 1); /* Make sure that our subsystems are ready. */ + i18n_init(); init_common_subsystems (); gnupg_init_signals (0, NULL); - i18n_init(); opt.command_fd = -1; /* no command fd */ opt.pgp2_workarounds = 1; Modified: trunk/g10/keylist.c =================================================================== --- trunk/g10/keylist.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/g10/keylist.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -24,6 +24,9 @@ #include #include #include +#ifdef HAVE_DOSISH_SYSTEM +#include /* for setmode() */ +#endif #include "gpg.h" #include "options.h" @@ -50,7 +53,8 @@ int oth_err; }; -static FILE *attrib_fp=NULL; +/* The stream used to write attribute packets to. */ +static FILE *attrib_fp = NULL; /**************** * List the keys @@ -745,6 +749,7 @@ } fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp); + fflush (attrib_fp); } } @@ -1609,29 +1614,35 @@ -void set_attrib_fd(int fd) +void +set_attrib_fd (int fd) { static int last_fd=-1; if ( fd != -1 && last_fd == fd ) return; - if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr ) + if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr + && attrib_fp != log_get_stream () ) fclose (attrib_fp); attrib_fp = NULL; if ( fd == -1 ) return; +#ifdef HAVE_DOSISH_SYSTEM + setmode ( fileno(fp) , O_BINARY ); +#endif if( fd == 1 ) attrib_fp = stdout; else if( fd == 2 ) attrib_fp = stderr; else - attrib_fp = fdopen( fd, "wb" ); - if( !attrib_fp ) { - log_fatal("can't open fd %d for attribute output: %s\n", - fd, strerror(errno)); - } - + attrib_fp = fdopen (fd, "wb"); + if (!attrib_fp) + { + log_fatal("can't open fd %d for attribute output: %s\n", + fd, strerror(errno)); + } + last_fd = fd; } Modified: trunk/kbx/kbxutil.c =================================================================== --- trunk/kbx/kbxutil.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/kbx/kbxutil.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -419,10 +419,9 @@ log_set_prefix ("kbxutil", 1); /* Make sure that our subsystems are ready. */ + i18n_init (); init_common_subsystems (); - i18n_init (); - /* Check that the libraries are suitable. Do it here because the option parsing may need services of the library. */ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/scd/scdaemon.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -364,9 +364,9 @@ log_set_prefix ("scdaemon", 1|4); /* Make sure that our subsystems are ready. */ + i18n_init (); init_common_subsystems (); - i18n_init (); /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/sm/gpgsm.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -869,6 +869,7 @@ log_set_prefix ("gpgsm", 1); /* Make sure that our subsystems are ready. */ + i18n_init(); init_common_subsystems (); /* Check that the libraries are suitable. Do it here because the @@ -888,7 +889,6 @@ gnupg_init_signals (0, emergency_cleanup); create_dotlock (NULL); /* register locking cleanup */ - i18n_init(); opt.def_cipher_algoid = "AES"; /*des-EDE3-CBC*/ Modified: trunk/tools/gpg-check-pattern.c =================================================================== --- trunk/tools/gpg-check-pattern.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/tools/gpg-check-pattern.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -168,10 +168,9 @@ log_set_prefix ("gpg-check-pattern", 1); /* Make sure that our subsystems are ready. */ + i18n_init (); init_common_subsystems (); - i18n_init (); - /* We need Libgcrypt for hashing. */ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) { Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/tools/gpg-connect-agent.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -1152,11 +1152,11 @@ log_set_prefix ("gpg-connect-agent", 1); /* Make sure that our subsystems are ready. */ + i18n_init(); init_common_subsystems (); assuan_set_assuan_err_source (0); - i18n_init(); opt.homedir = default_homedir (); opt.connect_flags = 1; /* Use extended connect mode. */ Modified: trunk/tools/gpgconf.c =================================================================== --- trunk/tools/gpgconf.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/tools/gpgconf.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -147,10 +147,9 @@ log_set_prefix ("gpgconf", 1); /* Make sure that our subsystems are ready. */ + i18n_init(); init_common_subsystems (); - i18n_init(); - /* Parse the command line. */ pargs.argc = &argc; pargs.argv = &argv; Modified: trunk/tools/symcryptrun.c =================================================================== --- trunk/tools/symcryptrun.c 2008-12-08 19:10:42 UTC (rev 4888) +++ trunk/tools/symcryptrun.c 2008-12-09 08:58:02 UTC (rev 4889) @@ -884,10 +884,9 @@ log_set_prefix ("symcryptrun", 1); /* Make sure that our subsystems are ready. */ + i18n_init(); init_common_subsystems (); - i18n_init(); - opt.homedir = default_homedir (); /* Check whether we have a config file given on the commandline */ From cvs at cvs.gnupg.org Tue Dec 9 11:43:23 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 11:43:23 +0100 Subject: [svn] GnuPG - r4890 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2008-12-09 11:43:22 +0100 (Tue, 09 Dec 2008) New Revision: 4890 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keygen.c Log: Check algo usage. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-09 08:58:02 UTC (rev 4889) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-09 10:43:22 UTC (rev 4890) @@ -1,3 +1,8 @@ +2008-12-09 Werner Koch + + * keygen.c (proc_parameter_file): Check that key and subkey usages + are allowed. + 2008-11-18 David Shaw * trustdb.c (validate_one_keyblock): Fix the trust signature @@ -330,8 +335,8 @@ 2007-01-31 David Shaw - * keygen.c (do_generate_keypair, proc_parameter_file, - generate_keypair, generate_subkeypair): Pass a timestamp through + * keygen.c (do_generate_keypair, proc_parameter_file) + (generate_keypair, generate_subkeypair): Pass a timestamp through to all the gen_xxx functions. * keyedit.c (sign_uids): Another multiple to single timestamp Modified: branches/STABLE-BRANCH-1-4/g10/keygen.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keygen.c 2008-12-09 08:58:02 UTC (rev 4889) +++ branches/STABLE-BRANCH-1-4/g10/keygen.c 2008-12-09 10:43:22 UTC (rev 4890) @@ -2196,42 +2196,62 @@ return -1; } - err=parse_parameter_usage (fname, para, pKEYUSAGE); - if(err==0) + err = parse_parameter_usage (fname, para, pKEYUSAGE); + if (!err) { /* Default to algo capabilities if key-usage is not provided */ - r=xmalloc_clear(sizeof(*r)); - r->key=pKEYUSAGE; - r->u.usage=openpgp_pk_algo_usage(algo); - r->next=para; - para=r; + r = xmalloc_clear(sizeof(*r)); + r->key = pKEYUSAGE; + r->u.usage = openpgp_pk_algo_usage(algo); + r->next = para; + para = r; } - else if(err==-1) + else if (err == -1) return -1; + else + { + r = get_parameter (para, pKEYUSAGE); + if (r && (r->u.usage & ~openpgp_pk_algo_usage (algo))) + { + log_error ("%s:%d: specified Key-Usage not allowed for algo %d\n", + fname, r->lnr, algo); + return -1; + } + } r = get_parameter( para, pSUBKEYTYPE ); if(r) { - algo=get_parameter_algo( para, pSUBKEYTYPE); - if(check_pubkey_algo(algo)) + algo = get_parameter_algo (para, pSUBKEYTYPE); + if (check_pubkey_algo (algo)) { - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); + log_error ("%s:%d: invalid algorithm\n", fname, r->lnr ); return -1; } - err=parse_parameter_usage (fname, para, pSUBKEYUSAGE); - if(err==0) + err = parse_parameter_usage (fname, para, pSUBKEYUSAGE); + if (!err) { /* Default to algo capabilities if subkey-usage is not provided */ - r=xmalloc_clear(sizeof(*r)); - r->key=pSUBKEYUSAGE; - r->u.usage=openpgp_pk_algo_usage(algo); - r->next=para; - para=r; + r = xmalloc_clear (sizeof(*r)); + r->key = pSUBKEYUSAGE; + r->u.usage = openpgp_pk_algo_usage (algo); + r->next = para; + para = r; } - else if(err==-1) + else if (err == -1) return -1; + else + { + r = get_parameter (para, pSUBKEYUSAGE); + if (r && (r->u.usage & ~openpgp_pk_algo_usage (algo))) + { + log_error ("%s:%d: specified Subkey-Usage not allowed" + " for algo %d\n", fname, r->lnr, algo); + return -1; + } + } } if( get_parameter_value( para, pUSERID ) ) From cvs at cvs.gnupg.org Tue Dec 9 11:46:30 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 11:46:30 +0100 Subject: [svn] GnuPG - r4891 - trunk/g10 Message-ID: Author: wk Date: 2008-12-09 11:46:29 +0100 (Tue, 09 Dec 2008) New Revision: 4891 Modified: trunk/g10/ChangeLog trunk/g10/keygen.c trunk/g10/keyserver.c trunk/g10/trustdb.c Log: Flush keyserver search output. Add trustdb chnages from 1.4. Check algo usage for batch key generation. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-09 10:43:22 UTC (rev 4890) +++ trunk/g10/ChangeLog 2008-12-09 10:46:29 UTC (rev 4891) @@ -1,5 +1,19 @@ 2008-12-09 Werner Koch + * keygen.c (proc_parameter_file): Check that key and subkey usages + are allowed. + +2008-12-09 David Shaw (wk) + + * trustdb.c (validate_one_keyblock): Fix the trust signature + calculations so that we lower the trust depth of signatures to fit + within the current chain, rather than discarding any signature + that does not fit within the trust depth. + +2008-12-09 Werner Koch + + * keyserver.c (show_prompt): Flush stdout. + * gpg.c (open_info_file): Add arg BINARY and adjust callers. * gpg.c (main): Call i18n_init before init_common_subsystems. Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2008-12-09 10:43:22 UTC (rev 4890) +++ trunk/g10/keygen.c 2008-12-09 10:46:29 UTC (rev 4891) @@ -2287,7 +2287,8 @@ } /* - * parse the usage parameter and set the keyflags. Return true on error. + * Parse the usage parameter and set the keyflags. Returns -1 on + * error, 0 for no usage given or 1 for usage available. */ static int parse_parameter_usage (const char *fname, @@ -2435,54 +2436,75 @@ algo=get_parameter_algo(para,pKEYTYPE); if (openpgp_pk_test_algo2 (algo, PUBKEY_USAGE_SIG)) { - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); + log_error ("%s:%d: invalid algorithm\n", fname, r->lnr ); return -1; } } else { - log_error("%s: no Key-Type specified\n",fname); + log_error ("%s: no Key-Type specified\n",fname); return -1; } - err=parse_parameter_usage (fname, para, pKEYUSAGE); - if(err==0) + err = parse_parameter_usage (fname, para, pKEYUSAGE); + if (!err) { /* Default to algo capabilities if key-usage is not provided */ - r=xmalloc_clear(sizeof(*r)); - r->key=pKEYUSAGE; - r->u.usage=openpgp_pk_algo_usage(algo); - r->next=para; - para=r; + r = xmalloc_clear(sizeof(*r)); + r->key = pKEYUSAGE; + r->u.usage = openpgp_pk_algo_usage(algo); + r->next = para; + para = r; } - else if(err==-1) + else if (err == -1) return -1; + else + { + r = get_parameter (para, pKEYUSAGE); + if (r && (r->u.usage & ~openpgp_pk_algo_usage (algo))) + { + log_error ("%s:%d: specified Key-Usage not allowed for algo %d\n", + fname, r->lnr, algo); + return -1; + } + } r = get_parameter( para, pSUBKEYTYPE ); if(r) { - algo=get_parameter_algo( para, pSUBKEYTYPE); + algo = get_parameter_algo (para, pSUBKEYTYPE); if (openpgp_pk_test_algo (algo)) { - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); + log_error ("%s:%d: invalid algorithm\n", fname, r->lnr ); return -1; } - err=parse_parameter_usage (fname, para, pSUBKEYUSAGE); - if(err==0) + err = parse_parameter_usage (fname, para, pSUBKEYUSAGE); + if (!err) { /* Default to algo capabilities if subkey-usage is not provided */ - r=xmalloc_clear(sizeof(*r)); - r->key=pSUBKEYUSAGE; - r->u.usage=openpgp_pk_algo_usage(algo); - r->next=para; - para=r; + r = xmalloc_clear (sizeof(*r)); + r->key = pSUBKEYUSAGE; + r->u.usage = openpgp_pk_algo_usage (algo); + r->next = para; + para = r; } - else if(err==-1) + else if (err == -1) return -1; + else + { + r = get_parameter (para, pSUBKEYUSAGE); + if (r && (r->u.usage & ~openpgp_pk_algo_usage (algo))) + { + log_error ("%s:%d: specified Subkey-Usage not allowed" + " for algo %d\n", fname, r->lnr, algo); + return -1; + } + } } + if( get_parameter_value( para, pUSERID ) ) have_user_id=1; else Modified: trunk/g10/keyserver.c =================================================================== --- trunk/g10/keyserver.c 2008-12-09 10:43:22 UTC (rev 4890) +++ trunk/g10/keyserver.c 2008-12-09 10:46:29 UTC (rev 4891) @@ -731,6 +731,8 @@ { char *answer; + fflush (stdout); + if(count && opt.command_fd==-1) { static int from=1; Modified: trunk/g10/trustdb.c =================================================================== --- trunk/g10/trustdb.c 2008-12-09 10:43:22 UTC (rev 4890) +++ trunk/g10/trustdb.c 2008-12-09 10:46:29 UTC (rev 4891) @@ -1,6 +1,6 @@ /* trustdb.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + * 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1935,54 +1935,78 @@ did not exist. This is safe for non-trust sigs as well since we don't accept a regexp on the sig unless it's a trust sig. */ - if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP || - (uidnode && check_regexp(kr->trust_regexp, - uidnode->pkt->pkt.user_id->name)))) + if (kr && (!kr->trust_regexp + || opt.trust_model != TM_PGP + || (uidnode + && check_regexp(kr->trust_regexp, + uidnode->pkt->pkt.user_id->name)))) { - if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth) - log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n", - uidnode->pkt->pkt.user_id->name,sig->trust_depth, - kr->trust_depth); - /* Are we part of a trust sig chain? We always favor the latest trust sig, rather than the greater or lesser trust sig or value. I could make a decent argument for any of these cases, but this seems to be what PGP does, and I'd like to be compatible. -dms */ - if(opt.trust_model==TM_PGP && sig->trust_depth - && pk->trust_timestamp<=sig->timestamp - && (sig->trust_depth<=kr->trust_depth - || kr->ownertrust==TRUST_ULTIMATE)) + if (opt.trust_model == TM_PGP + && sig->trust_depth + && pk->trust_timestamp <= sig->timestamp) { - /* If we got here, we know that: + unsigned char depth; - this is a trust sig. + /* If the depth on the signature is less than the + chain currently has, then use the signature depth + so we don't increase the depth beyond what the + signer wanted. If the depth on the signature is + more than the chain currently has, then use the + chain depth so we use as much of the signature + depth as the chain will permit. An ultimately + trusted signature can restart the depth to + whatever level it likes. */ - it's a newer trust sig than any previous trust - sig on this key (not uid). + if (sig->trust_depth < kr->trust_depth + || kr->ownertrust == TRUST_ULTIMATE) + depth = sig->trust_depth; + else + depth = kr->trust_depth; - it is legal in that it was either generated by an - ultimate key, or a key that was part of a trust - chain, and the depth does not violate the - original trust sig. + if (depth) + { + if(DBG_TRUST) + log_debug ("trust sig on %s, sig depth is %d," + " kr depth is %d\n", + uidnode->pkt->pkt.user_id->name, + sig->trust_depth, + kr->trust_depth); - if there is a regexp attached, it matched - successfully. - */ + /* If we got here, we know that: - if(DBG_TRUST) - log_debug("replacing trust value %d with %d and " - "depth %d with %d\n", - pk->trust_value,sig->trust_value, - pk->trust_depth,sig->trust_depth); + this is a trust sig. - pk->trust_value=sig->trust_value; - pk->trust_depth=sig->trust_depth-1; + it's a newer trust sig than any previous trust + sig on this key (not uid). - /* If the trust sig contains a regexp, record it - on the pk for the next round. */ - if(sig->trust_regexp) - pk->trust_regexp=sig->trust_regexp; + it is legal in that it was either generated by an + ultimate key, or a key that was part of a trust + chain, and the depth does not violate the + original trust sig. + + if there is a regexp attached, it matched + successfully. + */ + + if (DBG_TRUST) + log_debug ("replacing trust value %d with %d and " + "depth %d with %d\n", + pk->trust_value,sig->trust_value, + pk->trust_depth,depth); + + pk->trust_value = sig->trust_value; + pk->trust_depth = depth-1; + + /* If the trust sig contains a regexp, record it + on the pk for the next round. */ + if (sig->trust_regexp) + pk->trust_regexp = sig->trust_regexp; + } } if (kr->ownertrust == TRUST_ULTIMATE) From cvs at cvs.gnupg.org Tue Dec 9 12:54:44 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 12:54:44 +0100 Subject: [svn] GnuPG - r4892 - in trunk: . agent po Message-ID: Author: wk Date: 2008-12-09 12:54:40 +0100 (Tue, 09 Dec 2008) New Revision: 4892 Modified: trunk/ChangeLog trunk/README trunk/agent/command.c trunk/configure.ac trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po Log: Preparing a release candidate. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-12-09 10:46:29 UTC (rev 4891) +++ trunk/ChangeLog 2008-12-09 11:54:40 UTC (rev 4892) @@ -1,6 +1,6 @@ -2008-10-20 Werner Koch +2008-12-09 Werner Koch - * + Release 2.0.10rc1. 2008-10-17 Werner Koch Modified: trunk/README =================================================================== --- trunk/README 2008-12-09 10:46:29 UTC (rev 4891) +++ trunk/README 2008-12-09 11:54:40 UTC (rev 4892) @@ -58,11 +58,10 @@ If everything succeeds, you have a working GnuPG with support for S/MIME and smartcards. Note that there is no binary gpg but a gpg2 so -that this package won't conflict with a GnuPG 1.4 installation. gpg2 +that this package won't conflict with a GnuPG 1.4 installation. gpg2 behaves just like gpg. -In case of problem please ask on gnupg-users at gnupg.org for advise. Note -that this release is only expected to build on GNU and *BSD systems. +In case of problem please ask on gnupg-users at gnupg.org for advise. Note that the PKITS tests are always skipped unless you copy the PKITS test data file into the tests/pkits directory. Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2008-12-09 10:46:29 UTC (rev 4891) +++ trunk/agent/command.c 2008-12-09 11:54:40 UTC (rev 4892) @@ -1153,7 +1153,7 @@ rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); if (rc) - log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc)); + log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc)); return rc; } Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-12-09 10:46:29 UTC (rev 4891) +++ trunk/configure.ac 2008-12-09 11:54:40 UTC (rev 4892) @@ -24,8 +24,8 @@ # 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" right before creating a distribution. -m4_define([my_version], [2.0.10]) -m4_define([my_issvn], [yes]) +m4_define([my_version], [2.0.10rc1]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) AC_INIT([gnupg], Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Tue Dec 9 13:03:08 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 13:03:08 +0100 Subject: [svn] GnuPG - r4893 - in trunk: g10 po Message-ID: Author: wk Date: 2008-12-09 13:03:04 +0100 (Tue, 09 Dec 2008) New Revision: 4893 Modified: trunk/g10/keylist.c trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po Log: W32 fix Modified: trunk/g10/keylist.c =================================================================== --- trunk/g10/keylist.c 2008-12-09 11:54:40 UTC (rev 4892) +++ trunk/g10/keylist.c 2008-12-09 12:03:04 UTC (rev 4893) @@ -1630,7 +1630,7 @@ return; #ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(fp) , O_BINARY ); + setmode (fd, O_BINARY); #endif if( fd == 1 ) attrib_fp = stdout; Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Tue Dec 9 13:31:22 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 13:31:22 +0100 Subject: [svn] GnuPG - r4894 - tags Message-ID: Author: wk Date: 2008-12-09 13:31:22 +0100 (Tue, 09 Dec 2008) New Revision: 4894 Added: tags/gnupg-2.0.10rc1/ Log: Release version tag. From cvs at cvs.gnupg.org Tue Dec 9 13:32:54 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Dec 2008 13:32:54 +0100 Subject: [svn] GnuPG - r4895 - in trunk: . g10 Message-ID: Author: wk Date: 2008-12-09 13:32:53 +0100 (Tue, 09 Dec 2008) New Revision: 4895 Modified: trunk/configure.ac trunk/g10/ChangeLog trunk/g10/gpg.c Log: Minor bug fix. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-09 12:31:22 UTC (rev 4894) +++ trunk/g10/ChangeLog 2008-12-09 12:32:53 UTC (rev 4895) @@ -1,5 +1,9 @@ 2008-12-09 Werner Koch + * gpg.c (main) [IS_DEVELOPMENT_VERSION]: Fix strusage use. + +2008-12-09 Werner Koch + * keygen.c (proc_parameter_file): Check that key and subkey usages are allowed. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-12-09 12:31:22 UTC (rev 4894) +++ trunk/configure.ac 2008-12-09 12:32:53 UTC (rev 4895) @@ -24,8 +24,8 @@ # 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" right before creating a distribution. -m4_define([my_version], [2.0.10rc1]) -m4_define([my_issvn], [no]) +m4_define([my_version], [2.0.10]) +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)])) AC_INIT([gnupg], Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-12-09 12:31:22 UTC (rev 4894) +++ trunk/g10/gpg.c 2008-12-09 12:32:53 UTC (rev 4895) @@ -2936,15 +2936,15 @@ fprintf(stderr, "%s\n", strusage(15) ); } #ifdef IS_DEVELOPMENT_VERSION - if( !opt.batch ) + if (!opt.batch) { const char *s; - if((s=strusage(20))) + if((s=strusage(25))) log_info("%s\n",s); - if((s=strusage(21))) + if((s=strusage(26))) log_info("%s\n",s); - if((s=strusage(22))) + if((s=strusage(27))) log_info("%s\n",s); } #endif From cvs at cvs.gnupg.org Wed Dec 10 11:57:48 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 10 Dec 2008 11:57:48 +0100 Subject: [svn] GnuPG - r4896 - in trunk: scripts sm Message-ID: Author: wk Date: 2008-12-10 11:57:47 +0100 (Wed, 10 Dec 2008) New Revision: 4896 Modified: trunk/scripts/mail-to-translators trunk/sm/ChangeLog trunk/sm/gpgsm.c Log: fix a gpgconf default. Cosmetic changes. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-12-09 12:32:53 UTC (rev 4895) +++ trunk/sm/ChangeLog 2008-12-10 10:57:47 UTC (rev 4896) @@ -1,3 +1,10 @@ +2008-12-10 Werner Koch + + * gpgsm.c (our_cipher_test_algo): Use the GCRY constants as we now + require 1.4. + (our_md_test_algo): Ditto. Add SHA224. + (main) : Update default cipher algo. + 2008-12-09 Werner Koch * gpgsm.c (main): Call i18n_init before init_common_subsystems. Modified: trunk/scripts/mail-to-translators =================================================================== --- trunk/scripts/mail-to-translators 2008-12-09 12:32:53 UTC (rev 4895) +++ trunk/scripts/mail-to-translators 2008-12-10 10:57:47 UTC (rev 4896) @@ -48,15 +48,20 @@ more than one version of a project (we maintain 1.4 and 2.0) and thus I'd ask you *not to use the TP Robot* for GnuPG. +The release candidate for 2.0.10 is available at: + + ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/gnupg-2.0.10rc1.tar.bz2 + ftp://ftp.gnupg.org/gcrypt/alpha/gnupg/gnupg-2.0.10rc1.tar.bz2.sig + Output of msgfmt is: $(msgfmt --check --statistics $file 2>&1 | head) If you are not able to continue the translation work, I suggest to -pass this message on to another translator and drop a a short note to +pass this message on to another translator and drop a short note to gnupg-hackers at gnupg.org . -Thanks, +Happy hacking, Werner Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2008-12-09 12:32:53 UTC (rev 4895) +++ trunk/sm/gpgsm.c 2008-12-10 10:57:47 UTC (rev 4896) @@ -448,10 +448,10 @@ case GCRY_CIPHER_SERPENT128: case GCRY_CIPHER_SERPENT192: case GCRY_CIPHER_SERPENT256: - case 309 /*GCRY_CIPHER_SEED*/: - case 310 /*GCRY_CIPHER_CAMELLIA128*/: - case 311 /*GCRY_CIPHER_CAMELLIA192*/: - case 312 /*GCRY_CIPHER_CAMELLIA256*/: + case GCRY_CIPHER_SEED: + case GCRY_CIPHER_CAMELLIA128: + case GCRY_CIPHER_CAMELLIA192: + case GCRY_CIPHER_CAMELLIA256: return gcry_cipher_test_algo (algo); default: return 1; @@ -467,10 +467,11 @@ case GCRY_MD_MD5: case GCRY_MD_SHA1: case GCRY_MD_RMD160: + case GCRY_MD_SHA224: case GCRY_MD_SHA256: case GCRY_MD_SHA384: case GCRY_MD_SHA512: - case 305 /*GCRY_MD_WHIRLPOOL*/: + case GCRY_MD_WHIRLPOOL: return gcry_md_test_algo (algo); default: return 1; @@ -890,6 +891,8 @@ create_dotlock (NULL); /* register locking cleanup */ + /* Note: If you change this default cipher algorithm , please + remember to update the Gpgconflist entry as well. */ opt.def_cipher_algoid = "AES"; /*des-EDE3-CBC*/ opt.homedir = default_homedir (); @@ -1604,7 +1607,7 @@ #ifndef HAVE_W32_SYSTEM printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #endif - printf ("cipher-algo:%lu:\"3DES:\n", GC_OPT_FLAG_DEFAULT); + printf ("cipher-algo:%lu:\"AES:\n", GC_OPT_FLAG_DEFAULT); printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); From cvs at cvs.gnupg.org Wed Dec 10 13:23:31 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 10 Dec 2008 13:23:31 +0100 Subject: [svn] gcry - r1372 - in trunk: . cipher doc src tests Message-ID: Author: wk Date: 2008-12-10 13:23:30 +0100 (Wed, 10 Dec 2008) New Revision: 1372 Modified: trunk/NEWS trunk/cipher/ChangeLog trunk/cipher/dsa.c trunk/cipher/rijndael.c trunk/doc/ChangeLog trunk/doc/gcrypt.texi trunk/src/hmac256.c trunk/tests/ChangeLog trunk/tests/fipsdrv.c trunk/tests/pubkey.c Log: Allow speicification of domain parameters for DSA key generation. Doc updates. Allows the use of the strings AES-128, AES-192, AES-256 to specify AES algorithms. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/cipher/ChangeLog 2008-12-10 12:23:30 UTC (rev 1372) @@ -1,3 +1,14 @@ +2008-12-10 Werner Koch + + * dsa.c (generate): Add arg DOMAIN and use it if specified. + (generate_fips186): Ditto. + (dsa_generate_ext): Parse and check the optional "domain" + parameter and pass them to the generate functions. + + * rijndael.c (rijndael_names): Add "AES128" and "AES-128". + (rijndael192_names): Add "AES-192". + (rijndael256_names): Add "AES-256". + 2008-12-05 Werner Koch * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/doc/ChangeLog 2008-12-10 12:23:30 UTC (rev 1372) @@ -1,3 +1,8 @@ +2008-12-10 Werner Koch + + * gcrypt.texi (Cryptographic Functions): Explain the domain + parameter for key generation. + 2008-12-05 Werner Koch * gcrypt.texi: Updates for pubkey generation. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/tests/ChangeLog 2008-12-10 12:23:30 UTC (rev 1372) @@ -1,3 +1,13 @@ +2008-12-10 Werner Koch + + * pubkey.c (get_dsa_key_with_domain_new): New. + (get_dsa_key_fips186_with_domain_new): New. + (check_run): Call them. + +2008-12-08 Werner Koch + + * fipsdrv.c [W32]: Include fcntl.h. + 2008-12-05 Werner Koch * pubkey.c (get_dsa_key_new): Add arg transient_key. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/NEWS 2008-12-10 12:23:30 UTC (rev 1372) @@ -11,7 +11,10 @@ * In fips mode, RSA keys are now generated using the X9.31 algorithm and DSA keys using the FIPS 186-2 algorithm. + * The transient-key flag is now also supported for DSA key + generation. DSA domain parameters may given as well. + Noteworthy changes in version 1.4.3 (2008-09-18) ------------------------------------------------ Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/cipher/dsa.c 2008-12-10 12:23:30 UTC (rev 1372) @@ -46,6 +46,15 @@ } DSA_secret_key; +/* A structure used to hold domain parameters. */ +typedef struct +{ + gcry_mpi_t p; /* prime */ + gcry_mpi_t q; /* group order */ + gcry_mpi_t g; /* group generator */ +} dsa_domain_t; + + /* A sample 1024 bit DSA key used for the selftests. */ static const char sample_secret_key[] = "(private-key" @@ -92,6 +101,7 @@ unsigned int nbits, unsigned int qbits, int transient_key, + dsa_domain_t *domain, gcry_mpi_t **ret_factors); static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey); @@ -235,7 +245,7 @@ */ static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, - int transient_key, gcry_mpi_t **ret_factors ) + int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors ) { gcry_mpi_t p; /* the prime */ gcry_mpi_t q; /* the 160 bit prime factor */ @@ -274,33 +284,45 @@ return GPG_ERR_INV_VALUE; } - /* Generate the primes. */ - p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); - /* get q out of factors */ - q = mpi_copy((*ret_factors)[0]); - if( mpi_get_nbits(q) != qbits ) - BUG(); - - /* Find a generator g (h and e are helpers). - e = (p-1)/q */ - e = mpi_alloc( mpi_get_nlimbs(p) ); - mpi_sub_ui( e, p, 1 ); - mpi_fdiv_q( e, e, q ); - g = mpi_alloc( mpi_get_nlimbs(p) ); - h = mpi_alloc_set_ui( 1 ); /* we start with 2 */ - do + if (domain->p && domain->q && domain->g) { - mpi_add_ui( h, h, 1 ); - /* g = h^e mod p */ - gcry_mpi_powm( g, h, e, p ); - } - while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */ + /* Domain parameters are given; use them. */ + p = mpi_copy (domain->p); + q = mpi_copy (domain->q); + g = mpi_copy (domain->g); + gcry_assert (mpi_get_nbits (p) == nbits); + gcry_assert (mpi_get_nbits (q) == qbits); + h = mpi_alloc (0); + e = NULL; + } + else + { + /* Generate new domain parameters. */ + p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors); + /* Get q out of factors. */ + q = mpi_copy ((*ret_factors)[0]); + gcry_assert (mpi_get_nbits (q) == qbits); - /* Select a random number which has these properties: + /* Find a generator g (h and e are helpers). + e = (p-1)/q */ + e = mpi_alloc (mpi_get_nlimbs (p)); + mpi_sub_ui (e, p, 1); + mpi_fdiv_q (e, e, q); + g = mpi_alloc (mpi_get_nlimbs (p)); + h = mpi_alloc_set_ui (1); /* (We start with 2.) */ + do + { + mpi_add_ui (h, h, 1); + /* g = h^e mod p */ + gcry_mpi_powm (g, h, e, p); + } + while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */ + } + + /* Select a random number X with the property: * 0 < x < q-1 - * This must be a very good random number because this - * is the secret part. */ - /* The random quality depends on the transient_key flag. */ + * This must be a very good random number because this is the secret + * part. The random quality depends on the transient_key flag. */ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; if (DBG_CIPHER) log_debug("choosing a random x%s", transient_key? " (transient-key)":""); @@ -368,10 +390,13 @@ /* Generate a DSA key pair with a key of size NBITS using the algorithm given in FIPS-186-3. If USE_FIPS186_2 is true, FIPS-186-2 is used and thus the length is restricted to 1024/160. - If DERIVEPARMS are not NULL the may contain a seed value. */ + If DERIVEPARMS is not NULL it may contain a seed value. If domain + parameters are specified in DOMAIN, DERIVEPARMS may not be given + and NBITS and QBITS must match the specified domain parameters. */ static gpg_err_code_t generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, gcry_sexp_t deriveparms, int use_fips186_2, + dsa_domain_t *domain, int *r_counter, void **r_seed, size_t *r_seedlen, gcry_mpi_t *r_h) { @@ -419,49 +444,66 @@ else return GPG_ERR_INV_VALUE; - /* Get an initial seed value. */ - if (deriveparms) + if (domain->p && domain->q && domain->g) { - initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0); - if (initial_seed.sexp) - initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, - &initial_seed.seedlen); + /* Domain parameters are given; use them. */ + prime_p = mpi_copy (domain->p); + prime_q = mpi_copy (domain->q); + value_g = mpi_copy (domain->g); + gcry_assert (mpi_get_nbits (prime_p) == nbits); + gcry_assert (mpi_get_nbits (prime_q) == qbits); + gcry_assert (!deriveparms); + ec = 0; } + else + { + /* Generate new domain parameters. */ - /* Fixme: Enable 186-3 after it has been approved and after fixing - the generation function. */ -/* if (use_fips186_2) */ - (void)use_fips186_2; - ec = _gcry_generate_fips186_2_prime (nbits, qbits, - initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -/* else */ -/* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ -/* &prime_q, &prime_p, */ -/* r_counter, */ -/* r_seed, r_seedlen, NULL); */ - gcry_sexp_release (initial_seed.sexp); - if (ec) - goto leave; + /* Get an initial seed value. */ + if (deriveparms) + { + initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0); + if (initial_seed.sexp) + initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, + &initial_seed.seedlen); + } + + /* Fixme: Enable 186-3 after it has been approved and after fixing + the generation function. */ + /* if (use_fips186_2) */ + (void)use_fips186_2; + ec = _gcry_generate_fips186_2_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); + /* else */ + /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ + /* &prime_q, &prime_p, */ + /* r_counter, */ + /* r_seed, r_seedlen, NULL); */ + gcry_sexp_release (initial_seed.sexp); + if (ec) + goto leave; - /* Find a generator g (h and e are helpers). - e = (p-1)/q */ - value_e = mpi_alloc_like (prime_p); - mpi_sub_ui (value_e, prime_p, 1); - mpi_fdiv_q (value_e, value_e, prime_q ); - value_g = mpi_alloc_like (prime_p); - value_h = mpi_alloc_set_ui (1); - do - { - mpi_add_ui (value_h, value_h, 1); - /* g = h^e mod p */ - mpi_powm (value_g, value_h, value_e, prime_p); - } - while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */ + /* Find a generator g (h and e are helpers). + e = (p-1)/q */ + value_e = mpi_alloc_like (prime_p); + mpi_sub_ui (value_e, prime_p, 1); + mpi_fdiv_q (value_e, value_e, prime_q ); + value_g = mpi_alloc_like (prime_p); + value_h = mpi_alloc_set_ui (1); + do + { + mpi_add_ui (value_h, value_h, 1); + /* g = h^e mod p */ + mpi_powm (value_g, value_h, value_e, prime_p); + } + while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */ + } + /* Select a random number x with: 0 < x < q */ value_x = gcry_mpi_snew (qbits); do @@ -648,13 +690,17 @@ int transient_key = 0; int use_fips186_2 = 0; int use_fips186 = 0; - - + dsa_domain_t domain; + (void)algo; /* No need to check it. */ (void)evalue; /* Not required for DSA. */ + memset (&domain, 0, sizeof domain); + if (genparms) { + gcry_sexp_t domainsexp; + /* Parse the optional qbits element. */ l1 = gcry_sexp_find_token (genparms, "qbits", 0); if (l1) @@ -699,6 +745,48 @@ use_fips186_2 = 1; gcry_sexp_release (l1); } + + /* Check whether domain parameters are given. */ + domainsexp = gcry_sexp_find_token (genparms, "domain", 0); + if (domainsexp) + { + /* DERIVEPARMS can't be used together with domain + parameters. NBITS abnd QBITS may not be specified + because there values are derived from the domain + parameters. */ + if (deriveparms || qbits || nbits) + { + gcry_sexp_release (domainsexp); + gcry_sexp_release (deriveparms); + return GPG_ERR_INV_VALUE; + } + + /* Put all domain parameters into the domain object. */ + l1 = gcry_sexp_find_token (domainsexp, "p", 0); + domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + l1 = gcry_sexp_find_token (domainsexp, "q", 0); + domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + l1 = gcry_sexp_find_token (domainsexp, "g", 0); + domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + gcry_sexp_release (domainsexp); + + /* Check that all domain parameters are available. */ + if (!domain.p || !domain.q || !domain.g) + { + gcry_mpi_release (domain.p); + gcry_mpi_release (domain.q); + gcry_mpi_release (domain.g); + gcry_sexp_release (deriveparms); + return GPG_ERR_MISSING_VALUE; + } + + /* Get NBITS and QBITS from the domain parameters. */ + nbits = mpi_get_nbits (domain.p); + qbits = mpi_get_nbits (domain.q); + } } if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ()) @@ -709,10 +797,13 @@ gcry_mpi_t h_value; ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2, + &domain, &counter, &seed, &seedlen, &h_value); gcry_sexp_release (deriveparms); - if (!ec) + if (!ec && h_value) { + /* Format the seed-values unless domain parameters are used + for which a H_VALUE of NULL is an indication. */ ec = gpg_err_code (gcry_sexp_build (&seedinfo, NULL, "(seed-values(counter %d)(seed %b)(h %m))", @@ -731,8 +822,13 @@ } else { - ec = generate (&sk, nbits, qbits, transient_key, retfactors); + ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors); } + + gcry_mpi_release (domain.p); + gcry_mpi_release (domain.q); + gcry_mpi_release (domain.g); + if (!ec) { skey[0] = sk.p; Modified: trunk/cipher/rijndael.c =================================================================== --- trunk/cipher/rijndael.c 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/cipher/rijndael.c 2008-12-10 12:23:30 UTC (rev 1372) @@ -1174,6 +1174,8 @@ static const char *rijndael_names[] = { "RIJNDAEL", + "AES128", + "AES-128", NULL }; @@ -1199,6 +1201,7 @@ static const char *rijndael192_names[] = { "RIJNDAEL192", + "AES-192", NULL }; @@ -1224,6 +1227,7 @@ static const char *rijndael256_names[] = { "RIJNDAEL256", + "AES-256", NULL }; Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/doc/gcrypt.texi 2008-12-10 12:23:30 UTC (rev 1372) @@ -2726,22 +2726,21 @@ (domain (p @var{p-mpi}) (q @var{q-mpi}) - (g @var{q-mpi}) - (seed @var{seed-mpi}) - (counter @var{counter-mpi}) - (h @var{h-mpi})))) + (g @var{q-mpi})))) @end example -The @code{seed}, @code{counter} and @code{h} domain parameters are -optional and currently not used. + at code{nbits} and @code{qbits} may not be specified because they are +derived from the domain parameters. @item derive-parms -This is currently only meaningful for RSA keys. If given, it is used -to derive the RSA keys using the given parameters. This is in general -only useful for key generation tests. If given for an RSA key the -X9.31 key generation algorithm is used even if libgcrypt is not in -FIPS mode. +This is currently only implemented for RSA and DSA keys. It is not +allowed to use this together with a @code{domain} specification. If +given, it is used to derive the keys using the given parameters. +If given for an RSA key the X9.31 key generation algorithm is used +even if libgcrypt is not in FIPS mode. If given for a DSA key, the +FIPS 186 algorithm is used even if libgcrypt is not in FIPS mode. + @example (genkey (rsa @@ -2762,6 +2761,15 @@ 321DE34A#)))) @end example + at example +(genkey + (dsa + (nbits 4:1024) + (derive-parms + (seed @var{seed-mpi})))) + at end example + + @item use-x931 @cindex X9.31 Force the use of the ANSI X9.31 key generation algorithm instead of Modified: trunk/src/hmac256.c =================================================================== --- trunk/src/hmac256.c 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/src/hmac256.c 2008-12-10 12:23:30 UTC (rev 1372) @@ -19,7 +19,7 @@ /* This is a standalone HMAC-SHA-256 implementation based on the code - from ../cipher/sha256.c. It is a second implementarion to allow + from ../cipher/sha256.c. It is a second implementation to allow comparing against the standard implementations and to be used for internal consistency checks. It should not be used for sensitive data because no mechanisms to clear the stack etc are used. Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/tests/fipsdrv.c 2008-12-10 12:23:30 UTC (rev 1372) @@ -26,7 +26,9 @@ #include #include #include -#ifndef HAVE_W32_SYSTEM +#ifdef HAVE_W32_SYSTEM +# include /* We need setmode(). */ +#else # include #endif #include Modified: trunk/tests/pubkey.c =================================================================== --- trunk/tests/pubkey.c 2008-12-05 18:53:06 UTC (rev 1371) +++ trunk/tests/pubkey.c 2008-12-10 12:23:30 UTC (rev 1372) @@ -418,7 +418,93 @@ *skey = sec_key; } + static void +get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + "(genkey (dsa (transient-key)(domain" + "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" + "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" + "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" + "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" + "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" + "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" + "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" + "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" + "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" + ")))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + +static void +get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + "(genkey (dsa (transient-key)(use-fips186)(domain" + "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" + "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" + "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" + "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" + "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" + "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" + "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" + "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" + "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" + ")))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void check_run (void) { gpg_error_t err; @@ -492,6 +578,20 @@ /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key with given domain.\n"); + get_dsa_key_with_domain_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n"); + get_dsa_key_fips186_with_domain_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); } From cvs at cvs.gnupg.org Wed Dec 10 13:41:15 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 10 Dec 2008 13:41:15 +0100 Subject: [svn] GnuPG - r4897 - in trunk: agent doc Message-ID: Author: wk Date: 2008-12-10 13:41:15 +0100 (Wed, 10 Dec 2008) New Revision: 4897 Modified: trunk/agent/ChangeLog trunk/agent/command.c trunk/doc/gpg-agent.texi Log: Add option --no-ask for GET_PASSPHRASE. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-12-10 10:57:47 UTC (rev 4896) +++ trunk/agent/ChangeLog 2008-12-10 12:41:15 UTC (rev 4897) @@ -1,3 +1,7 @@ +2008-12-10 Werner Koch + + * command.c (cmd_get_passphrase): Implement option --no-ask. + 2008-12-09 Werner Koch * gpg-agent.c (main): Call i18n_init before init_common_subsystems. Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2008-12-10 10:57:47 UTC (rev 4896) +++ trunk/agent/command.c 2008-12-10 12:41:15 UTC (rev 4897) @@ -836,7 +836,7 @@ } -/* GET_PASSPHRASE [--data] [--check] +/* GET_PASSPHRASE [--data] [--check] [--no-ask] [ ] This function is usually used to ask for a passphrase to be used @@ -853,6 +853,10 @@ If the option "--check" is used the passphrase constraints checks as implemented by gpg-agent are applied. A check is not done if the passphrase has been found in the cache. + + If the option "--no-ask" is used and the passphrase is not in the + cache the user will not be asked to enter a passphrase but the error + code GPG_ERR_NO_DATA is returned. */ static int @@ -865,10 +869,11 @@ char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL; char *p; void *cache_marker; - int opt_data, opt_check; + int opt_data, opt_check, opt_no_ask; opt_data = has_option (line, "--data"); opt_check = has_option (line, "--check"); + opt_no_ask = has_option (line, "--no-ask"); line = skip_options (line); cacheid = line; @@ -920,6 +925,8 @@ rc = send_back_passphrase (ctx, opt_data, pw); agent_unlock_cache_entry (&cache_marker); } + else if (opt_no_ask) + rc = gpg_error (GPG_ERR_NO_DATA); else { /* Note, that we only need to replace the + characters and Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2008-12-10 10:57:47 UTC (rev 4896) +++ trunk/doc/gpg-agent.texi 2008-12-10 12:41:15 UTC (rev 4897) @@ -1036,7 +1036,7 @@ clients to use the agent with minimum effort. @example - GET_PASSPHRASE [--data] [--check] @var{cache_id} [@var{error_message} @var{prompt} @var{description}] + GET_PASSPHRASE [--data] [--check] [--no-ask] @var{cache_id} [@var{error_message} @var{prompt} @var{description}] @end example @var{cache_id} is expected to be a string used to identify a cached @@ -1067,6 +1067,11 @@ constraints checks are applied. A check is not done if the passphrase has been found in the cache. +If the option @option{--no-ask} is used and the passphrase is not in the +cache the user will not be asked to enter a passphrase but the error +code @code{GPG_ERR_NO_DATA} is returned. + + @example CLEAR_PASSPHRASE @var{cache_id} @end example From cvs at cvs.gnupg.org Wed Dec 10 15:50:58 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 10 Dec 2008 15:50:58 +0100 Subject: [svn] gcry - r1373 - in trunk: src tests Message-ID: Author: wk Date: 2008-12-10 15:50:57 +0100 (Wed, 10 Dec 2008) New Revision: 1373 Modified: trunk/src/ChangeLog trunk/src/hmac256.c trunk/tests/ChangeLog trunk/tests/basic.c Log: Fix for big endian hosts. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-12-10 12:23:30 UTC (rev 1372) +++ trunk/src/ChangeLog 2008-12-10 14:50:57 UTC (rev 1373) @@ -1,3 +1,7 @@ +2008-12-10 Werner Koch + + * hmac256.c (finalize): Fix for big endian hosts. + 2008-12-05 Werner Koch * global.c (gcry_free): Save and restore ERRNO if set. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-10 12:23:30 UTC (rev 1372) +++ trunk/tests/ChangeLog 2008-12-10 14:50:57 UTC (rev 1373) @@ -1,5 +1,8 @@ 2008-12-10 Werner Koch + * basic.c (main): Check for error after running self-test in + non-fips mode. + * pubkey.c (get_dsa_key_with_domain_new): New. (get_dsa_key_fips186_with_domain_new): New. (check_run): Call them. Modified: trunk/src/hmac256.c =================================================================== --- trunk/src/hmac256.c 2008-12-10 12:23:30 UTC (rev 1372) +++ trunk/src/hmac256.c 2008-12-10 14:50:57 UTC (rev 1373) @@ -270,14 +270,8 @@ /* Store the digest into hd->buf. */ p = hd->buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *p++ = hd->h##a; *p++ = hd->h##a >> 8; \ - *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0) -#else /* little endian */ #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) - -#endif X(0); X(1); X(2); Modified: trunk/tests/basic.c =================================================================== --- trunk/tests/basic.c 2008-12-10 12:23:30 UTC (rev 1372) +++ trunk/tests/basic.c 2008-12-10 14:50:57 UTC (rev 1373) @@ -2168,7 +2168,8 @@ else { /* If in standard mode, run selftests. */ - gcry_control (GCRYCTL_SELFTEST, 0); + if (gcry_control (GCRYCTL_SELFTEST, 0)) + fail ("running self-test failed\n"); } if (verbose) From cvs at cvs.gnupg.org Thu Dec 11 15:54:25 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Dec 2008 15:54:25 +0100 Subject: [svn] gcry - r1374 - trunk/tests Message-ID: Author: wk Date: 2008-12-11 15:54:25 +0100 (Thu, 11 Dec 2008) New Revision: 1374 Modified: trunk/tests/ChangeLog trunk/tests/cavs_driver.pl trunk/tests/fipsdrv.c Log: Add fipsdriv mode rsa-derive. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-10 14:50:57 UTC (rev 1373) +++ trunk/tests/ChangeLog 2008-12-11 14:54:25 UTC (rev 1374) @@ -1,3 +1,8 @@ +2008-12-11 Werner Koch + + * fipsdrv.c (run_rsa_derive): New. + (main): Add mode rsa-derive. + 2008-12-10 Werner Koch * basic.c (main): Check for error after running self-test in Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2008-12-10 14:50:57 UTC (rev 1373) +++ trunk/tests/cavs_driver.pl 2008-12-11 14:54:25 UTC (rev 1374) @@ -135,6 +135,24 @@ # return en/decrypted data in hex form my $encdec; +# +# Derive an RSA key from the given X9.31 parameters. +# $1: modulus size +# $2: E in hex form +# $3: Xp1 in hex form +# $4: Xp2 in hex form +# $5: Xp in hex form +# $6: Xq1 in hex form +# $7: Xq2 in hex form +# $8: Xq in hex form +# return: string with the calculated values in hex format, where each value +# is separated from the previous with a \n in the following order: +# P\n +# Q\n +# D\n +my $rsa_derive; + + # Sign a message with RSA # $1: data to be signed in hex form # $2: Hash algo @@ -358,6 +376,33 @@ } +sub libgcrypt_rsa_derive($$$$$$$$) { + my $n = shift; + my $e = shift; + my $xp1 = shift; + my $xp2 = shift; + my $xp = shift; + my $xq1 = shift; + my $xq2 = shift; + my $xq = shift; + my $sexp; + my @tmp; + + $n = sprintf ("%u", $n); + $e = sprintf ("%u", $e); + $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" + . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")" + . "(derive-parms" + . "(Xp1 #$xp1#)" + . "(Xp2 #$xp2#)" + . "(Xp #$xp#)" + . "(Xq1 #$xq1#)" + . "(Xq2 #$xq2#)" + . "(Xq #$xq#))))\n"; + + return pipe_through_program($sexp, "fipsdrv rsa-derive"); +} + sub libgcrypt_rsa_sign($$$) { my $data = shift; my $hashalgo = shift; Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2008-12-10 14:50:57 UTC (rev 1373) +++ trunk/tests/fipsdrv.c 2008-12-11 14:54:25 UTC (rev 1374) @@ -164,7 +164,23 @@ putc ('\n', stderr); } +/* static void */ +/* show_sexp (const char *prefix, gcry_sexp_t a) */ +/* { */ +/* char *buf; */ +/* size_t size; */ +/* if (prefix) */ +/* fputs (prefix, stderr); */ +/* size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */ +/* buf = gcry_xmalloc (size); */ + +/* gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */ +/* fprintf (stderr, "%.*s", (int)size, buf); */ +/* gcry_free (buf); */ +/* } */ + + /* Convert STRING consisting of hex characters into its binary representation and store that at BUFFER. BUFFER needs to be of LENGTH bytes. The function checks that the STRING will convert @@ -1261,7 +1277,72 @@ gcry_md_close (hd); } + +/* Derive an RSA key using the S-expression in (DATA,DATALEN). This + S-expression is used directly as input to gcry_pk_genkey. The + result is printed to stdout with one parameter per line in hex + format and in this order: p, q, d. */ +static void +run_rsa_derive (const void *data, size_t datalen) +{ + gpg_error_t err; + gcry_sexp_t s_keyspec, s_key, s_top, l1; + gcry_mpi_t mpi; + const char *parmlist; + int idx; + + if (!datalen) + err = gpg_error (GPG_ERR_NO_DATA); + else + err = gcry_sexp_new (&s_keyspec, data, datalen, 1); + if (err) + die ("gcry_sexp_new failed for RSA key derive: %s\n", + gpg_strerror (err)); + + err = gcry_pk_genkey (&s_key, s_keyspec); + if (err) + die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (s_keyspec); + + /* P and Q might have been swapped but we need to to return them in + the proper order. Build the parameter list accordingly. */ + parmlist = "pqd"; + s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0); + if (s_top) + { + l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0); + if (l1) + parmlist = "qpd"; + gcry_sexp_release (l1); + gcry_sexp_release (s_top); + } + + /* Parse and print the parameters. */ + l1 = gcry_sexp_find_token (s_key, "private-key", 0); + s_top = gcry_sexp_find_token (l1, "rsa", 0); + gcry_sexp_release (l1); + if (!s_top) + die ("private-key part not found in result\n"); + + for (idx=0; parmlist[idx]; idx++) + { + l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); + mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + if (!mpi) + die ("parameter %c missing in private-key\n", parmlist[idx]); + print_mpi_line (mpi, 1); + gcry_mpi_release (mpi); + } + + gcry_sexp_release (s_top); + gcry_sexp_release (s_key); +} + + + static size_t compute_tag_length (size_t n) { @@ -1879,8 +1960,8 @@ ("Usage: " PGM " [OPTIONS] MODE [FILE]\n" "Run a crypto operation using hex encoded input and output.\n" "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify},\n" - " dsa-{pqg-gen,gen,sign,verify}\n" + " encrypt, decrypt, digest, random, hmac-sha,\n" + " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" "OPTIONS:\n" " --verbose Print additional information\n" " --binary Input and output is in binary form\n" @@ -2041,6 +2122,10 @@ if (!argc || argc > 2) usage (0); mode_string = *argv; + + if (!strcmp (mode_string, "rsa-derive")) + binary_input = 1; + if (argc == 2 && strcmp (argv[1], "-")) { input = fopen (argv[1], binary_input? "rb":"r"); @@ -2258,6 +2343,12 @@ gcry_free (key_buffer); } + else if (!strcmp (mode_string, "rsa-derive")) + { + if (!data) + die ("no data available (do not use --chunk)\n"); + run_rsa_derive (data, datalen); + } else if (!strcmp (mode_string, "rsa-gen")) { int keysize; From cvs at cvs.gnupg.org Thu Dec 11 16:07:41 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Dec 2008 16:07:41 +0100 Subject: [svn] gcry - r1375 - trunk/tests Message-ID: Author: wk Date: 2008-12-11 16:07:41 +0100 (Thu, 11 Dec 2008) New Revision: 1375 Modified: trunk/tests/cavs_driver.pl Log: oops. Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2008-12-11 14:54:25 UTC (rev 1374) +++ trunk/tests/cavs_driver.pl 2008-12-11 15:07:41 UTC (rev 1375) @@ -389,7 +389,7 @@ my @tmp; $n = sprintf ("%u", $n); - $e = sprintf ("%u", $e); + $e = sprintf ("%u", hex($e)); $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")" . "(derive-parms" From cvs at cvs.gnupg.org Thu Dec 11 18:00:52 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Dec 2008 18:00:52 +0100 Subject: [svn] GnuPG - r4898 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2008-12-11 18:00:52 +0100 (Thu, 11 Dec 2008) New Revision: 4898 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/sig-check.c Log: Close message digest; fixes memory leak. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-10 12:41:15 UTC (rev 4897) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-11 17:00:52 UTC (rev 4898) @@ -1,3 +1,7 @@ +2008-12-11 Werner Koch + + * sig-check.c (check_revocation_keys): Close message digest. + 2008-12-09 Werner Koch * keygen.c (proc_parameter_file): Check that key and subkey usages Modified: branches/STABLE-BRANCH-1-4/g10/sig-check.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/sig-check.c 2008-12-10 12:41:15 UTC (rev 4897) +++ branches/STABLE-BRANCH-1-4/g10/sig-check.c 2008-12-11 17:00:52 UTC (rev 4898) @@ -427,6 +427,7 @@ hash_public_key(md,pk); rc=signature_check(sig,md); cache_sig_result(sig,rc); + md_close (md); break; } } From cvs at cvs.gnupg.org Thu Dec 11 18:44:52 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Dec 2008 18:44:52 +0100 Subject: [svn] GnuPG - r4899 - in trunk: . g10 Message-ID: Author: wk Date: 2008-12-11 18:44:52 +0100 (Thu, 11 Dec 2008) New Revision: 4899 Added: trunk/g10/t-rmd160.c Modified: trunk/NEWS trunk/g10/ChangeLog trunk/g10/Makefile.am trunk/g10/gpg.c trunk/g10/keygen.c trunk/g10/keyid.c trunk/g10/main.h trunk/g10/sig-check.c trunk/g10/trustdb.h Log: Make gpg not depend on the RIPE-MD160 implementaion in Libgcrypt. Fix SIG_ID computation. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/ChangeLog 2008-12-11 17:44:52 UTC (rev 4899) @@ -1,3 +1,23 @@ +2008-12-11 Werner Koch + + * sig-check.c (signature_check2): Change algorithm used to compute + the SIG_ID. + (check_revocation_keys): Close message digest. + + * rmd160.c, rmd160.h: New. Based on code from GnuPG-1.4. + * t-rmd160.c: New. + * Makefile.am: Add support to run tests. + * keyid.c (namehash_from_uid): Use rmd160_hash_buffer. + +2008-12-10 Werner Koch + + * trustdb.h (NAMEHASH_HASH): Remove unsued constant. + + * gpg.c (print_mds): Print RMD160 only is enabled. + + * keygen.c (keygen_set_std_prefs): Include RMD160 only if + available. + 2008-12-09 Werner Koch * gpg.c (main) [IS_DEVELOPMENT_VERSION]: Fix strusage use. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/NEWS 2008-12-11 17:44:52 UTC (rev 4899) @@ -19,6 +19,8 @@ * [gpg] New control statement %ask-passphrase for the unattended key generation. + * [gpg] The algorithm to compute the SIG_ID status has been changed. + * [gpgsm] Now uses AES by default. * [gpgsm] Made --output option work with --export-secret-key-p12. Modified: trunk/g10/Makefile.am =================================================================== --- trunk/g10/Makefile.am 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/Makefile.am 2008-12-11 17:44:52 UTC (rev 4899) @@ -30,6 +30,8 @@ needed_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a bin_PROGRAMS = gpg2 gpgv2 +noinst_PROGRAMS = $(module_tests) +TESTS = $(module_tests) if ENABLE_BZIP2_SUPPORT bzip2_source = compress-bz2.c @@ -57,6 +59,7 @@ textfilter.c \ progress.c \ misc.c \ + rmd160.c \ options.h \ openfile.c \ keyid.c \ @@ -121,6 +124,12 @@ gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ $(LIBICONV) +t_common_ldadd = +module_tests = t-rmd160 +t_rmd160_SOURCES = t-rmd160.c rmd160.c +t_rmd160_LDADD = $(t_common_ldadd) + + $(PROGRAMS): $(needed_libs) ../common/libgpgrl.a install-data-local: Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/gpg.c 2008-12-11 17:44:52 UTC (rev 4899) @@ -4187,7 +4187,8 @@ else { print_hashline( md, GCRY_MD_MD5, fname ); print_hashline( md, GCRY_MD_SHA1, fname ); - print_hashline( md, GCRY_MD_RMD160, fname ); + if (!gcry_md_test_algo (GCRY_MD_RMD160)) + print_hashline( md, GCRY_MD_RMD160, fname ); if (!gcry_md_test_algo (GCRY_MD_SHA224)) print_hashline (md, GCRY_MD_SHA224, fname); if (!gcry_md_test_algo (GCRY_MD_SHA256)) @@ -4204,7 +4205,8 @@ else { print_hex( md, GCRY_MD_MD5, fname ); print_hex( md, GCRY_MD_SHA1, fname ); - print_hex( md, GCRY_MD_RMD160, fname ); + if (!gcry_md_test_algo (GCRY_MD_RMD160)) + print_hex( md, GCRY_MD_RMD160, fname ); if (!gcry_md_test_algo (GCRY_MD_SHA224)) print_hex (md, GCRY_MD_SHA224, fname); if (!gcry_md_test_algo (GCRY_MD_SHA256)) Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/keygen.c 2008-12-11 17:44:52 UTC (rev 4899) @@ -352,7 +352,8 @@ strcat(dummy_string,"H8 "); /* RIPEMD160 */ - strcat(dummy_string,"H3 "); + if (!openpgp_md_test_algo(DIGEST_ALGO_RMD160)) + strcat(dummy_string,"H3 "); /* ZLIB */ strcat(dummy_string,"Z2 "); Modified: trunk/g10/keyid.c =================================================================== --- trunk/g10/keyid.c 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/keyid.c 2008-12-11 17:44:52 UTC (rev 4899) @@ -33,6 +33,7 @@ #include "options.h" #include "keydb.h" #include "i18n.h" +#include "rmd160.h" int pubkey_letter( int algo ) @@ -448,16 +449,14 @@ byte * namehash_from_uid(PKT_user_id *uid) { - if(uid->namehash==NULL) + if (!uid->namehash) { - uid->namehash = xmalloc(20); - + uid->namehash = xmalloc (20); + if(uid->attrib_data) - gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash, - uid->attrib_data, uid->attrib_len); + rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len); else - gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash, - uid->name, uid->len); + rmd160_hash_buffer (uid->namehash, uid->name, uid->len); } return uid->namehash; Modified: trunk/g10/main.h =================================================================== --- trunk/g10/main.h 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/main.h 2008-12-11 17:44:52 UTC (rev 4899) @@ -328,7 +328,6 @@ void block_all_signals(void); void unblock_all_signals(void); - /*-- server.c --*/ int gpg_server (ctrl_t); Modified: trunk/g10/sig-check.c =================================================================== --- trunk/g10/sig-check.c 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/sig-check.c 2008-12-11 17:44:52 UTC (rev 4899) @@ -130,41 +130,63 @@ * and the timestamp, but the drawback of this is, that it is * not possible to sign more than one identical document within * one second. Some remote batch processing applications might - * like this feature here */ - gcry_md_hd_t md; - + * like this feature here. + * + * Note that before 2.0.10, we used RIPE-MD160 for the hash + * and accidently didn't include the timestamp and algorithm + * information in the hash. Given that this feature is not + * commonly used and that a replay attacks detection should + * not solely be based on this feature (because it does not + * work with RSA), we take the freedom and switch to SHA-1 + * with 2.0.10 to take advantage of hardware supported SHA-1 + * implementations. We also include the missing information + * in the hash. Note also the SIG_ID as computed by gpg 1.x + * and gpg 2.x didn't matched either because 2.x used to print + * MPIs not in PGP format. */ u32 a = sig->timestamp; - int i, nsig = pubkey_get_nsig( sig->pubkey_algo ); - byte *p, *buffer; + int nsig = pubkey_get_nsig( sig->pubkey_algo ); + unsigned char *p, *buffer; + size_t n, nbytes; + int i; + char hashbuf[20]; - if (gcry_md_open (&md, GCRY_MD_RMD160, 0)) - BUG (); + nbytes = 6; + for (i=0; i < nsig; i++ ) + { + if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n, sig->data[i])) + BUG(); + nbytes += n; + } - /* FIXME: Why the hell are we updating DIGEST here??? */ - gcry_md_putc( digest, sig->pubkey_algo ); - gcry_md_putc( digest, sig->digest_algo ); - gcry_md_putc( digest, (a >> 24) & 0xff ); - gcry_md_putc( digest, (a >> 16) & 0xff ); - gcry_md_putc( digest, (a >> 8) & 0xff ); - gcry_md_putc( digest, a & 0xff ); - for(i=0; i < nsig; i++ ) { - size_t n; - unsigned char *tmp; + /* Make buffer large enough to be later used as output buffer. */ + if (nbytes < 100) + nbytes = 100; + nbytes += 10; /* Safety margin. */ - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i])) + /* Fill and hash buffer. */ + buffer = p = xmalloc (nbytes); + *p++ = sig->pubkey_algo; + *p++ = sig->digest_algo; + *p++ = (a >> 24) & 0xff; + *p++ = (a >> 16) & 0xff; + *p++ = (a >> 8) & 0xff; + *p++ = a & 0xff; + nbytes -= 6; + for (i=0; i < nsig; i++ ) + { + if (gcry_mpi_print (GCRYMPI_FMT_PGP, p, nbytes, &n, sig->data[i])) BUG(); - gcry_md_write (md, tmp, n); - xfree (tmp); - } - gcry_md_final (md); - p = make_radix64_string ( gcry_md_read( md, 0 ), 20 ); - buffer = xmalloc( strlen(p) + 60 ); - sprintf( buffer, "%s %s %lu", - p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp ); - write_status_text( STATUS_SIG_ID, buffer ); - xfree(buffer); - xfree(p); - gcry_md_close(md); + p += n; + nbytes -= n; + } + gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, buffer, p-buffer); + + p = make_radix64_string (hashbuf, 20); + sprintf (buffer, "%s %s %lu", + p, strtimestamp (sig->timestamp), (ulong)sig->timestamp); + xfree (p); + write_status_text (STATUS_SIG_ID, buffer); + xfree (buffer); } return rc; @@ -420,6 +442,7 @@ hash_public_key(md,pk); rc=signature_check(sig,md); cache_sig_result(sig,rc); + gcry_md_close (md); break; } } Added: trunk/g10/t-rmd160.c =================================================================== --- trunk/g10/t-rmd160.c (rev 0) +++ trunk/g10/t-rmd160.c 2008-12-11 17:44:52 UTC (rev 4899) @@ -0,0 +1,92 @@ +/* t-rmd160.c - Module test for rmd160.c + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include + +#include "rmd160.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + +static void +run_test (void) +{ + static struct + { + const char *data; + const char *expect; + } testtbl[] = + { + { "", + "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" + "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" }, + { "a", + "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae" + "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" }, + { "abc", + "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04" + "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" }, + { "message digest", + "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" + "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" }, + { "abcdefghijklmnopqrstuvwxyz", + "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb" + "\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789", + "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed" + "\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89" }, + { "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890", + "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb" + "\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb" }, + + { NULL, NULL } + }; + int idx; + char digest[20]; + + for (idx=0; testtbl[idx].data; idx++) + { + rmd160_hash_buffer (digest, + testtbl[idx].data, strlen(testtbl[idx].data)); + if (memcmp (digest, testtbl[idx].expect, 20)) + fail (idx); + } +} + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + run_test (); + + return 0; +} + Modified: trunk/g10/trustdb.h =================================================================== --- trunk/g10/trustdb.h 2008-12-11 17:00:52 UTC (rev 4898) +++ trunk/g10/trustdb.h 2008-12-11 17:44:52 UTC (rev 4899) @@ -36,7 +36,6 @@ #define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */ #define TRUST_FLAG_PENDING_CHECK 256 /* a check-trustdb is pending */ -#define NAMEHASH_HASH DIGEST_ALGO_RMD160 #define NAMEHASH_LEN 20 /*-- trustdb.c --*/ From cvs at cvs.gnupg.org Thu Dec 11 18:46:17 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Dec 2008 18:46:17 +0100 Subject: [svn] GnuPG - r4900 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2008-12-11 18:46:16 +0100 (Thu, 11 Dec 2008) New Revision: 4900 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/sig-check.c Log: Change SIG_ID computation to m Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-11 17:44:52 UTC (rev 4899) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-11 17:46:16 UTC (rev 4900) @@ -1,6 +1,8 @@ 2008-12-11 Werner Koch * sig-check.c (check_revocation_keys): Close message digest. + (signature_check2): Switch to SHA-1 for SIG_ID computation. This + is to match 2.0.10. 2008-12-09 Werner Koch Modified: branches/STABLE-BRANCH-1-4/g10/sig-check.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/sig-check.c 2008-12-11 17:44:52 UTC (rev 4899) +++ branches/STABLE-BRANCH-1-4/g10/sig-check.c 2008-12-11 17:46:16 UTC (rev 4900) @@ -124,19 +124,31 @@ * and the timestamp, but the drawback of this is, that it is * not possible to sign more than one identical document within * one second. Some remote batch processing applications might - * like this feature here */ + * like this feature here. + * + * Note that before 1.4.10, we used RIPE-MD160 for the hash + * and accidently didn't include the timestamp and algorithm + * information in the hash. Given that this feature is not + * commonly used and that a replay attacks detection should + * not solely be based on this feature (because it does not + * work with RSA), we take the freedom and switch to SHA-1 + * with 1.4.10 to take advantage of hardware supported SHA-1 + * implementations and to match the 2.0.10 behaviour. We also + * include the missing information in the hash. Note also the + * SIG_ID as computed by gpg 1.x and gpg 2.x didn't matched + * either because 2.x used to print MPIs not in PGP format. */ MD_HANDLE md; u32 a = sig->timestamp; int i, nsig = pubkey_get_nsig( sig->pubkey_algo ); byte *p, *buffer; - md = md_open( DIGEST_ALGO_RMD160, 0); - md_putc( digest, sig->pubkey_algo ); - md_putc( digest, sig->digest_algo ); - md_putc( digest, (a >> 24) & 0xff ); - md_putc( digest, (a >> 16) & 0xff ); - md_putc( digest, (a >> 8) & 0xff ); - md_putc( digest, a & 0xff ); + md = md_open (DIGEST_ALGO_SHA1, 0); + md_putc (md, sig->pubkey_algo); + md_putc (md, sig->digest_algo); + md_putc (md, (a >> 24) & 0xff); + md_putc (md, (a >> 16) & 0xff); + md_putc (md, (a >> 8) & 0xff); + md_putc (md, a & 0xff); for(i=0; i < nsig; i++ ) { unsigned n = mpi_get_nbits( sig->data[i]); From cvs at cvs.gnupg.org Thu Dec 11 18:47:47 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Dec 2008 18:47:47 +0100 Subject: [svn] GnuPG - r4901 - branches/STABLE-BRANCH-1-4 Message-ID: Author: wk Date: 2008-12-11 18:47:47 +0100 (Thu, 11 Dec 2008) New Revision: 4901 Modified: branches/STABLE-BRANCH-1-4/NEWS Log: Change the SIG_ID computation to match 2.0.10. Modified: branches/STABLE-BRANCH-1-4/NEWS =================================================================== --- branches/STABLE-BRANCH-1-4/NEWS 2008-12-11 17:46:16 UTC (rev 4900) +++ branches/STABLE-BRANCH-1-4/NEWS 2008-12-11 17:47:47 UTC (rev 4901) @@ -1,6 +1,8 @@ Noteworthy changes in version 1.4.10 (unreleased) ------------------------------------------------- + * The algorithm to compute the SIG_ID status has been changed to + match the one from 2.0.10. Noteworthy changes in version 1.4.9 (2008-03-26) From cvs at cvs.gnupg.org Fri Dec 12 09:54:51 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Dec 2008 09:54:51 +0100 Subject: [svn] GnuPG - r4902 - trunk/g10 Message-ID: Author: wk Date: 2008-12-12 09:54:50 +0100 (Fri, 12 Dec 2008) New Revision: 4902 Added: trunk/g10/rmd160.h Modified: trunk/g10/ChangeLog trunk/g10/Makefile.am Log: Add missing header file. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-11 17:47:47 UTC (rev 4901) +++ trunk/g10/ChangeLog 2008-12-12 08:54:50 UTC (rev 4902) @@ -1,3 +1,7 @@ +2008-12-12 Werner Koch + + * Makefile.am (common_source): Add rmd160.h. + 2008-12-11 Werner Koch * sig-check.c (signature_check2): Change algorithm used to compute Modified: trunk/g10/Makefile.am =================================================================== --- trunk/g10/Makefile.am 2008-12-11 17:47:47 UTC (rev 4901) +++ trunk/g10/Makefile.am 2008-12-12 08:54:50 UTC (rev 4902) @@ -59,7 +59,7 @@ textfilter.c \ progress.c \ misc.c \ - rmd160.c \ + rmd160.c rmd160.h \ options.h \ openfile.c \ keyid.c \ Added: trunk/g10/rmd160.h =================================================================== --- trunk/g10/rmd160.h (rev 0) +++ trunk/g10/rmd160.h 2008-12-12 08:54:50 UTC (rev 4902) @@ -0,0 +1,24 @@ +/* rmd160.h + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#ifndef G10_RMD160_H +#define G10_RMD160_H + +void rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length); + +#endif /*G10_RMD160_H*/ From cvs at cvs.gnupg.org Fri Dec 12 13:01:20 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Dec 2008 13:01:20 +0100 Subject: [svn] GnuPG - r4903 - trunk/g10 Message-ID: Author: wk Date: 2008-12-12 13:01:20 +0100 (Fri, 12 Dec 2008) New Revision: 4903 Added: trunk/g10/rmd160.c Modified: trunk/g10/ChangeLog trunk/g10/cpr.c trunk/g10/main.h trunk/g10/passphrase.c Log: Add rmd160.c. Emit anotehr error code status line. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-12-12 08:54:50 UTC (rev 4902) +++ trunk/g10/ChangeLog 2008-12-12 12:01:20 UTC (rev 4903) @@ -1,5 +1,8 @@ 2008-12-12 Werner Koch + * passphrase.c (passphrase_get): Write a STATUS_ERROR. + * cpr.c (write_status_error): New. + * Makefile.am (common_source): Add rmd160.h. 2008-12-11 Werner Koch Modified: trunk/g10/cpr.c =================================================================== --- trunk/g10/cpr.c 2008-12-12 08:54:50 UTC (rev 4902) +++ trunk/g10/cpr.c 2008-12-12 12:01:20 UTC (rev 4903) @@ -157,6 +157,19 @@ } +void +write_status_error (const char *where, int errcode) +{ + if (!statusfp || !status_currently_allowed (STATUS_ERROR)) + return; /* Not enabled or allowed. */ + + fprintf (statusfp, "[GNUPG:] %s %s %u\n", + get_status_string (STATUS_ERROR), where, gpg_err_code (errcode)); + if (fflush (statusfp) && opt.exit_on_status_write_error) + g10_exit (0); +} + + /* * Write a status line with a buffer using %XX escapes. If WRAP is > * 0 wrap the line after this length. If STRING is not NULL it will Modified: trunk/g10/main.h =================================================================== --- trunk/g10/main.h 2008-12-12 08:54:50 UTC (rev 4902) +++ trunk/g10/main.h 2008-12-12 12:01:20 UTC (rev 4903) @@ -153,6 +153,7 @@ void set_status_fd ( int fd ); int is_status_enabled ( void ); void write_status ( int no ); +void write_status_error (const char *where, int errcode); void write_status_text ( int no, const char *text ); void write_status_buffer ( int no, const char *buffer, size_t len, int wrap ); Modified: trunk/g10/passphrase.c =================================================================== --- trunk/g10/passphrase.c 2008-12-12 08:54:50 UTC (rev 4902) +++ trunk/g10/passphrase.c 2008-12-12 12:01:20 UTC (rev 4903) @@ -377,6 +377,8 @@ errors from the agent. */ if (canceled) *canceled = 1; + + write_status_error ("get_passphrase", rc); } if (pk) Added: trunk/g10/rmd160.c =================================================================== --- trunk/g10/rmd160.c (rev 0) +++ trunk/g10/rmd160.c 2008-12-12 12:01:20 UTC (rev 4903) @@ -0,0 +1,425 @@ +/* rmd160.c - RIPE-MD160 + * Copyright (C) 1998, 1999, 2000, 2001, 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* For historic reasons gpg uses RIPE-MD160 to to identify names in + the trustdb. It would be better to change that to SHA-1, to take + advantage of a SHA-1 hardware operation provided by some CPUs. + This would break trustdb compatibility and thus we don't want to do + it now. + + We do not use the libgcrypt provided implementation of RMD160 + because that is not available in FIPS mode, thus for the sake of + gpg internal non-cryptographic, purposes, we use this separate + implementation. +*/ + +#include + +#include +#include +#include + +#include "../jnlib/types.h" +#include "rmd160.h" + +/* + * Rotate the 32 bit integer X by N bytes. + */ +#if defined(__GNUC__) && defined(__i386__) +static inline u32 +rol (u32 x, int n) +{ + __asm__("roll %%cl,%0" + :"=r" (x) + :"0" (x),"c" (n)); + return x; +} +#else +#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) +#endif + +/* Structure holding the context for the RIPE-MD160 computation. */ +typedef struct +{ + u32 h0, h1, h2, h3, h4; + u32 nblocks; + unsigned char buf[64]; + int count; +} rmd160_context_t; + + + +static void +rmd160_init (rmd160_context_t *hd) +{ + hd->h0 = 0x67452301; + hd->h1 = 0xEFCDAB89; + hd->h2 = 0x98BADCFE; + hd->h3 = 0x10325476; + hd->h4 = 0xC3D2E1F0; + hd->nblocks = 0; + hd->count = 0; +} + + + +/* + * Transform the message X which consists of 16 32-bit-words. + */ +static void +transform (rmd160_context_t *hd, const unsigned char *data) +{ + u32 a,b,c,d,e,aa,bb,cc,dd,ee,t; +#ifdef BIG_ENDIAN_HOST + u32 x[16]; + { + int i; + unsigned char *p2, *p1; + for (i=0, p1=data, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) + { + p2[3] = *p1++; + p2[2] = *p1++; + p2[1] = *p1++; + p2[0] = *p1++; + } + } +#else + u32 x[16]; + memcpy (x, data, 64); +#endif + + +#define K0 0x00000000 +#define K1 0x5A827999 +#define K2 0x6ED9EBA1 +#define K3 0x8F1BBCDC +#define K4 0xA953FD4E +#define KK0 0x50A28BE6 +#define KK1 0x5C4DD124 +#define KK2 0x6D703EF3 +#define KK3 0x7A6D76E9 +#define KK4 0x00000000 +#define F0(x,y,z) ( (x) ^ (y) ^ (z) ) +#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) ) +#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) +#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) +#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) +#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \ + a = rol(t,s) + e; \ + c = rol(c,10); \ + } while(0) + + /* Left lane. */ + a = hd->h0; + b = hd->h1; + c = hd->h2; + d = hd->h3; + e = hd->h4; + R( a, b, c, d, e, F0, K0, 0, 11 ); + R( e, a, b, c, d, F0, K0, 1, 14 ); + R( d, e, a, b, c, F0, K0, 2, 15 ); + R( c, d, e, a, b, F0, K0, 3, 12 ); + R( b, c, d, e, a, F0, K0, 4, 5 ); + R( a, b, c, d, e, F0, K0, 5, 8 ); + R( e, a, b, c, d, F0, K0, 6, 7 ); + R( d, e, a, b, c, F0, K0, 7, 9 ); + R( c, d, e, a, b, F0, K0, 8, 11 ); + R( b, c, d, e, a, F0, K0, 9, 13 ); + R( a, b, c, d, e, F0, K0, 10, 14 ); + R( e, a, b, c, d, F0, K0, 11, 15 ); + R( d, e, a, b, c, F0, K0, 12, 6 ); + R( c, d, e, a, b, F0, K0, 13, 7 ); + R( b, c, d, e, a, F0, K0, 14, 9 ); + R( a, b, c, d, e, F0, K0, 15, 8 ); + R( e, a, b, c, d, F1, K1, 7, 7 ); + R( d, e, a, b, c, F1, K1, 4, 6 ); + R( c, d, e, a, b, F1, K1, 13, 8 ); + R( b, c, d, e, a, F1, K1, 1, 13 ); + R( a, b, c, d, e, F1, K1, 10, 11 ); + R( e, a, b, c, d, F1, K1, 6, 9 ); + R( d, e, a, b, c, F1, K1, 15, 7 ); + R( c, d, e, a, b, F1, K1, 3, 15 ); + R( b, c, d, e, a, F1, K1, 12, 7 ); + R( a, b, c, d, e, F1, K1, 0, 12 ); + R( e, a, b, c, d, F1, K1, 9, 15 ); + R( d, e, a, b, c, F1, K1, 5, 9 ); + R( c, d, e, a, b, F1, K1, 2, 11 ); + R( b, c, d, e, a, F1, K1, 14, 7 ); + R( a, b, c, d, e, F1, K1, 11, 13 ); + R( e, a, b, c, d, F1, K1, 8, 12 ); + R( d, e, a, b, c, F2, K2, 3, 11 ); + R( c, d, e, a, b, F2, K2, 10, 13 ); + R( b, c, d, e, a, F2, K2, 14, 6 ); + R( a, b, c, d, e, F2, K2, 4, 7 ); + R( e, a, b, c, d, F2, K2, 9, 14 ); + R( d, e, a, b, c, F2, K2, 15, 9 ); + R( c, d, e, a, b, F2, K2, 8, 13 ); + R( b, c, d, e, a, F2, K2, 1, 15 ); + R( a, b, c, d, e, F2, K2, 2, 14 ); + R( e, a, b, c, d, F2, K2, 7, 8 ); + R( d, e, a, b, c, F2, K2, 0, 13 ); + R( c, d, e, a, b, F2, K2, 6, 6 ); + R( b, c, d, e, a, F2, K2, 13, 5 ); + R( a, b, c, d, e, F2, K2, 11, 12 ); + R( e, a, b, c, d, F2, K2, 5, 7 ); + R( d, e, a, b, c, F2, K2, 12, 5 ); + R( c, d, e, a, b, F3, K3, 1, 11 ); + R( b, c, d, e, a, F3, K3, 9, 12 ); + R( a, b, c, d, e, F3, K3, 11, 14 ); + R( e, a, b, c, d, F3, K3, 10, 15 ); + R( d, e, a, b, c, F3, K3, 0, 14 ); + R( c, d, e, a, b, F3, K3, 8, 15 ); + R( b, c, d, e, a, F3, K3, 12, 9 ); + R( a, b, c, d, e, F3, K3, 4, 8 ); + R( e, a, b, c, d, F3, K3, 13, 9 ); + R( d, e, a, b, c, F3, K3, 3, 14 ); + R( c, d, e, a, b, F3, K3, 7, 5 ); + R( b, c, d, e, a, F3, K3, 15, 6 ); + R( a, b, c, d, e, F3, K3, 14, 8 ); + R( e, a, b, c, d, F3, K3, 5, 6 ); + R( d, e, a, b, c, F3, K3, 6, 5 ); + R( c, d, e, a, b, F3, K3, 2, 12 ); + R( b, c, d, e, a, F4, K4, 4, 9 ); + R( a, b, c, d, e, F4, K4, 0, 15 ); + R( e, a, b, c, d, F4, K4, 5, 5 ); + R( d, e, a, b, c, F4, K4, 9, 11 ); + R( c, d, e, a, b, F4, K4, 7, 6 ); + R( b, c, d, e, a, F4, K4, 12, 8 ); + R( a, b, c, d, e, F4, K4, 2, 13 ); + R( e, a, b, c, d, F4, K4, 10, 12 ); + R( d, e, a, b, c, F4, K4, 14, 5 ); + R( c, d, e, a, b, F4, K4, 1, 12 ); + R( b, c, d, e, a, F4, K4, 3, 13 ); + R( a, b, c, d, e, F4, K4, 8, 14 ); + R( e, a, b, c, d, F4, K4, 11, 11 ); + R( d, e, a, b, c, F4, K4, 6, 8 ); + R( c, d, e, a, b, F4, K4, 15, 5 ); + R( b, c, d, e, a, F4, K4, 13, 6 ); + + aa = a; bb = b; cc = c; dd = d; ee = e; + + /* Right lane. */ + a = hd->h0; + b = hd->h1; + c = hd->h2; + d = hd->h3; + e = hd->h4; + R( a, b, c, d, e, F4, KK0, 5, 8); + R( e, a, b, c, d, F4, KK0, 14, 9); + R( d, e, a, b, c, F4, KK0, 7, 9); + R( c, d, e, a, b, F4, KK0, 0, 11); + R( b, c, d, e, a, F4, KK0, 9, 13); + R( a, b, c, d, e, F4, KK0, 2, 15); + R( e, a, b, c, d, F4, KK0, 11, 15); + R( d, e, a, b, c, F4, KK0, 4, 5); + R( c, d, e, a, b, F4, KK0, 13, 7); + R( b, c, d, e, a, F4, KK0, 6, 7); + R( a, b, c, d, e, F4, KK0, 15, 8); + R( e, a, b, c, d, F4, KK0, 8, 11); + R( d, e, a, b, c, F4, KK0, 1, 14); + R( c, d, e, a, b, F4, KK0, 10, 14); + R( b, c, d, e, a, F4, KK0, 3, 12); + R( a, b, c, d, e, F4, KK0, 12, 6); + R( e, a, b, c, d, F3, KK1, 6, 9); + R( d, e, a, b, c, F3, KK1, 11, 13); + R( c, d, e, a, b, F3, KK1, 3, 15); + R( b, c, d, e, a, F3, KK1, 7, 7); + R( a, b, c, d, e, F3, KK1, 0, 12); + R( e, a, b, c, d, F3, KK1, 13, 8); + R( d, e, a, b, c, F3, KK1, 5, 9); + R( c, d, e, a, b, F3, KK1, 10, 11); + R( b, c, d, e, a, F3, KK1, 14, 7); + R( a, b, c, d, e, F3, KK1, 15, 7); + R( e, a, b, c, d, F3, KK1, 8, 12); + R( d, e, a, b, c, F3, KK1, 12, 7); + R( c, d, e, a, b, F3, KK1, 4, 6); + R( b, c, d, e, a, F3, KK1, 9, 15); + R( a, b, c, d, e, F3, KK1, 1, 13); + R( e, a, b, c, d, F3, KK1, 2, 11); + R( d, e, a, b, c, F2, KK2, 15, 9); + R( c, d, e, a, b, F2, KK2, 5, 7); + R( b, c, d, e, a, F2, KK2, 1, 15); + R( a, b, c, d, e, F2, KK2, 3, 11); + R( e, a, b, c, d, F2, KK2, 7, 8); + R( d, e, a, b, c, F2, KK2, 14, 6); + R( c, d, e, a, b, F2, KK2, 6, 6); + R( b, c, d, e, a, F2, KK2, 9, 14); + R( a, b, c, d, e, F2, KK2, 11, 12); + R( e, a, b, c, d, F2, KK2, 8, 13); + R( d, e, a, b, c, F2, KK2, 12, 5); + R( c, d, e, a, b, F2, KK2, 2, 14); + R( b, c, d, e, a, F2, KK2, 10, 13); + R( a, b, c, d, e, F2, KK2, 0, 13); + R( e, a, b, c, d, F2, KK2, 4, 7); + R( d, e, a, b, c, F2, KK2, 13, 5); + R( c, d, e, a, b, F1, KK3, 8, 15); + R( b, c, d, e, a, F1, KK3, 6, 5); + R( a, b, c, d, e, F1, KK3, 4, 8); + R( e, a, b, c, d, F1, KK3, 1, 11); + R( d, e, a, b, c, F1, KK3, 3, 14); + R( c, d, e, a, b, F1, KK3, 11, 14); + R( b, c, d, e, a, F1, KK3, 15, 6); + R( a, b, c, d, e, F1, KK3, 0, 14); + R( e, a, b, c, d, F1, KK3, 5, 6); + R( d, e, a, b, c, F1, KK3, 12, 9); + R( c, d, e, a, b, F1, KK3, 2, 12); + R( b, c, d, e, a, F1, KK3, 13, 9); + R( a, b, c, d, e, F1, KK3, 9, 12); + R( e, a, b, c, d, F1, KK3, 7, 5); + R( d, e, a, b, c, F1, KK3, 10, 15); + R( c, d, e, a, b, F1, KK3, 14, 8); + R( b, c, d, e, a, F0, KK4, 12, 8); + R( a, b, c, d, e, F0, KK4, 15, 5); + R( e, a, b, c, d, F0, KK4, 10, 12); + R( d, e, a, b, c, F0, KK4, 4, 9); + R( c, d, e, a, b, F0, KK4, 1, 12); + R( b, c, d, e, a, F0, KK4, 5, 5); + R( a, b, c, d, e, F0, KK4, 8, 14); + R( e, a, b, c, d, F0, KK4, 7, 6); + R( d, e, a, b, c, F0, KK4, 6, 8); + R( c, d, e, a, b, F0, KK4, 2, 13); + R( b, c, d, e, a, F0, KK4, 13, 6); + R( a, b, c, d, e, F0, KK4, 14, 5); + R( e, a, b, c, d, F0, KK4, 0, 15); + R( d, e, a, b, c, F0, KK4, 3, 13); + R( c, d, e, a, b, F0, KK4, 9, 11); + R( b, c, d, e, a, F0, KK4, 11, 11); + + + t = hd->h1 + d + cc; + hd->h1 = hd->h2 + e + dd; + hd->h2 = hd->h3 + a + ee; + hd->h3 = hd->h4 + b + aa; + hd->h4 = hd->h0 + c + bb; + hd->h0 = t; +} + + +/* Update the message digest with the content of (INBUF,INLEN). */ +static void +rmd160_write (rmd160_context_t *hd, const unsigned char *inbuf, size_t inlen) +{ + if( hd->count == 64 ) + { + /* Flush the buffer. */ + transform (hd, hd->buf); + hd->count = 0; + hd->nblocks++; + } + if (!inbuf) + return; + + if (hd->count) + { + for (; inlen && hd->count < 64; inlen--) + hd->buf[hd->count++] = *inbuf++; + rmd160_write (hd, NULL, 0); + if (!inlen) + return; + } + + while (inlen >= 64) + { + transform (hd, inbuf); + hd->count = 0; + hd->nblocks++; + inlen -= 64; + inbuf += 64; + } + for (; inlen && hd->count < 64; inlen--) + hd->buf[hd->count++] = *inbuf++; +} + + +/* Complete the message computation. */ +static void +rmd160_final( rmd160_context_t *hd ) +{ + u32 t, msb, lsb; + unsigned char *p; + + rmd160_write (hd, NULL, 0); /* Flush buffer. */ + + t = hd->nblocks; + /* Multiply by 64 to make a byte count. */ + lsb = t << 6; + msb = t >> 26; + /* Add the count. */ + t = lsb; + if ((lsb += hd->count) < t) + msb++; + /* Multiply by 8 to make a bit count. */ + t = lsb; + lsb <<= 3; + msb <<= 3; + msb |= t >> 29; + + if (hd->count < 56) + { + /* Enough room. */ + hd->buf[hd->count++] = 0x80; /* Pad character. */ + while (hd->count < 56) + hd->buf[hd->count++] = 0; + } + else + { + /* Need one extra block. */ + hd->buf[hd->count++] = 0x80; /* Pad character. */ + while (hd->count < 64) + hd->buf[hd->count++] = 0; + rmd160_write (hd, NULL, 0); /* Flush buffer. */ + memset (hd->buf, 0, 56); /* Fill next block with zeroes. */ + } + /* Append the 64 bit count. */ + hd->buf[56] = lsb; + hd->buf[57] = lsb >> 8; + hd->buf[58] = lsb >> 16; + hd->buf[59] = lsb >> 24; + hd->buf[60] = msb; + hd->buf[61] = msb >> 8; + hd->buf[62] = msb >> 16; + hd->buf[63] = msb >> 24; + transform (hd, hd->buf); + + p = hd->buf; +#define X(a) do { *p++ = hd->h##a; *p++ = hd->h##a >> 8; \ + *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0) + X(0); + X(1); + X(2); + X(3); + X(4); +#undef X +} + + +/* + * Compines function to put the hash value of the supplied BUFFER into + * OUTBUF which must have a size of 20 bytes. + */ +void +rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length) +{ + rmd160_context_t hd; + + rmd160_init (&hd); + rmd160_write (&hd, buffer, length); + rmd160_final (&hd); + memcpy (outbuf, hd.buf, 20); +} From cvs at cvs.gnupg.org Fri Dec 12 15:04:23 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Dec 2008 15:04:23 +0100 Subject: [svn] GnuPG - r4904 - trunk/doc Message-ID: Author: wk Date: 2008-12-12 15:04:22 +0100 (Fri, 12 Dec 2008) New Revision: 4904 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi trunk/doc/gpgsm.texi Log: Small doc fixes. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-12-12 12:01:20 UTC (rev 4903) +++ trunk/doc/ChangeLog 2008-12-12 14:04:22 UTC (rev 4904) @@ -1,3 +1,8 @@ +2008-12-12 Werner Koch + + * gpgsm.texi (General GPGSM Commands): Fix --help, --version and + --warranty wording. + 2008-12-08 Werner Koch * DETAILS: Clarify the use of "trust" and "validity" as suggested Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2008-12-12 12:01:20 UTC (rev 4903) +++ trunk/doc/gpg.texi 2008-12-12 14:04:22 UTC (rev 4904) @@ -149,7 +149,7 @@ @itemx -h @opindex help Print a usage message summarizing the most useful command line options. -Not that you cannot abbreviate this command. +Note that you cannot abbreviate this command. @item --warranty @opindex warranty Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2008-12-12 12:01:20 UTC (rev 4903) +++ trunk/doc/gpgsm.texi 2008-12-12 14:04:22 UTC (rev 4904) @@ -77,21 +77,22 @@ @table @gnupgtabopt @item --version @opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. +Print the program version and licensing information. Note that you +cannot abbreviate this command. @item --help, -h @opindex help Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. +Note that you cannot abbreviate this command. @item --warranty @opindex warranty -Print warranty information. +Print warranty information. Note that you cannot abbreviate this +command. @item --dump-options @opindex dump-options -Print a list of all available options and commands. Not that you can +Print a list of all available options and commands. Note that you cannot abbreviate this command. @end table From cvs at cvs.gnupg.org Wed Dec 17 20:42:17 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 17 Dec 2008 20:42:17 +0100 Subject: [svn] GnuPG - r4905 - trunk/agent Message-ID: Author: wk Date: 2008-12-17 20:42:17 +0100 (Wed, 17 Dec 2008) New Revision: 4905 Modified: trunk/agent/ChangeLog trunk/agent/gpg-agent.c Log: Fix signal handling race condition. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-12-12 14:04:22 UTC (rev 4904) +++ trunk/agent/ChangeLog 2008-12-17 19:42:17 UTC (rev 4905) @@ -1,3 +1,8 @@ +2008-12-17 Werner Koch + + * gpg-agent.c (handle_connections): Set action of all pth event + handled signals to SIG_IGN. Use a different pth_sigmask strategy. + 2008-12-10 Werner Koch * command.c (cmd_get_passphrase): Implement option --no-ask. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2008-12-12 14:04:22 UTC (rev 4904) +++ trunk/agent/gpg-agent.c 2008-12-17 19:42:17 UTC (rev 4905) @@ -1748,13 +1748,28 @@ #ifndef HAVE_W32_SYSTEM /* fixme */ /* Make sure that the signals we are going to handle are not blocked - and create an event object for them. */ + and create an event object for them. We also set the default + action to ignore because we use an Pth event to get notified + about signals. This avoids that the default action is taken in + case soemthing goes wrong within Pth. The problem might also be + a Pth bug. */ sigemptyset (&sigs ); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); + { + static const int mysigs[] = { SIGHUP, SIGUSR1, SIGUSR2, SIGINT, SIGTERM }; + struct sigaction sa; + int i; + + for (i=0; i < DIM (mysigs); i++) + { + sigemptyset (&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigaction (mysigs[i], &sa, NULL); + + sigaddset (&sigs, mysigs[i]); + } + } + pth_sigmask (SIG_UNBLOCK, &sigs, NULL); ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); #else @@ -1782,8 +1797,10 @@ for (;;) { - sigset_t oldsigs; + /* Make sure that our signals are not blocked. */ + pth_sigmask (SIG_UNBLOCK, &sigs, NULL); + /* Shutdown test. */ if (shutdown_pending) { if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1) @@ -1843,7 +1860,7 @@ log_error (_("pth_select failed: %s - waiting 1s\n"), strerror (errno)); pth_sleep (1); - continue; + continue; } if (pth_event_occurred (ev)) @@ -1862,11 +1879,11 @@ handle_tick (); } - + /* We now might create new threads and because we don't want any signals (as we are handling them here) to be delivered to a new thread. Thus we need to block those signals. */ - pth_sigmask (SIG_BLOCK, &sigs, &oldsigs); + pth_sigmask (SIG_BLOCK, &sigs, NULL); if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset)) { @@ -1943,10 +1960,6 @@ } fd = GNUPG_INVALID_FD; } - - /* Restore the signal mask. */ - pth_sigmask (SIG_SETMASK, &oldsigs, NULL); - } pth_event_free (ev, PTH_FREE_ALL); From cvs at cvs.gnupg.org Thu Dec 18 17:34:32 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Dec 2008 17:34:32 +0100 Subject: [svn] GnuPG - r4906 - in trunk: agent po scd Message-ID: Author: wk Date: 2008-12-18 17:34:28 +0100 (Thu, 18 Dec 2008) New Revision: 4906 Modified: trunk/agent/gpg-agent.c trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/ccid-driver.c trunk/scd/command.c Log: Fixed some card related problems. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-12-17 19:42:17 UTC (rev 4905) +++ trunk/scd/ChangeLog 2008-12-18 16:34:28 UTC (rev 4906) @@ -1,3 +1,17 @@ +2008-12-18 Werner Koch + + * ccid-driver.c (abort_cmd): New. + (bulk_in): Call abort_cmd after severe errors. + + * apdu.c (reader_table_s): Add field ANY_STATUS. + (new_reader_slot): Clear it. + (apdu_get_status): Use ANY_STATUS to update the change counter. + Remove the use of the flag bit from LAST_STATUS everywhere. + * command.c (update_reader_status_file): Factor code out to ... + (send_client_notifications): New. Track signals already sent. + (update_reader_status_file): Shutdown the reader after a failed + apdu_get_status. + 2008-12-09 Werner Koch * scdaemon.c (main): Call i18n_init before init_common_subsystems. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2008-12-17 19:42:17 UTC (rev 4905) +++ trunk/agent/gpg-agent.c 2008-12-18 16:34:28 UTC (rev 4906) @@ -1602,7 +1602,7 @@ agent_sigusr2_action (void) { if (opt.verbose) - log_info ("SIGUSR2 received - checking smartcard status\n"); + log_info ("SIGUSR2 received - updating card event counter\n"); /* Nothing to check right now. We only increment a counter. */ bump_card_eventcounter (); } Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2008-12-17 19:42:17 UTC (rev 4905) +++ trunk/scd/apdu.c 2008-12-18 16:34:28 UTC (rev 4906) @@ -133,6 +133,7 @@ } rapdu; #endif /*USE_G10CODE_RAPDU*/ char *rdrname; /* Name of the connected reader or NULL if unknown. */ + int any_status; /* True if we have seen any status. */ int last_status; int status; int is_t0; /* True if we know that we are running T=0. */ @@ -340,7 +341,8 @@ reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = NULL; - reader_table[reader].used = 1; + reader_table[reader].used = 1; + reader_table[reader].any_status = 0; reader_table[reader].last_status = 0; reader_table[reader].is_t0 = 1; #ifdef NEED_PCSC_WRAPPER @@ -1289,8 +1291,7 @@ and usable. Remember this. */ reader_table[slot].last_status = ( APDU_CARD_USABLE | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE - | 0x8000); + | APDU_CARD_ACTIVE); reader_table[slot].is_t0 = !!(card_protocol & PCSC_PROTOCOL_T0); } } @@ -1743,8 +1744,7 @@ and usable. Thus remember this. */ slotp->last_status = ( APDU_CARD_USABLE | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE - | 0x8000); + | APDU_CARD_ACTIVE); } slotp->atrlen = len; @@ -1947,8 +1947,7 @@ and usable. Thus remember this. */ reader_table[slot].last_status = (APDU_CARD_USABLE | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE - | 0x8000); + | APDU_CARD_ACTIVE); } reader_table[slot].close_reader = close_ccid_reader; @@ -2615,8 +2614,7 @@ and usable. Thus remember this. */ reader_table[slot].last_status = (APDU_CARD_USABLE | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE - | 0x8000); + | APDU_CARD_ACTIVE); } unlock_slot (slot); @@ -2662,8 +2660,7 @@ and usable. Thus remember this. */ reader_table[slot].last_status = (APDU_CARD_USABLE | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE - | 0x8000); + | APDU_CARD_ACTIVE); } } } @@ -2733,17 +2730,16 @@ return sw; } - /* Keep track of changes. We use one extra bit to test whether we - have checked the status at least once. */ - if ( s != (reader_table[slot].last_status & 0x07ff) - || !reader_table[slot].last_status ) + /* Keep track of changes. */ + if (s != reader_table[slot].last_status + || !reader_table[slot].any_status ) { reader_table[slot].change_counter++; /* Make sure that the ATR is invalid so that a reset will be by activate. */ reader_table[slot].atrlen = 0; } - reader_table[slot].last_status = (s | 0x8000); + reader_table[slot].any_status = 1; if (status) *status = s; Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2008-12-17 19:42:17 UTC (rev 4905) +++ trunk/scd/ccid-driver.c 2008-12-18 16:34:28 UTC (rev 4906) @@ -1,5 +1,6 @@ /* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2007 + * 2008 Free Software Foundation, Inc. * Written by Werner Koch. * * This file is part of GnuPG. @@ -262,6 +263,7 @@ static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, size_t *nread, int expected_type, int seqno, int timeout, int no_debug); +static int abort_cmd (ccid_driver_t handle); /* Convert a little endian stored 4 byte value into an unsigned integer. */ @@ -1069,7 +1071,10 @@ /* Set the level of debugging to LEVEL and return the old level. -1 just returns the old level. A level of 0 disables debugging, 1 enables debugging, 2 enables additional tracing of the T=1 - protocol, other values are not yet defined. */ + protocol, other values are not yet defined. + + Note that libusb may provide its own debugging feature which is + enabled by setting the envvar USB_DEBUG. */ int ccid_set_debug_level (int level) { @@ -1395,7 +1400,7 @@ rc = usb_bulk_write (handle->idev, handle->ep_bulk_out, (char*)msg, msglen, - 1000 /* ms timeout */); + 5000 /* ms timeout */); if (rc == msglen) return 0; if (rc == -1) @@ -1463,17 +1468,20 @@ if (msglen < 10) { DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen); + abort_cmd (handle); return CCID_DRIVER_ERR_INV_VALUE; } if (buffer[5] != 0) { DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]); + abort_cmd (handle); return CCID_DRIVER_ERR_INV_VALUE; } if (buffer[6] != seqno) { DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n", seqno, buffer[6]); + abort_cmd (handle); return CCID_DRIVER_ERR_INV_VALUE; } @@ -1492,6 +1500,7 @@ if (buffer[0] != expected_type) { DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); + abort_cmd (handle); return CCID_DRIVER_ERR_INV_VALUE; } @@ -1521,6 +1530,113 @@ } + +/* Send an abort sequence and wait until everything settled. */ +static int +abort_cmd (ccid_driver_t handle) +{ + int rc; + char dummybuf[8]; + unsigned char seqno; + unsigned char msg[100]; + size_t msglen; + int i; + + if (!handle->idev) + { + /* I don't know how to send an abort to non-USB devices. */ + rc = CCID_DRIVER_ERR_NOT_SUPPORTED; + } + + DEBUGOUT ("sending abort sequence\n"); + /* Send the abort command to the control pipe. Note that we don't + need to keep track of sent abort commands because there should + never be another thread using the same slot concurrently. */ + seqno = (handle->seqno & 0xff); + rc = usb_control_msg (handle->idev, + 0x21,/* bmRequestType: host-to-device, + class specific, to interface. */ + 1, /* ABORT */ + (seqno << 8 | 0 /* slot */), + handle->ifc_no, + dummybuf, 0, + 1000 /* ms timeout */); + if (rc < 0) + { + DEBUGOUT_1 ("usb_control_msg error: %s\n", strerror (errno)); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } + + /* Now send the abort command to the bulk out pipe using the same + SEQNO and SLOT. */ + msg[0] = PC_to_RDR_Abort; + msg[5] = 0; /* slot */ + msg[6] = seqno; + msg[7] = 0; /* RFU */ + msg[8] = 0; /* RFU */ + msg[9] = 0; /* RFU */ + msglen = 10; + set_msg_len (msg, 0); + handle->seqno++; /* Bumb up for the next use. */ + + DEBUGOUT ("sending"); + for (i=0; i < msglen; i++) + DEBUGOUT_CONT_1 (" %02X", msg[i]); + DEBUGOUT_LF (); + rc = usb_bulk_write (handle->idev, + handle->ep_bulk_out, + (char*)msg, msglen, + 5000 /* ms timeout */); + if (rc == msglen) + rc = 0; + else if (rc == -1) + DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n", strerror (errno)); + else + DEBUGOUT_1 ("usb_bulk_write failed in abort_cmd: %d\n", rc); + + if (rc) + return rc; + + /* Wait for the expected response. */ + do + { + rc = usb_bulk_read (handle->idev, + handle->ep_bulk_in, + (char*)msg, sizeof msg, + 5000 /*ms timeout*/); + if (rc < 0) + { + DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n", + strerror (errno)); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } + msglen = rc; + + if (msglen < 10) + { + DEBUGOUT_1 ("bulk-in msg in abort_cmd too short (%u)\n", + (unsigned int)msglen); + return CCID_DRIVER_ERR_INV_VALUE; + } + if (msg[5] != 0) + { + DEBUGOUT_1 ("unexpected bulk-in slot (%d) in abort_cmd\n", msg[5]); + return CCID_DRIVER_ERR_INV_VALUE; + } + + DEBUGOUT_3 ("status: %02X error: %02X octet[9]: %02X\n", + msg[7], msg[8], msg[9]); + if (CCID_COMMAND_FAILED (msg)) + print_command_failed (msg); + } + while (msg[0] != RDR_to_PC_SlotStatus && msg[5] != 0 && msg[6] != seqno); + + DEBUGOUT ("sending abort sequence succeeded\n"); + + return 0; +} + + /* Note that this function won't return the error codes NO_CARD or CARD_INACTIVE. IF RESULT is not NULL, the result from the operation will get returned in RESULT and its length in RESULTLEN. Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2008-12-17 19:42:17 UTC (rev 4905) +++ trunk/scd/command.c 2008-12-18 16:34:28 UTC (rev 4906) @@ -1964,6 +1964,84 @@ } + +/* Helper to send the clients a status change notification. */ +static void +send_client_notifications (void) +{ + struct { + pid_t pid; +#ifdef HAVE_W32_SYSTEM + HANDLE handle; +#else + int signo; +#endif + } killed[50]; + int killidx = 0; + int kidx; + struct server_local_s *sl; + + for (sl=session_list; sl; sl = sl->next_session) + { + if (sl->event_signal && sl->assuan_ctx) + { + pid_t pid = assuan_get_pid (sl->assuan_ctx); +#ifdef HAVE_W32_SYSTEM + HANDLE handle = (void *)sl->event_signal; + + for (kidx=0; kidx < killidx; kidx++) + if (killed[kidx].pid == pid + && killed[kidx].handle == handle) + break; + if (kidx < killidx) + log_info ("event %lx (%p) already triggered for client %d\n", + sl->event_signal, handle, (int)pid); + else + { + log_info ("triggering event %lx (%p) for client %d\n", + sl->event_signal, handle, (int)pid); + if (!SetEvent (handle)) + log_error ("SetEvent(%lx) failed: %s\n", + sl->event_signal, w32_strerror (-1)); + if (killidx < DIM (killed)) + { + killed[killidx].pid = pid; + killed[killidx].handle = handle; + killidx++; + } + } +#else /*!HAVE_W32_SYSTEM*/ + int signo = sl->event_signal; + + if (pid != (pid_t)(-1) && pid && signo > 0) + { + for (kidx=0; kidx < killidx; kidx++) + if (killed[kidx].pid == pid + && killed[kidx].signo == signo) + break; + if (kidx < killidx) + log_info ("signal %d already sent to client %d\n", + signo, (int)pid); + else + { + log_info ("sending signal %d to client %d\n", + signo, (int)pid); + kill (pid, signo); + if (killidx < DIM (killed)) + { + killed[killidx].pid = pid; + killed[killidx].signo = signo; + killidx++; + } + } +#endif /*!HAVE_W32_SYSTEM*/ + } + } + } +} + + + /* This is the core of scd_update_reader_status_file but the caller needs to take care of the locking. */ static void @@ -1985,12 +2063,17 @@ { struct slot_status_s *ss = slot_table + idx; struct server_local_s *sl; + int sw_apdu; if (!ss->valid || ss->slot == -1) continue; /* Not valid or reader not yet open. */ - if ( apdu_get_status (ss->slot, 0, &status, &changed) ) - continue; /* Get status failed. */ + sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed); + if (sw_apdu) + { + /* Get status failed. Ignore that. */ + continue; + } if (!ss->any || ss->status != status || ss->changed != changed ) { @@ -1998,8 +2081,10 @@ char templ[50]; FILE *fp; - log_info ("updating status of slot %d to 0x%04X\n", - ss->slot, status); + log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n", + ss->slot, ss->status, status, ss->changed, changed); + ss->status = status; + ss->changed = changed; /* FIXME: Should this be IDX instead of ss->slot? This depends on how client sessions will associate the reader @@ -2065,33 +2150,9 @@ update_card_removed (idx, 1); ss->any = 1; - ss->status = status; - ss->changed = changed; /* Send a signal to all clients who applied for it. */ - for (sl=session_list; sl; sl = sl->next_session) - if (sl->event_signal && sl->assuan_ctx) - { - pid_t pid = assuan_get_pid (sl->assuan_ctx); - -#ifdef HAVE_W32_SYSTEM - HANDLE handle = (void *)sl->event_signal; - - log_info ("client pid is %d, triggering event %lx (%p)\n", - pid, sl->event_signal, handle); - if (!SetEvent (handle)) - log_error ("SetEvent(%lx) failed: %s\n", - sl->event_signal, w32_strerror (-1)); -#else - int signo = sl->event_signal; - - log_info ("client pid is %d, sending signal %d\n", - pid, signo); - if (pid != (pid_t)(-1) && pid && signo > 0) - kill (pid, signo); -#endif - } - + send_client_notifications (); } /* Check whether a disconnect is pending. */ @@ -2104,7 +2165,7 @@ { /* FIXME: Use a real timeout. */ /* At least one connection and all allow a disconnect. */ - log_debug ("disconnecting card in slot %d\n", ss->slot); + log_info ("disconnecting card in slot %d\n", ss->slot); apdu_disconnect (ss->slot); } } From cvs at cvs.gnupg.org Sun Dec 21 17:57:34 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Sun, 21 Dec 2008 17:57:34 +0100 Subject: [svn] GnuPG - r4907 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: dshaw Date: 2008-12-21 17:57:33 +0100 (Sun, 21 Dec 2008) New Revision: 4907 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/gpg.c Log: * gpg.c (main): Properly handle UTF8 usernames with --sign-key and --lsign-key. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-18 16:34:28 UTC (rev 4906) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-12-21 16:57:33 UTC (rev 4907) @@ -1,3 +1,8 @@ +2008-12-21 David Shaw + + * gpg.c (main): Properly handle UTF8 usernames with --sign-key and + --lsign-key. + 2008-12-11 Werner Koch * sig-check.c (check_revocation_keys): Close message digest. Modified: branches/STABLE-BRANCH-1-4/g10/gpg.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/gpg.c 2008-12-18 16:34:28 UTC (rev 4906) +++ branches/STABLE-BRANCH-1-4/g10/gpg.c 2008-12-21 16:57:33 UTC (rev 4907) @@ -3539,7 +3539,7 @@ append_to_strlist( &sl, "save" ); username = make_username( fname ); - keyedit_menu(fname, locusr, sl, 0, 0 ); + keyedit_menu(username, locusr, sl, 0, 0 ); xfree(username); free_strlist(sl); break;