1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

See ChangeLog: Mon Sep 18 16:35:45 CEST 2000 Werner Koch

This commit is contained in:
Werner Koch 2000-09-18 14:35:34 +00:00
parent c2fff8f204
commit 986d928ce2
46 changed files with 1780 additions and 852 deletions

View File

@ -1,3 +1,20 @@
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* acinclude.m4 (GNUPG_CHECK_MLOCK): Removed that silly mkdir().
* configure.in: Changes to allow for Solaris random device.
By Nils Ellmenreich.
(--with-egd-socket): New.
* configure.in (GNUPG_HOMEDIR): New.
* configure.in: Check for fstat64 and fopen64
* acinclude.m4 (GNUPG_CHECK_FAQPROG): New.
* configure.in: Test for this.
* configure.in (DYNLINK_MOD_CFLAGS): Fix by David Champion.
Tue Aug 22 14:31:15 CEST 2000 Werner Koch <wk@openit.de>
Version 1.1.1

34
NEWS
View File

@ -1,8 +1,38 @@
Noteworthy changes in version 1.1.1
-----------------------------------
Noteworthy changes in the current CVS HEAD
------------------------------------------
THIS IS A DEVELOPMENT VERSION; see README-alpha
* Fixed problems with piping to/from other MS-Windows software
* Expiration time of the primary key can be changed again.
* Revoked user IDs are now marked in the output of --list-key
* New options --merge-only and --try-all-secrets.
* New configuration option --with-egd-socket.
* The --trusted-key option is back after it left us with 0.9.5
* RSA is supported. Key generation does not yet work but will come
soon.
* CAST5 and SHA-1 are now the default algorithms to protect the key
and for symmetric-only encryption. This should solve a couple
of compatibility problems because the old algorithms are optional
according to RFC2440
* Twofish and MDC enhanced encryption is now used. PGP 7 supports
this. Older versions of GnuPG don't support it, so they should be
upgraded to at least 1.0.2
Noteworthy changes in version 1.1.1
-----------------------------------
* Add gpg-agent.
* Removed option --emulate-checksum-bug

View File

@ -1 +1,2 @@
1.1.1
1.1.1a

View File

@ -74,6 +74,8 @@
#undef NAME_OF_DEV_URANDOM
/* Linux has an ioctl */
#undef HAVE_DEV_RANDOM_IOCTL
/* see cipher/rndegd.c */
#undef EGD_SOCKET_NAME
#undef USE_DYNAMIC_LINKING

View File

@ -67,6 +67,32 @@ AC_DEFUN(GNUPG_CHECK_GNUMAKE,
fi
])
dnl GNUPG_CHECK_FAQPROG
dnl
AC_DEFUN(GNUPG_CHECK_FAQPROG,
[ AC_MSG_CHECKING(for faqprog.pl)
if faqprog.pl -V 2>/dev/null | grep '^faqprog.pl ' >/dev/null 2>&1; then
working_faqprog=yes
FAQPROG="faqprog.pl"
else
working_faqprog=no
FAQPROG=": "
fi
AC_MSG_RESULT($working_faqprog)
AC_SUBST(FAQPROG)
AM_CONDITIONAL(WORKING_FAQPROG, test "$working_faqprog" = "yes" )
if test $working_faqprog = no; then
AC_MSG_WARN([[
***
*** It seems that the faqprog.pl program is not installed.
*** Unless you do not change the source of the FAQs it is not required.
*** The working version of this utility should be available at:
*** ftp://ftp.gnupg.org/pub/gcrypt/contrib/faqprog.pl
***]])
fi
])
dnl GNUPG_LINK_FILES( SRC, DEST )
@ -358,7 +384,7 @@ define(GNUPG_CHECK_MLOCK,
#endif
], [
int i;
mkdir ("foo", 0);
/* glibc defines this for functions which it implements
* to always fail with ENOSYS. Some functions are actually
* named something starting with __ and the normal name

View File

@ -1,3 +1,21 @@
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* rndlinux.c (open_device): Loose random device checking.
By Nils Ellmenreich.
* random.c (fast_random_poll): Check ENOSYS for getrusage.
* rndunix.c: Add 2 sources for QNX. By Sam Roberts.
* pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
* rsa.c: Changed the comment about the patent.
(secret): Speed up by using the CRT. For a 2k keys this
is about 3 times faster.
(stronger_key_check): New but unused code to check the secret key.
* Makefile.am: Included rsa.[ch].
* pubkey.c: Enabled RSA support.
(pubkey_get_npkey): Removed RSA workaround.
Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
* pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new

View File

@ -50,6 +50,7 @@ libcipher_la_SOURCES = cipher.c \
rmd.h \
dsa.h \
dsa.c \
rsa.c rsa.h \
smallprime.c \
construct.c

View File

@ -30,9 +30,7 @@
#include "cipher.h"
#include "elgamal.h"
#include "dsa.h"
#if 0
#include "rsa.h"
#endif
#include "dynload.h"
/* FIXME: use set_lasterr() */
@ -196,7 +194,6 @@ setup_pubkey_table(void)
BUG();
i++;
#if 0
pubkey_table[i].algo = PUBKEY_ALGO_RSA;
pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
&pubkey_table[i].npkey,
@ -248,7 +245,6 @@ setup_pubkey_table(void)
if( !pubkey_table[i].name )
BUG();
i++;
#endif
for( ; i < TABLE_SIZE; i++ )
pubkey_table[i].name = NULL;
@ -433,8 +429,6 @@ pubkey_get_npkey( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].npkey;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 2; /* see the RSA keyids */
return 0;
}
@ -450,8 +444,6 @@ pubkey_get_nskey( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].nskey;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 6; /* see the RSA keyids */
return 0;
}
@ -467,8 +459,6 @@ pubkey_get_nsig( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].nsig;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 1; /* see the RSA keyids */
return 0;
}
@ -484,8 +474,6 @@ pubkey_get_nenc( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].nenc;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 1; /* see the RSA keyids */
return 0;
}
@ -1509,6 +1497,11 @@ gcry_pk_ctl( int cmd, void *buffer, size_t buflen)
* Buffer must be NULL, nbytes may have the address of a variable
* with the required usage of the algorithm. It may be 0 for don't
* care or a combination of the GCRY_PK_USAGE_xxx flags;
* GCRYCTL_GET_ALGO_USAGE:
* Return the usage glafs for the give algo. An invalid alog
* does return 0. Disabled algos are ignored here becuase we
* only want to know whether the algo is at all capable of
* the usage.
*
* On error the value -1 is returned and the error reason may be
* retrieved by gcry_errno().
@ -1535,6 +1528,15 @@ gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes)
}
break;
case GCRYCTL_GET_ALGO_USAGE:
do {
int i;
for(i=0; pubkey_table[i].name; i++ )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].use;
} while( load_pubkey_modules() );
return 0;
case GCRYCTL_GET_ALGO_NPKEY: return pubkey_get_npkey( algo );
case GCRYCTL_GET_ALGO_NSKEY: return pubkey_get_nskey( algo );
case GCRYCTL_GET_ALGO_NSIGN: return pubkey_get_nsig( algo );

View File

@ -604,7 +604,9 @@ fast_random_poll()
#endif
#else
{ struct rusage buf;
if( getrusage( RUSAGE_SELF, &buf ) )
/* QNX/Neutrino does return ENOSYS - so we just ignore it and
* add whatever is in buf */
if( getrusage( RUSAGE_SELF, &buf ) && errno != ENOSYS )
BUG();
add_randomness( &buf, sizeof buf, 1 );
memset( &buf, 0, sizeof buf );

View File

@ -63,7 +63,7 @@ get_entropy_count( int fd )
#endif
/****************
* Used to open the Linux and xBSD /dev/random devices
* Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists), ...)
*/
static int
open_device( const char *name, int minor )
@ -76,8 +76,9 @@ open_device( const char *name, int minor )
g10_log_fatal("can't open %s: %s\n", name, strerror(errno) );
if( fstat( fd, &sb ) )
g10_log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
if( !S_ISCHR(sb.st_mode) )
g10_log_fatal("invalid random device!\n" );
/* Don't check device type for better portability */
/* if( (!S_ISCHR(sb.st_mode)) && (!S_ISFIFO(sb.st_mode)) )
g10_log_fatal("invalid random device!\n" ); */
return fd;
}

View File

@ -244,6 +244,7 @@ static struct RI {
{ "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
{ "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
{ "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0 },
{ "/bin/ps", "-A", SC(0.3), NULL, 0, 0, 0, 0 }, /*QNX*/
{ "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1 },
{ "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0 },
/* Unreliable source, depends on system usage */
@ -292,6 +293,10 @@ static struct RI {
/* This is a complex and screwball program. Some systems have things
* like rX_dmn, x = integer, for RAID systems, but the statistics are
* pretty dodgy */
#ifdef __QNXNTO__
{ "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
NULL, 0, 0, 0, 0 },
#endif
#if 0
/* The following aren't enabled since they're somewhat slow and not very
* unpredictable, however they give an indication of the sort of sources

View File

@ -1,10 +1,6 @@
/* rsa.c - RSA function
* Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
* Copyright (C) 2000 Free Software Foundation, Inc.
***********************************************************************
* ATTENTION: This code should not be used in the United States
* before the U.S. Patent #4,405,829 expires on September 20, 2000!
***********************************************************************
*
* This file is part of GnuPG.
*
@ -23,11 +19,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/* This code uses an algorithm protected by U.S. Patent #4,405,829
which expires on September 20, 2000. The patent holder placed that
patent into the public domain on Sep 6th, 2000.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "g10lib.h"
#include "mpi.h"
#include "cipher.h"
#include "rsa.h"
@ -68,7 +69,7 @@ test_keys( RSA_secret_key *sk, unsigned nbits )
pk.e = sk->e;
{ char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( test, p, (nbits+7)/8, 0 );
m_free(p);
g10_free(p);
}
public( out1, test, &pk );
@ -200,22 +201,111 @@ public(MPI output, MPI input, RSA_public_key *pkey )
mpi_powm( output, input, pkey->e, pkey->n );
}
#if 0
static void
stronger_key_check ( RSA_secret_key *skey )
{
MPI t = mpi_alloc_secure ( 0 );
MPI t1 = mpi_alloc_secure ( 0 );
MPI t2 = mpi_alloc_secure ( 0 );
MPI phi = mpi_alloc_secure ( 0 );
/* check that n == p * q */
mpi_mul( t, skey->p, skey->q);
if (mpi_cmp( t, skey->n) )
log_info ( "RSA Oops: n != p * q\n" );
/* check that p is less than q */
if( mpi_cmp( skey->p, skey->q ) > 0 )
log_info ("RSA Oops: p >= q\n");
/* check that e divides neither p-1 nor q-1 */
mpi_sub_ui(t, skey->p, 1 );
mpi_fdiv_r(t, t, skey->e );
if ( !mpi_cmp_ui( t, 0) )
log_info ( "RSA Oops: e divides p-1\n" );
mpi_sub_ui(t, skey->q, 1 );
mpi_fdiv_r(t, t, skey->e );
if ( !mpi_cmp_ui( t, 0) )
log_info ( "RSA Oops: e divides q-1\n" );
/* check that d is correct */
mpi_sub_ui( t1, skey->p, 1 );
mpi_sub_ui( t2, skey->q, 1 );
mpi_mul( phi, t1, t2 );
mpi_gcd(t, t1, t2);
mpi_fdiv_q(t, phi, t);
mpi_invm(t, skey->e, t );
if ( mpi_cmp(t, skey->d ) )
log_info ( "RSA Oops: d is wrong\n");
/* check for crrectness of u */
mpi_invm(t, skey->p, skey->q );
if ( mpi_cmp(t, skey->u ) )
log_info ( "RSA Oops: u is wrong\n");
log_info ( "RSA secret key check finished\n");
mpi_free (t);
mpi_free (t1);
mpi_free (t2);
mpi_free (phi);
}
#endif
/****************
* Secret key operation. Encrypt INPUT with SKEY and put result into OUTPUT.
*
* m = c^d mod n
*
* Where m is OUTPUT, c is INPUT and d,n are elements of PKEY.
* Or faster:
*
* FIXME: We should better use the Chinese Remainder Theorem
* m1 = c ^ (d mod (p-1)) mod p
* m2 = c ^ (d mod (q-1)) mod q
* h = u * (m2 - m1) mod q
* m = m1 + h * p
*
* Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
*/
static void
secret(MPI output, MPI input, RSA_secret_key *skey )
{
#if 0
mpi_powm( output, input, skey->d, skey->n );
#else
MPI m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
MPI m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
MPI h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
/* m1 = c ^ (d mod (p-1)) mod p */
mpi_sub_ui( h, skey->p, 1 );
mpi_fdiv_r( h, skey->d, h );
mpi_powm( m1, input, h, skey->p );
/* m2 = c ^ (d mod (q-1)) mod q */
mpi_sub_ui( h, skey->q, 1 );
mpi_fdiv_r( h, skey->d, h );
mpi_powm( m2, input, h, skey->q );
/* h = u * ( m2 - m1 ) mod q */
mpi_sub( h, m2, m1 );
if ( mpi_is_neg( h ) )
mpi_add ( h, h, skey->q );
mpi_mulm( h, skey->u, h, skey->q );
/* m = m2 + h * p */
mpi_mul ( h, h, skey->p );
mpi_add ( output, m1, h );
/* ready */
mpi_free ( h );
mpi_free ( m1 );
mpi_free ( m2 );
#endif
}
/*********************************************
************** interface ******************
*********************************************/
@ -226,7 +316,7 @@ rsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
RSA_secret_key sk;
if( !is_RSA(algo) )
return G10ERR_PUBKEY_ALGO;
return GCRYERR_INV_PK_ALGO;
generate( &sk, nbits );
skey[0] = sk.n;
@ -236,7 +326,7 @@ rsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
skey[4] = sk.q;
skey[5] = sk.u;
/* make an empty list of factors */
*retfactors = m_alloc_clear( 1 * sizeof **retfactors );
*retfactors = g10_xcalloc( 1, sizeof **retfactors );
return 0;
}
@ -247,7 +337,7 @@ rsa_check_secret_key( int algo, MPI *skey )
RSA_secret_key sk;
if( !is_RSA(algo) )
return G10ERR_PUBKEY_ALGO;
return GCRYERR_INV_PK_ALGO;
sk.n = skey[0];
sk.e = skey[1];
@ -256,7 +346,7 @@ rsa_check_secret_key( int algo, MPI *skey )
sk.q = skey[4];
sk.u = skey[5];
if( !check_secret_key( &sk ) )
return G10ERR_BAD_SECKEY;
return GCRYERR_INV_PK_ALGO;
return 0;
}
@ -269,7 +359,7 @@ rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
RSA_public_key pk;
if( algo != 1 && algo != 2 )
return G10ERR_PUBKEY_ALGO;
return GCRYERR_INV_PK_ALGO;
pk.n = pkey[0];
pk.e = pkey[1];
@ -284,7 +374,7 @@ rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
RSA_secret_key sk;
if( algo != 1 && algo != 2 )
return G10ERR_PUBKEY_ALGO;
return GCRYERR_INV_PK_ALGO;
sk.n = skey[0];
sk.e = skey[1];
@ -303,7 +393,7 @@ rsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
RSA_secret_key sk;
if( algo != 1 && algo != 3 )
return G10ERR_PUBKEY_ALGO;
return GCRYERR_INV_PK_ALGO;
sk.n = skey[0];
sk.e = skey[1];
@ -326,13 +416,13 @@ rsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int rc;
if( algo != 1 && algo != 3 )
return G10ERR_PUBKEY_ALGO;
return GCRYERR_INV_PK_ALGO;
pk.n = pkey[0];
pk.e = pkey[1];
result = mpi_alloc( (160+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB);
public( result, data[0], &pk );
/*rc = (*cmp)( opaquev, result );*/
rc = mpi_cmp( result, hash )? G10ERR_BAD_SIGN:0;
rc = mpi_cmp( result, hash )? GCRYERR_BAD_SIGNATURE:0;
mpi_free(result);
return rc;
@ -366,10 +456,16 @@ rsa_get_info( int algo,
*nsig = 1;
switch( algo ) {
case 1: *usage = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC; return "RSA";
case 2: *usage = PUBKEY_USAGE_ENC; return "RSA-E";
case 3: *usage = PUBKEY_USAGE_SIG; return "RSA-S";
case 1: *usage = GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR; return "RSA";
case 2: *usage = GCRY_PK_USAGE_ENCR; return "RSA-E";
case 3: *usage = GCRY_PK_USAGE_SIGN; return "RSA-S";
default:*usage = 0; return NULL;
}
}

View File

@ -48,6 +48,11 @@ case "$use_static_rnd" in
;;
esac
AC_ARG_WITH(egd-socket,
[ --with-egd-socket=NAME Use NAME for the EGD socket)],
egd_socket_name="$withval", egd_socket_name="" )
AC_DEFINE_UNQUOTED(EGD_SOCKET_NAME, "$egd_socket_name")
dnl
@ -164,6 +169,7 @@ AC_ISC_POSIX
AC_PROG_INSTALL
AC_PROG_AWK
GPH_PROG_DOCBOOK
GNUPG_CHECK_FAQPROG
dnl
@ -271,19 +277,30 @@ case "${target}" in
*-openbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic -fpic -Wl,-Bshareable -Wl,-x"
DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x"
;;
*-netbsd*)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic -fpic -Wl,-Bshareable -Wl,-x"
DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x"
;;
*-solaris*)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/random"
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
;;
*)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
# -shared is a gcc-ism. Find pic flags from GNUPG_CHECK_PIC.
if test -n "$GCC" ; then
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
else
DYNLINK_MOD_CFLAGS="$CFLAGS_PIC"
fi
;;
esac
AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM")
@ -429,7 +446,7 @@ AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror stpcpy strlwr stricmp tcgetattr rand strtoul mmap)
AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit clock_gettime)
AC_CHECK_FUNCS(memicmp atexit raise getpagesize strftime nl_langinfo)
AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask)
AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask fopen64 fstat64)
GNUPG_CHECK_MLOCK
GNUPG_FUNC_MKDIR_TAKES_ONE_ARG
@ -473,7 +490,7 @@ dnl check whether we have a random device
dnl
if test "$try_dev_random" = yes ; then
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
[if test -c "$NAME_OF_DEV_RANDOM" && test -c "$NAME_OF_DEV_URANDOM" ; then
[if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then
ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi])
if test "$ac_cv_have_dev_random" = yes; then
AC_DEFINE(HAVE_DEV_RANDOM)
@ -740,10 +757,16 @@ cat >gnupg-defs.tmp <<G10EOF
#define GNUPG_LOCALEDIR "c:/lib/gnupg/locale"
#define GNUPG_LIBDIR "c:/lib/gnupg"
#define GNUPG_DATADIR "c:/lib/gnupg"
#define GNUPG_HOMEDIR "c:/gnupg-test"
#else
#define GNUPG_LOCALEDIR "${prefix}/${DATADIRNAME}/locale"
#define GNUPG_LIBDIR "${libdir}/gnupg"
#define GNUPG_DATADIR "${datadir}/gnupg"
#ifdef __VMS
#define GNUPG_HOMEDIR "/SYS\$LOGIN/gnupg"
#else
#define GNUPG_HOMEDIR "~/.gnupg-test"
#endif
#endif
G10EOF
if cmp -s gnupg-defs.h gnupg-defs.tmp 2>/dev/null; then

View File

@ -1,3 +1,81 @@
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* parse-packet.c (dump_sig_subpkt): Dump key flags.
(parse_one_sig_subpkt,can_handle_critical): Add KeyFlags support.
* build-packet.c (build_sig_subpkt): Ditto.
* g10.c: New option --allow-freeform-uid. By Jeroen C. van Gelderen.
* keygen.c (ask_user_id): Implemented here.
* parse-packet.c (dump_sig_subpkt): Print info about the ARR.
* openfile.c (overwrite_filep): Always return okay if the file is
called /dev/null.
(make_outfile_name): Add ".sign" to the list of know extensions.
(open_sigfile): Ditto.
* getkey.c: Large parts rewritten to have a better sub key selection
and handle some meta information from signatures more correctly.
(get_primary_seckey): Removed.
* seckey_cert.c (do_check): Set main keyid from the data in the sk.
* free-packet.c (copy_public_parts_to_secret_key): New.
* sig-check.c (check_key_signature2): Enabled shortcut for already
checked signatures.
* keydb.h: New macros IS_xxx_SIG, IS_xxx_REV.
* misc.c (openpgp_pk_algo_usage): New.
* packet.h: New field req_uage and do not use pubkey_usage anymore
to request a specific usage. Changed at all places.
* keyid.c (keyid_from_sk): Cache the keyid in the sk
* passphrase.c (hash_passphrase): Removed funny assert. Reported by
David Mathog.
* keyedit.c (keyedit_menu): Allow "debug" on secret keys.
* keygen.c (keygen_add_std_prefs): Changed order of preferences to
twofish, cast5, blowfish.
* gpg.c: The --trusted-key option is back.
* trustdb.c (verify_own_key): Handle this option.
(add_ultimate_key): Moved stuff from verify_own_key to this new func.
(register_trusted_key): New.
* openfile.c (try_make_homedir): Changes for non-Posix systems.
* gpg.c (main): Take the default homedir from macro.
* encode.c (encode_simple, encode_crypt): Fix for large files.
* sign.c (sign_file): Ditto.
* gpg.c (main): Don't set --quite along with --no-tty. By Frank Tobin.
* misc.c (disable_core_dump): Don't display a warning here but a return
a status value and ...
* gpg.c (main): ...print warning here. Suggested by Sam Roberts.
* misc.c (print_pubkey_algo_note): Do not print the RSA notice.
* sig-check.c (do_signature_check): Do not emit the RSA status message.
* pubkey-enc.c (get_session_key): Ditto.
* ringedit.c (cmp_seckey): Fix for v4 RSA keys.
* seckey-cert.c (do_check): Workaround for PGP 7 bug.
* pkclist.c (algo_available): Removed hack to disable Twofish.
* gpg.c (main): Default S2K algorithms are now SHA1 and CAST5 - this
should solve a lot of compatibility problems with other OpenPGP
apps because those algorithms are SHOULD and not optional. The old
way to force it was by using the --openpgp option whith the drawback
that this would disable a couple of workarounds for PGP.
* gpg.c: New option --merge-only. Suggested by Brendan O'Dea.
* import.c (import_one): Implemented it here.
(import_secret_one): Ditto.
(print_stats): and give some stats.
* gpg.c: New option --try-all-secrets on suggestion from
Matthias Urlichs.
* pubkey-enc.c (get_session_key): Quite easy to implement here.
Mon Aug 21 17:59:17 CEST 2000 Werner Koch <wk@openit.de>
* gpg.c: New option --use-agent

View File

@ -701,6 +701,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
case SIGSUBPKT_NOTATION:
case SIGSUBPKT_POLICY:
case SIGSUBPKT_REVOC_REASON:
case SIGSUBPKT_KEY_FLAGS:
hashed = 1; break;
default: hashed = 0; break;
}

View File

@ -220,6 +220,10 @@ encode_simple( const char *filename, int mode )
if( filename && !opt.textmode && !mode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
/* we can't yet encode the length of very large files,
* so we switch to partial length encoding in this case */
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
}
else
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
@ -368,6 +372,10 @@ encode_crypt( const char *filename, STRLIST remusr )
if( filename && !opt.textmode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
/* we can't yet encode the length of very large files,
* so we switch to partial lengthn encoding in this case */
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
}
else
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

View File

@ -139,6 +139,32 @@ copy_public_key( PKT_public_key *d, PKT_public_key *s )
return copy_public_key_new_namehash( d, s, NULL );
}
/****************
* Replace all common parts of a sk by the one from the public key.
* This is a hack and a better solution will be to just store the real secret
* parts somewhere and don't duplicate all the other stuff.
*/
void
copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
{
sk->expiredate = pk->expiredate;
sk->pubkey_algo = pk->pubkey_algo;
sk->pubkey_usage= pk->pubkey_usage;
sk->created = pk->created;
sk->req_usage = pk->req_usage;
sk->req_algo = pk->req_algo;
sk->has_expired = pk->has_expired;
sk->is_revoked = pk->is_revoked;
sk->is_valid = pk->is_valid;
sk->main_keyid[0]= pk->main_keyid[0];
sk->main_keyid[1]= pk->main_keyid[1];
sk->keyid[0] = pk->keyid[0];
sk->keyid[1] = pk->keyid[1];
}
PKT_signature *
copy_signature( PKT_signature *d, PKT_signature *s )
{
@ -450,3 +476,7 @@ cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
}

File diff suppressed because it is too large Load Diff

View File

@ -179,6 +179,7 @@ enum cmd_and_opt_values { aNull = 0,
oDisableCipherAlgo,
oDisablePubkeyAlgo,
oAllowNonSelfsignedUID,
oAllowFreeformUID,
oNoLiteral,
oSetFilesize,
oHonorHttpProxy,
@ -188,7 +189,9 @@ enum cmd_and_opt_values { aNull = 0,
oNoRandomSeedFile,
oNoAutoKeyRetrieve,
oUseAgent,
oEmu3DESS2KBug, /* will be removed in 1.1 */
oMergeOnly,
oTryAllSecrets,
oTrustedKey,
oEmuMDEncodeBug,
aTest };
@ -290,6 +293,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCompletesNeeded, "completes-needed", 1, "@"},
{ oMarginalsNeeded, "marginals-needed", 1, "@"},
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
{ oTrustedKey, "trusted-key", 2, N_("|KEYID|ulimately trust this key")},
{ oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
{ oOpenPGP, "openpgp", 0, N_("set all packet, cipher and digest options to OpenPGP behavior")},
@ -362,6 +366,7 @@ static ARGPARSE_OPTS opts[] = {
{ oDisableCipherAlgo, "disable-cipher-algo", 2, "@" },
{ oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" },
{ oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
{ oAllowFreeformUID, "allow-freeform-uid", 0, "@" },
{ oNoLiteral, "no-literal", 0, "@" },
{ oSetFilesize, "set-filesize", 20, "@" },
{ oHonorHttpProxy,"honor-http-proxy", 0, "@" },
@ -370,7 +375,8 @@ static ARGPARSE_OPTS opts[] = {
{ oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
{ oNoRandomSeedFile, "no-random-seed-file", 0, "@" },
{ oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
{ oEmu3DESS2KBug, "emulate-3des-s2k-bug", 0, "@"},
{ oMergeOnly, "merge-only", 0, "@" },
{ oTryAllSecrets, "try-all-secrets", 0, "@" },
{ oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
{0} };
@ -601,6 +607,7 @@ main( int argc, char **argv )
char **orig_argv;
const char *fname;
char *username;
int may_coredump;
STRLIST sl, remusr= NULL, locusr=NULL;
STRLIST nrings=NULL, sec_nrings=NULL;
armor_filter_context_t afx;
@ -642,7 +649,7 @@ main( int argc, char **argv )
}
gcry_control( GCRYCTL_USE_SECURE_RNDPOOL );
disable_core_dumps();
may_coredump = disable_core_dumps();
init_signals();
create_dotlock(NULL); /* register locking cleanup */
i18n_init();
@ -653,8 +660,8 @@ main( int argc, char **argv )
opt.def_digest_algo = 0;
opt.def_compress_algo = 2;
opt.s2k_mode = 3; /* iterated+salted */
opt.s2k_digest_algo = GCRY_MD_RMD160;
opt.s2k_cipher_algo = GCRY_CIPHER_BLOWFISH;
opt.s2k_digest_algo = GCRY_MD_SHA1;
opt.s2k_cipher_algo = GCRY_CIPHER_CAST5;
opt.completes_needed = 1;
opt.marginals_needed = 3;
opt.max_cert_depth = 5;
@ -666,11 +673,7 @@ main( int argc, char **argv )
opt.homedir = getenv("GNUPGHOME");
#endif
if( !opt.homedir || !*opt.homedir ) {
#ifdef HAVE_DRIVE_LETTERS
opt.homedir = "c:/gnupg-test";
#else
opt.homedir = "~/.gnupg-test";
#endif
opt.homedir = GNUPG_HOMEDIR;
}
/* check whether we have a config file on the commandline */
@ -801,7 +804,7 @@ main( int argc, char **argv )
case oArmor: opt.armor = 1; opt.no_armor=0; break;
case oOutput: opt.outfile = pargs.r.ret_str; break;
case oQuiet: opt.quiet = 1; break;
case oNoTTY: opt.quiet = 1; tty_no_terminal(1); break;
case oNoTTY: tty_no_terminal(1); break;
case oDryRun: opt.dry_run = 1; break;
case oInteractive: opt.interactive = 1; break;
case oVerbose:
@ -894,7 +897,6 @@ main( int argc, char **argv )
opt.s2k_digest_algo = GCRY_MD_SHA1;
opt.s2k_cipher_algo = GCRY_CIPHER_CAST5;
break;
case oEmu3DESS2KBug: opt.emulate_bugs |= EMUBUG_3DESS2K; break;
case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break;
case oCompressSigs: opt.compress_sigs = 1; break;
case oRunAsShmCP:
@ -965,6 +967,7 @@ main( int argc, char **argv )
}
break;
case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
case oNoLiteral: opt.no_literal = 1; break;
case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
case oHonorHttpProxy: opt.honor_http_proxy = 1; break;
@ -973,6 +976,9 @@ main( int argc, char **argv )
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
case oNoRandomSeedFile: use_random_seed = 0; break;
case oNoAutoKeyRetrieve: opt.auto_key_retrieve = 0; break;
case oMergeOnly: opt.merge_only = 1; break;
case oTryAllSecrets: opt.try_all_secrets = 1; break;
case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
default : pargs.err = configfp? 1:2; break;
}
@ -1001,6 +1007,10 @@ main( int argc, char **argv )
log_info("used in a production environment or with production keys!\n");
}
#endif
if( may_coredump && !opt.quiet )
log_info(_("WARNING: program may create a core file!\n"));
if (opt.no_literal) {
log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
if (opt.textmode)
@ -1406,9 +1416,13 @@ main( int argc, char **argv )
case aPrimegen:
{ int mode = argc < 2 ? 0 : atoi(*argv);
{
#if 1
log_error( "command is currently not implemented\n");
#else
/* FIXME: disabled until we have an API to create primes */
int mode = argc < 2 ? 0 : atoi(*argv);
#if 0 /* FIXME: disabled until we have an API to create primes */
if( mode == 1 && argc == 2 ) {
mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
}
@ -1435,9 +1449,9 @@ main( int argc, char **argv )
mpi_release(g);
}
else
#endif
wrong_args("--gen-prime mode bits [qbits] ");
putchar('\n');
#endif
}
break;

View File

@ -50,6 +50,7 @@ static struct {
ulong secret_read;
ulong secret_imported;
ulong secret_dups;
ulong skipped_new_keys;
} stats;
@ -201,6 +202,9 @@ print_stats()
{
if( !opt.quiet ) {
log_info(_("Total number processed: %lu\n"), stats.count );
if( stats.skipped_new_keys )
log_info(_(" skipped new keys: %lu\n"),
stats.skipped_new_keys );
if( stats.no_user_id )
log_info(_(" w/o user IDs: %lu\n"), stats.no_user_id );
if( stats.imported || stats.imported_rsa ) {
@ -413,6 +417,13 @@ import_one( const char *fname, KBNODE keyblock, int fast )
log_error( _("key %08lX: public key not found: %s\n"),
(ulong)keyid[1], gpg_errstr(rc));
}
else if ( rc && opt.merge_only ) {
if( opt.verbose )
log_info( _("key %08lX: new key - skipped\n"), (ulong)keyid[1] );
rc = 0;
fast = 1; /* so that we don't get into the trustdb update */
stats.skipped_new_keys++;
}
else if( rc ) { /* insert this key */
/* get default resource */
if( get_keyblock_handle( NULL, 0, &kbpos ) ) {
@ -583,7 +594,7 @@ import_secret_one( const char *fname, KBNODE keyblock )
/* do we have this key already in one of our secrings ? */
rc = seckey_available( keyid );
if( rc == GPGERR_NO_SECKEY ) { /* simply insert this key */
if( rc == GPGERR_NO_SECKEY && !opt.merge_only ) { /* simply insert this key */
/* get default resource */
if( get_keyblock_handle( NULL, 1, &kbpos ) ) {
log_error("no default secret keyring\n");

View File

@ -31,6 +31,15 @@
#define MAX_FINGERPRINT_LEN 20
#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18)
#define IS_KEY_REV(s) ((s)->sig_class == 0x20)
#define IS_UID_REV(s) ((s)->sig_class == 0x30)
#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28)
struct getkey_ctx_s;
typedef struct getkey_ctx_s *GETKEY_CTX;

View File

@ -592,7 +592,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
{ N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") },
{ N_("s") , cmdSIGN , 0,1,1, NULL },
{ N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") },
{ N_("debug") , cmdDEBUG , 0,1,0, NULL },
{ N_("debug") , cmdDEBUG , 0,0,0, NULL },
{ N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") },
{ N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") },
{ N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") },

View File

@ -136,8 +136,8 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
keygen_add_key_expire( sig, opaque );
buf[0] = GCRY_CIPHER_TWOFISH;
buf[1] = GCRY_CIPHER_BLOWFISH;
buf[2] = GCRY_CIPHER_CAST5;
buf[1] = GCRY_CIPHER_CAST5;
buf[2] = GCRY_CIPHER_BLOWFISH;
build_sig_subpkt( sig, SIGSUBPKT_PREF_SYM, buf, 3 );
buf[0] = GCRY_MD_RMD160;
@ -889,7 +889,11 @@ ask_user_id( int mode )
aname = cpr_get("keygen.name",_("Real name: "));
trim_spaces(aname);
cpr_kill_prompt();
if( strpbrk( aname, "<([])>" ) )
if( opt.allow_freeform_uid )
break;
if( strpbrk( aname, "<>" ) )
tty_printf(_("Invalid character in name\n"));
else if( isdigit(*aname) )
tty_printf(_("Name may not start with a digit\n"));

View File

@ -166,11 +166,17 @@ keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
if( !keyid )
keyid = dummy_keyid;
if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
if( sk->keyid[0] || sk->keyid[1] ) {
keyid[0] = sk->keyid[0];
keyid[1] = sk->keyid[1];
}
else if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
if( pubkey_get_npkey(sk->pubkey_algo) )
v3_keyid( sk->skey[0], keyid ); /* take n */
else
keyid[0] = keyid[1] = 0;
sk->keyid[0] = keyid[0];
sk->keyid[1] = keyid[1];
}
else {
const byte *dp;
@ -180,6 +186,8 @@ keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
gcry_md_close(md);
sk->keyid[0] = keyid[0];
sk->keyid[1] = keyid[1];
}
return keyid[1];

View File

@ -51,7 +51,7 @@ char *make_radix64_string( const byte *data, size_t len );
/*-- misc.c --*/
void trap_unaligned(void);
void disable_core_dumps(void);
int disable_core_dumps(void);
u16 checksum_u16( unsigned n );
u16 checksum( byte *p, unsigned n );
u16 checksum_mpi( MPI a );
@ -65,6 +65,7 @@ int mpi_print( FILE *fp, MPI a, int mode );
int openpgp_cipher_test_algo( int algo );
int openpgp_pk_test_algo( int algo, unsigned int usage_flags );
int openpgp_pk_algo_usage ( int algo );
int openpgp_md_test_algo( int algo );
int pubkey_get_npkey( int algo );

View File

@ -68,22 +68,24 @@ trap_unaligned(void)
#endif
void
int
disable_core_dumps()
{
#ifndef HAVE_DOSISH_SYSTEM
#ifdef HAVE_DOSISH_SYSTEM
return 0;
#else
#ifdef HAVE_SETRLIMIT
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
if( !setrlimit( RLIMIT_CORE, &limit ) )
return;
if( errno != EINVAL )
return 0;
if( errno != EINVAL && errno != ENOSYS )
log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
#endif
if( !opt.quiet )
log_info(_("WARNING: program may create a core file!\n"));
return 1;
#endif
}
@ -318,15 +320,6 @@ print_pubkey_algo_note( int algo )
{
if( algo >= 100 && algo <= 110 )
no_exp_algo();
else if( is_RSA( algo ) ) {
static int did_note = 0;
if( !did_note ) {
did_note = 1;
log_info(_("RSA keys are deprecated; please consider "
"creating a new key and use this key in the future\n"));
}
}
}
void
@ -362,7 +355,7 @@ print_digest_algo_note( int algo )
/****************
* Wrapper around the libgcrypt function with addional checks on
* openPGP contrainst for the algo ID.
* openPGP contraints for the algo ID.
*/
int
openpgp_cipher_test_algo( int algo )
@ -382,6 +375,40 @@ openpgp_pk_test_algo( int algo, unsigned int usage_flags )
return gcry_pk_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, &n );
}
int
openpgp_pk_algo_usage ( int algo )
{
int usage = 0;
/* some are hardwired */
switch ( algo ) {
case GCRY_PK_RSA:
usage = GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR;
break;
case GCRY_PK_RSA_E:
usage = GCRY_PK_USAGE_ENCR;
break;
case GCRY_PK_RSA_S:
usage = GCRY_PK_USAGE_SIGN;
break;
case GCRY_PK_ELG_E:
usage = GCRY_PK_USAGE_ENCR;
break;
case GCRY_PK_DSA:
usage = GCRY_PK_USAGE_SIGN;
break;
case GCRY_PK_ELG:
usage = GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR;
break;
default:
usage = gcry_pk_algo_info ( algo, GCRYCTL_GET_ALGO_USAGE,
NULL, NULL);
}
return usage;
}
int
openpgp_md_test_algo( int algo )

View File

@ -70,6 +70,11 @@ overwrite_filep( const char *fname )
if( access( fname, F_OK ) )
return 1; /* does not exist */
#ifndef HAVE_DOSISH_SYSTEM
if ( !strcmp ( fname, "/dev/null" ) )
return 1; /* does not do any harm */
#endif
/* fixme: add some backup stuff in case of overwrite */
if( opt.answer_yes )
return 1;
@ -105,6 +110,12 @@ make_outfile_name( const char *iname )
buf[n-4] = 0;
return buf;
}
else if( n > 5 && !CMP_FILENAME(iname+n-5,".sign") ) {
char *buf = gcry_xstrdup( iname );
buf[n-5] = 0;
return buf;
}
log_info(_("%s: unknown suffix\n"), iname );
return NULL;
@ -241,6 +252,7 @@ open_sigfile( const char *iname )
if( iname && !(*iname == '-' && !iname[1]) ) {
len = strlen(iname);
if( len > 4 && ( !strcmp(iname + len - 4, ".sig")
|| ( len > 5 && !strcmp(iname + len - 5, ".sign") )
|| !strcmp(iname + len - 4, ".asc")) ) {
char *buf;
buf = gcry_xstrdup(iname);
@ -305,10 +317,24 @@ copy_options_file( const char *destdir )
void
try_make_homedir( const char *fname )
{
const char *defhome = GNUPG_HOMEDIR;
/* Create the directory only if the supplied directory name
* is the same as the default one. This way we avoid to create
* arbitrary directories when a non-default homedirectory is used.
* To cope with HOME, we do compare only the suffix if we see that
* the default homedir does start with a tilde.
*/
if( opt.dry_run )
return;
if( strlen(fname) >= 7
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
if ( ( *defhome == '~'
&& ( strlen(fname) >= strlen (defhome+1)
&& !strcmp(fname+strlen(defhome+1)-strlen(defhome+1),
defhome+1 ) ))
|| ( *defhome != '~'
&& !compare_filenames( fname, defhome ) )
) {
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
log_fatal( _("%s: can't create directory: %s\n"),
fname, strerror(errno) );
@ -321,3 +347,5 @@ try_make_homedir( const char *fname )
}
}

View File

@ -84,6 +84,7 @@ struct {
const char *set_policy_url;
int use_embedded_filename;
int allow_non_selfsigned_uid;
int allow_freeform_uid;
int no_literal;
ulong set_filesize;
int honor_http_proxy;
@ -92,6 +93,8 @@ struct {
int command_fd;
int auto_key_retrieve;
int use_agent;
int merge_only;
int try_all_secrets;
} opt;

View File

@ -128,8 +128,15 @@ typedef struct {
byte hdrbytes; /* number of header bytes */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
byte pubkey_usage; /* for now only used to pass it to getkey() */
byte pubkey_usage; /* the actual allowed usage as set by getkey() */
u32 created; /* according to the self-signature */
byte req_usage; /* hack to pass a request to getkey() */
byte req_algo; /* Ditto */
u32 has_expired; /* set to the expiration date if expired */
int is_revoked; /* key has been revoked */
int is_valid; /* key (especially subkey) is valid */
ulong local_id; /* internal use, valid if > 0 */
u32 main_keyid[2]; /* keyid of the primary key */
u32 keyid[2]; /* calculated by keyid_from_pk() */
byte *namehash; /* if != NULL: found by this name */
MPI pkey[GNUPG_MAX_NPKEY];
@ -142,6 +149,14 @@ typedef struct {
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
byte pubkey_usage;
u32 created; /* according to the self-signature */
byte req_usage;
byte req_algo;
u32 has_expired; /* set to the expiration date if expired */
int is_revoked; /* key has been revoked */
int is_valid; /* key (especially subkey) is valid */
u32 main_keyid[2]; /* keyid of the primary key */
u32 keyid[2];
byte is_primary;
byte is_protected; /* The secret info is protected and must */
/* be decrypted before use, the protected */
@ -169,6 +184,10 @@ typedef struct {
int len; /* length of the name */
char *photo; /* if this is not NULL, the packet is a photo ID */
int photolen; /* and the length of the photo */
int help_key_usage;
u32 help_key_expire;
int is_primary;
u32 created; /* according to the self-signature */
char name[1];
} PKT_user_id;
@ -322,6 +341,8 @@ PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
PKT_public_key *copy_public_key_new_namehash( PKT_public_key *d,
PKT_public_key *s,
const byte *namehash );
void copy_public_parts_to_secret_key( PKT_public_key *pk,
PKT_secret_key *sk );
PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
PKT_user_id *copy_user_id( PKT_user_id *d, PKT_user_id *s );

View File

@ -700,6 +700,17 @@ dump_sig_subpkt( int hashed, int type, int critical,
const char *p=NULL;
int i;
/* The CERT has warning out with explains how to use GNUPG to
* detect the ARRs - we print our old message here when it is a faked
* ARR and add an additional notice */
if ( type == SIGSUBPKT_ARR && !hashed ) {
printf("\tsubpkt %d len %u (additional recipient request)\n"
"WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
"encrypt to this key and thereby reveal the plaintext to "
"the owner of this ARR key. Detailed info follows:\n",
type, (unsigned)length );
}
printf("\t%s%ssubpkt %d len %u (", /*)*/
critical ? "critical ":"",
hashed ? "hashed ":"", type, (unsigned)length );
@ -737,9 +748,6 @@ dump_sig_subpkt( int hashed, int type, int critical,
printf("key expires after %s",
strtimevalue( buffer_to_u32(buffer) ) );
break;
case SIGSUBPKT_ARR:
p = "additional recipient request";
break;
case SIGSUBPKT_PREF_SYM:
fputs("pref-sym-algos:", stdout );
for( i=0; i < length; i++ )
@ -809,8 +817,10 @@ dump_sig_subpkt( int hashed, int type, int critical,
print_string( stdout, buffer, length, ')' );
break;
case SIGSUBPKT_KEY_FLAGS:
p = "key flags";
break;
fputs ( "key flags:", stdout );
for( i=0; i < length; i++ )
printf(" %02X", buffer[i] );
break;
case SIGSUBPKT_SIGNERS_UID:
p = "signer's user ID";
break;
@ -821,6 +831,16 @@ dump_sig_subpkt( int hashed, int type, int critical,
p = ")";
}
break;
case SIGSUBPKT_ARR:
fputs("Big Brother's key (ignored): ", stdout );
if( length < 22 )
p = "[too short]";
else {
printf("c=%02x a=%d f=", buffer[0], buffer[1] );
for( i=2; i < length; i++ )
printf("%02X", buffer[i] );
}
break;
case SIGSUBPKT_PRIV_ADD_SIG:
p = "signs additional user ID";
break;
@ -846,6 +866,8 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
if( n < 4 )
break;
return 0;
case SIGSUBPKT_KEY_FLAGS:
return 0;
case SIGSUBPKT_EXPORTABLE:
if( !n )
break;
@ -867,6 +889,10 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
case SIGSUBPKT_PREF_COMPR:
case SIGSUBPKT_POLICY:
return 0;
case SIGSUBPKT_PRIMARY_UID:
if ( n != 1 )
break;
return 0;
case SIGSUBPKT_PRIV_ADD_SIG:
/* because we use private data, we check the GNUPG marker */
if( n < 24 )
@ -897,6 +923,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR:
case SIGSUBPKT_KEY_FLAGS:
return 1;
case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
@ -1288,7 +1315,8 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
sk->version = version;
sk->is_primary = pkttype == PKT_SECRET_KEY;
sk->pubkey_algo = algorithm;
sk->pubkey_usage = 0; /* not yet used */
sk->req_usage = 0;
sk->pubkey_usage = 0; /* will be set by getkey functions */
}
else {
PKT_public_key *pk = pkt->pkt.public_key;
@ -1298,7 +1326,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
pk->hdrbytes = hdrlen;
pk->version = version;
pk->pubkey_algo = algorithm;
pk->pubkey_usage = 0; /* not yet used */
pk->req_usage = 0;
pk->pubkey_usage = 0; /* will be set bey getkey functions */
pk->is_revoked = 0;
pk->keyid[0] = 0;
pk->keyid[1] = 0;
}

View File

@ -640,7 +640,6 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
else {
gcry_md_write( md, s2k->salt, 8 );
count -= 8;
assert( count >= 0 );
gcry_md_write( md, pw, count );
}
}

View File

@ -814,13 +814,12 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
any_recipients = 1;
else if( (use & GCRY_PK_USAGE_ENCR) && !opt.no_encrypt_to ) {
pk = gcry_xcalloc( 1, sizeof *pk );
pk->pubkey_usage = use;
pk->req_usage = use;
if( (rc = get_pubkey_byname( NULL, pk, rov->d, NULL )) ) {
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), rov->d, gpg_errstr(rc) );
}
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
/* Skip the actual key if the key is already present
* in the list */
if (key_present_in_pk_list(pk_list, pk) == 0) {
@ -871,7 +870,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
if( pk )
free_public_key( pk );
pk = gcry_xcalloc( 1, sizeof *pk );
pk->pubkey_usage = use;
pk->req_usage = use;
rc = get_pubkey_byname( NULL, pk, answer, NULL );
if( rc )
tty_printf(_("No such user ID.\n"));
@ -937,7 +936,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
}
else if( !any_recipients && (def_rec = default_recipient()) ) {
pk = gcry_xcalloc( 1, sizeof *pk );
pk->pubkey_usage = use;
pk->req_usage = use;
rc = get_pubkey_byname( NULL, pk, def_rec, NULL );
if( rc )
log_error(_("unknown default recipient `%s'\n"), def_rec );
@ -962,7 +961,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
continue; /* encrypt-to keys are already handled */
pk = gcry_xcalloc( 1, sizeof *pk );
pk->pubkey_usage = use;
pk->req_usage = use;
if( (rc = get_pubkey_byname( NULL, pk, remusr->d, NULL )) ) {
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), remusr->d, gpg_errstr(rc) );
@ -1033,8 +1032,6 @@ static int
algo_available( int preftype, int algo )
{
if( preftype == PREFTYPE_SYM ) {
if( algo == GCRY_CIPHER_TWOFISH )
return 0; /* we don't want to generate Twofish messages for now*/
return algo && !openpgp_cipher_test_algo( algo );
}
else if( preftype == PREFTYPE_HASH ) {

View File

@ -106,14 +106,11 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
PKT_secret_key *sk = NULL;
int rc;
if( is_RSA(k->pubkey_algo) ) /* warn about that */
write_status(STATUS_RSA_OR_IDEA);
rc = openpgp_pk_test_algo( k->pubkey_algo, 0 );
if( rc )
goto leave;
if( k->keyid[0] || k->keyid[1] ) {
if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) {
sk = gcry_xcalloc( 1, sizeof *sk );
sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/
if( !(rc = get_seckey( sk, k->keyid )) )

View File

@ -1114,7 +1114,13 @@ cmp_seckey( PKT_secret_key *req_sk, PKT_secret_key *sk )
n = pubkey_get_nskey( req_sk->pubkey_algo );
for(i=0; i < n; i++ ) {
if( mpi_cmp( req_sk->skey[i], sk->skey[i] ) )
/* Note: because v4 protected keys have nothing in the
* mpis except for the first one, we skip all NULL MPIs.
* This might not be always correct in cases where the both
* keys do not match in their secret parts but we can ignore that
* because the need for this function is quite ugly. */
if( req_sk->skey[1] && sk->skey[i]
&& mpi_cmp( req_sk->skey[i], sk->skey[i] ) )
return -1;
}
return 0;

View File

@ -100,10 +100,8 @@ do_check( PKT_secret_key *sk )
keyid_from_sk( sk, keyid );
keyid[2] = keyid[3] = 0;
if( !sk->is_primary ) {
PKT_secret_key *sk2 = gcry_xcalloc( 1, sizeof *sk2 );
if( !get_primary_seckey( sk2, keyid ) )
keyid_from_sk( sk2, keyid+2 );
free_secret_key( sk2 );
keyid[2] = sk->main_keyid[0];
keyid[3] = sk->main_keyid[1];
}
dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
&sk->protect.s2k, 0 );
@ -128,11 +126,14 @@ do_check( PKT_secret_key *sk )
size_t ndata;
unsigned int ndatabits;
byte *p, *data;
u16 csumc = 0;
i = pubkey_get_npkey(sk->pubkey_algo);
assert( gcry_mpi_get_flag( sk->skey[i], GCRYMPI_FLAG_OPAQUE ) );
p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
ndata = (ndatabits+7)/8;
if ( ndata > 1 )
csumc = p[ndata-2] << 8 | p[ndata-1];
data = gcry_xmalloc_secure( ndata );
gcry_cipher_decrypt( cipher_hd, data, ndata, p, ndata );
mpi_release( sk->skey[i] ); sk->skey[i] = NULL ;
@ -145,6 +146,10 @@ do_check( PKT_secret_key *sk )
else {
csum = checksum( data, ndata-2);
sk->csum = data[ndata-2] << 8 | data[ndata-1];
if ( sk->csum != csum ) {
/* This is a PGP 7.0.0 workaround */
sk->csum = csumc; /* take the encrypted one */
}
}
/* must check it here otherwise the mpi_read_xx would fail
* because the length may have an arbitrary value */
@ -321,8 +326,6 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
#warning FIXME: replace set/get buffer
if( sk->version >= 4 ) {
/* FIXME: There is a bug in this function for all algorithms
* where the secret MPIs are more than 1 */
byte *bufarr[GNUPG_MAX_NSKEY];
unsigned narr[GNUPG_MAX_NSKEY];
unsigned nbits[GNUPG_MAX_NSKEY];

View File

@ -134,9 +134,6 @@ do_signature_check( PKT_signature *sig, GCRY_MD_HD digest,
PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
int rc=0;
if( is_RSA(sig->pubkey_algo) )
write_status(STATUS_RSA_OR_IDEA);
*r_expiredate = 0;
if( get_pubkey( pk, sig->keyid ) )
rc = GPGERR_NO_PUBKEY;
@ -451,10 +448,18 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
sig = node->pkt->pkt.signature;
algo = sig->digest_algo;
#if 0 /* I am not sure whether this is a good thing to do */
if( sig->flags.checked )
#if 0
if( sig->flags.checked ) {
log_debug("check_key_signature: already checked: %s\n",
sig->flags.valid? "good":"bad" );
if ( sig->flags.valid )
return 0; /* shortcut already checked signatures */
/* FIXME: We should also do this with bad signatures but here we
* have to distinguish between several reasons; e.g. for a missing
* public key. the key may now be available.
* For now we simply don't shortcut bad signatures
*/
}
#endif
if( (rc=openpgp_md_test_algo(algo)) )

View File

@ -485,6 +485,10 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if( fname ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("WARNING: `%s' is an empty file\n"), fname );
/* we can't yet encode the length of very large files,
* so we switch to partial length encoding in this case */
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
/* because the text_filter modifies the length of the
* data, it is not possible to know the used length

View File

@ -59,7 +59,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
PKT_secret_key *sk;
sk = gcry_xcalloc( 1, sizeof *sk );
sk->pubkey_usage = use;
sk->req_usage = use;
if( (rc = get_seckey_byname( sk, NULL, unlock )) ) {
free_secret_key( sk ); sk = NULL;
log_error("no default secret key: %s\n", gpg_errstr(rc) );
@ -90,7 +90,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
PKT_secret_key *sk;
sk = gcry_xcalloc( 1, sizeof *sk );
sk->pubkey_usage = use;
sk->req_usage = use;
if( (rc = get_seckey_byname( sk, locusr->d, unlock )) ) {
free_secret_key( sk ); sk = NULL;
log_error(_("skipped `%s': %s\n"), locusr->d, gpg_errstr(rc) );

View File

@ -109,6 +109,7 @@ static TN used_tns;
static int alloced_tns;
static int max_alloced_tns;
static struct keyid_list *trusted_key_list;
static LOCAL_ID_TABLE new_lid_table(void);
static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
@ -463,6 +464,64 @@ lid_from_keyid_no_sdir( u32 *keyid )
************* Initialization ****************
***********************************************/
void
register_trusted_key( const char *string )
{
u32 keyid[2];
struct keyid_list *r;
if( classify_user_id( string, keyid, NULL, NULL, NULL ) != 11 ) {
log_error(_("'%s' is not a valid long keyID\n"), string );
return;
}
for( r = trusted_key_list; r; r = r->next )
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] )
return;
r = gcry_xmalloc( sizeof *r );
r->keyid[0] = keyid[0];
r->keyid[1] = keyid[1];
r->next = trusted_key_list;
trusted_key_list = r;
}
static void
add_ultimate_key( PKT_public_key *pk, u32 *keyid )
{
int rc;
/* first make sure that the pubkey is in the trustdb */
rc = query_trust_record( pk );
if( rc == -1 && opt.dry_run )
return;
if( rc == -1 ) { /* put it into the trustdb */
rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] );
return;
}
}
else if( rc ) {
log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
return;
}
if( DBG_TRUST )
log_debug("key %08lX.%lu: stored into ultikey_table\n",
(ulong)keyid[1], pk->local_id );
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in trusted key table\n"),
(ulong)keyid[1]);
else if( opt.verbose > 1 )
log_info(_("key %08lX: accepted as trusted key.\n"),
(ulong)keyid[1]);
}
/****************
* Verify that all our public keys are in the trustdb.
*/
@ -474,7 +533,27 @@ verify_own_keys(void)
PKT_secret_key *sk = gcry_xcalloc( 1, sizeof *sk );
PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
u32 keyid[2];
struct keyid_list *kl;
/* put the trusted keys into the ultikey table */
for( kl = trusted_key_list; kl; kl = kl->next ) {
keyid[0] = kl->keyid[0];
keyid[1] = kl->keyid[1];
/* get the public key */
memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid );
if( rc ) {
log_info(_("key %08lX: no public key for trusted key - skipped\n"),
(ulong)keyid[1] );
}
else {
add_ultimate_key( pk, keyid );
release_public_key_parts( pk );
}
}
/* And now add all secret keys to the ultikey table */
while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
int have_pk = 0;
@ -487,6 +566,10 @@ verify_own_keys(void)
log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
(ulong)keyid[1] );
for( kl = trusted_key_list; kl; kl = kl->next ) {
if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
goto skip; /* already in trusted key table */
}
/* see whether we can access the public key of this secret key */
memset( pk, 0, sizeof *pk );
@ -504,33 +587,8 @@ verify_own_keys(void)
goto skip;
}
/* make sure that the pubkey is in the trustdb */
rc = query_trust_record( pk );
if( rc == -1 && opt.dry_run )
goto skip;
if( rc == -1 ) { /* put it into the trustdb */
rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] );
goto skip;
}
}
else if( rc ) {
log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
goto skip;
add_ultimate_key( pk, keyid );
}
if( DBG_TRUST )
log_debug("key %08lX.%lu: stored into ultikey_table\n",
(ulong)keyid[1], pk->local_id );
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in trusted key table\n"),
(ulong)keyid[1]);
else if( opt.verbose > 1 )
log_info(_("key %08lX: accepted as trusted key.\n"),
(ulong)keyid[1]);
skip:
release_secret_key_parts( sk );
if( have_pk )
@ -541,6 +599,15 @@ verify_own_keys(void)
else
rc = 0;
/* release the trusted keyid table */
{ struct keyid_list *kl2;
for( kl = trusted_key_list; kl; kl = kl2 ) {
kl2 = kl->next;
gcry_free( kl );
}
trusted_key_list = NULL;
}
enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
free_secret_key( sk );
free_public_key( pk );
@ -548,6 +615,8 @@ verify_own_keys(void)
}
/****************
* Perform some checks over the trustdb
* level 0: only open the db

View File

@ -116,6 +116,7 @@ size_t iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen );
void iobuf_unget_and_close_temp( IOBUF a, IOBUF temp );
u32 iobuf_get_filelength( IOBUF a );
#define IOBUF_FILELENGTH_LIMIT 0xffffffff
const char *iobuf_get_real_fname( IOBUF a );
const char *iobuf_get_fname( IOBUF a );

View File

@ -1,3 +1,8 @@
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* ring-a-party: substr starts at offset 1 not 0. Many thanks to Mike
for finding this bug. Flush the last key.
Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
* mail-signed-keys: New.

View File

@ -31,6 +31,9 @@ BEGIN { FS=":"
page = 0;
now = strftime("%b %d %H:%M %Y");
}
END {
if (any) myflush();
}
$1 == "pub" {
if( any ) myflush();
uidcount = 0;
@ -84,7 +87,7 @@ function printfpr16( s )
printf "f16 Fingerprint16 =";
for(i=0; i < 16; i++ ) {
if( i == 8 ) printf " ";
printf " %s", substr( s, i*2, 2 );
printf " %s", substr( s, i*2+1, 2 );
}
printf "\n"
}
@ -94,10 +97,13 @@ function printfpr20( s )
printf "f20 Fingerprint20 =";
for(i=0; i < 10; i++ ) {
if( i == 5 ) printf " ";
printf " %s", substr( s, i*4, 4 );
printf " %s", substr( s, i*4+1, 4 );
}
printf "\n"
}
' | tee a.pub | gpg --print-mds

View File

@ -1,3 +1,15 @@
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* strgutil.c (utf8_to_native): Fixed null ptr problem. By
Giampaolo Tomassoni.
* iobuf.c: Use fopen64 insead of fopen when available.
(iobuf_get_filelength): Use fstat64 when available but return
2^32-1 if the file is larger than this value.
* miscutil.c (answer_is_yes_no_quit): Swapped order of yes/no test
so that no is returned for an empty input. By David Champion.
Fri Aug 18 14:27:14 CEST 2000 Werner Koch <wk@openit.de>
* logger.c (log_set_file): Allow to set the file by name.

View File

@ -36,6 +36,14 @@
#include "util.h"
#include "iobuf.h"
#if defined (HAVE_FOPEN64) && defined (HAVE_FSTAT64)
#define fopen(a,b) fopen64 ((a),(b))
#define fstat(a,b) fstat64 ((a),(b))
#endif
typedef struct {
FILE *fp; /* open file handle */
int print_only_name; /* flags indicating that fname is not a real file*/
@ -1312,25 +1320,40 @@ iobuf_set_limit( IOBUF a, unsigned long nlimit )
u32
iobuf_get_filelength( IOBUF a )
{
#if defined (HAVE_FOPEN64) && defined (HAVE_FSTAT64)
struct stat64 st;
#else
struct stat st;
#endif
if( a->directfp ) {
FILE *fp = a->directfp;
if( !fstat(fileno(fp), &st) )
return st.st_size;
if( !fstat(fileno(fp), &st) ) {
#if defined (HAVE_FOPEN64) && defined (HAVE_FSTAT64)
if( st.st_size >= IOBUF_FILELENGTH_LIMIT )
return IOBUF_FILELENGTH_LIMIT;
#endif
return (u32)st.st_size;
}
log_error("fstat() failed: %s\n", strerror(errno) );
return 0;
}
/* Hmmm: file_filter may have already been removed */
for( ; a; a = a->chain )
if( !a->chain && a->filter == file_filter ) {
file_filter_ctx_t *b = a->filter_ov;
FILE *fp = b->fp;
if( !fstat(fileno(fp), &st) )
if( !fstat(fileno(fp), &st) ) {
#if defined (HAVE_FOPEN64) && defined (HAVE_FSTAT64)
if( st.st_size >= IOBUF_FILELENGTH_LIMIT )
return IOBUF_FILELENGTH_LIMIT;
#endif
return st.st_size;
}
log_error("fstat() failed: %s\n", strerror(errno) );
break;
}

View File

@ -311,16 +311,16 @@ answer_is_yes_no_quit( const char *s )
char *short_no = _("nN");
char *short_quit = _("qQ");
if( !stricmp(s, long_yes ) )
return 1;
if( !stricmp(s, long_no ) )
return 0;
if( !stricmp(s, long_yes ) )
return 1;
if( !stricmp(s, long_quit ) )
return -1;
if( strchr( short_yes, *s ) && !s[1] )
return 1;
if( strchr( short_no, *s ) && !s[1] )
return 0;
if( strchr( short_yes, *s ) && !s[1] )
return 1;
if( strchr( short_quit, *s ) && !s[1] )
return -1;
if( !stricmp(s, "yes" ) )

View File

@ -389,7 +389,8 @@ utf8_to_native( const char *string, size_t length )
case 0 : n++; if( p ) *p++ = '0'; break;
default: n += 3;
sprintf( p, "x%02x", *s );
p += 3;
if ( p )
p += 3;
break;
}
}
@ -496,3 +497,7 @@ utf8_to_native( const char *string, size_t length )
}